Skip to content

Commit

Permalink
Authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
Dany Marcoux committed Apr 26, 2021
1 parent 3f80986 commit 026b699
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 84 deletions.
16 changes: 3 additions & 13 deletions src/api/app/controllers/trigger_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ class TriggerController < ApplicationController
validate_action release: { method: :post, response: :status }
validate_action runservice: { method: :post, response: :status }

# before_action :validate_token, :set_package, :set_user, only: [:create]
# before_action :validate_token, only: [:create]
before_action :disallow_project_param, only: [:release]
before_action :validate_gitlab_event
before_action :set_token

# TODO
# we have to call it for runservices
before_action :require_valid_token
# before_action :set_package
# before_action :extract_auth_from_request, :validate_auth_token, :require_valid_token, except: [:create]
#
# Authentication happens with tokens, so no login is required
Expand All @@ -33,9 +32,9 @@ def create
# get token # Done
# pundit # TODO

package = set_package # TODO: set_filter, should be named fetch_package, maybe?
authorize @token
# the token type inference, we are still doing via action type.
@token.call(package) # i.e Token::Rebuild / Token::Release / Token::Service
@token.call(params) # i.e Token::Rebuild / Token::Release / Token::Service
render_ok
end

Expand Down Expand Up @@ -105,13 +104,4 @@ def validate_token
render_error message: 'Token not found or not valid.', status: 403
false
end

def set_package
@token.package || Package.get_by_project_and_name(params[:project], @token.package_find_options)
# @package = @token.package || Package.get_by_project_and_name(params[:project], params[:package], use_source: true)
end

def set_user
@user = @token.user
end
end
14 changes: 7 additions & 7 deletions src/api/app/models/token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ class Token < ApplicationRecord
belongs_to :user
belongs_to :package, inverse_of: :tokens

attr_accessor :package_from_association_or_params

has_secure_token :string

validates :user, presence: true
Expand All @@ -22,14 +24,12 @@ def self.token_type(action)
end
end

# TODO
# make sure:
# a) the name makes sense
# b) it lives in the right place
def call(_params)
raise AbstractMethodCalled
end

def package_find_options
{ use_source: true,
follow_project_links: false,
follow_multibuild: false }
{}
end
end

Expand Down
10 changes: 8 additions & 2 deletions src/api/app/models/token/rebuild.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@ def self.token_name
'rebuild'
end

# TODO: Use package_from_association_or_params instead of package
# def call(package:, project:, repository:, architecture:) USE THIS
def call(params)
package_name = package&.name || params[:package]
project_name = package&.project.name || params[:project]
project_name = package&.project.&name || params[:project]

Backend::Api::Sources::Package.rebuild(project_name, package_name, params)
end

def package_find_options
{ use_source: false, follow_project_links: true, follow_multibuild: true }
end
end

####
#### TODO: keep it or delete
#
#
# id user package
Expand Down
25 changes: 12 additions & 13 deletions src/api/app/models/token/release.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,27 @@ def self.token_name
'release'
end

def call(pkg)
release(pkg)
end

def release(pkg)
# TODO
# move authorization to pundit
raise NoPermissionForPackage.setup('no_permission', 403, "no permission for package #{pkg} in project #{pkg.project}") unless policy(pkg).update?
# TODO: Use package_from_association_or_params instead of package
def call(_params)
# AUTHORIZATION
raise NoPermissionForPackage.setup('no_permission', 403, "no permission for package #{package} in project #{package.project}") unless policy(package).update?

manual_release_targets = pkg.project.release_targets.where(trigger: 'manual')
raise NoPermissionForPackage.setup('not_found', 404, "#{pkg.project} has no release targets that are triggered manually") unless manual_release_targets.any?
manual_release_targets = package.project.release_targets.where(trigger: 'manual')
# AUTHORIZATION
raise NoPermissionForPackage.setup('not_found', 404, "#{package.project} has no release targets that are triggered manually") unless manual_release_targets.any?

manual_release_targets.each do |release_target|
release_package(pkg,
release_package(package,
release_target.target_repository,
pkg.release_target_name,
package.release_target_name,
{ filter_source_repository: release_target.repository,
manual: true,
comment: 'Releasing via trigger event' })
end
end

# render_ok
def package_find_options
{ use_source: true, follow_project_links: false, follow_multibuild: false }
end
end

Expand Down
31 changes: 6 additions & 25 deletions src/api/app/models/token/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,23 @@ def self.token_name
'runservice'
end

def call(pkg)
runservice(pkg)
end

# "runservice" (create action) from webhook_controller
# def code_from_webhook_controller
def runservice(pkg)
# TODO: Use package_from_association_or_params instead of package
def call(_params)
# TODO: move it to pundit in the trigger controller
# if !@user.is_active? || !@user.can_modify?(@package)
# render_error message: 'Token not found or not valid.', status: 404
# return
# end

Backend::Api::Sources::Package.trigger_services(pkg.project.name, pkg.name, User.session!.login)
Backend::Api::Sources::Package.trigger_services(package.project.name, package.name, user.login)
# TODO
# check if its necessary
package.sources_changed
# render_ok
end

# "runservice" (runservice action) from trigger controller
# def runservice
# # TODO: move it to pundit in the trigger controller
# # raise NoPermissionForPackage.setup('no_permission', 403, "no permission for package #{package} in project #{@pkg.project}") unless policy(@pkg).update?

# # execute the service in backend
# pass_to_backend(prepare_path_for_runservice)

# package.sources_changed
# end

# def prepare_path_for_runservice
# path = package.source_path
# params = { cmd: 'runservice', comment: 'runservice via trigger', user: User.session!.login }
# URI(path + build_query_from_hash(params, [:cmd, :comment, :user])).to_s
# end
def package_find_options
{ use_source: true, follow_project_links: false, follow_multibuild: false }
end
end

# == Schema Information
Expand Down
22 changes: 3 additions & 19 deletions src/api/app/policies/token/rebuild_policy.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,11 @@
class Token
class RebuildPolicy < ApplicationPolicy

# When are people allowed to rebuild?
# - the token's user has access to the package

def initialize(user, record, opts = {})
super(user, record)
def initialize(_user, record)
super(record.user, record)
end

def create?
user.can_modify?(record)
PackagePolicy.new(record.user, record.package_from_association_or_params).update?
end
end
end

# authorization needs to check:
# use_source => ends up checking sourceaccess (package.check_source_access?)
# follow_multibuild => already handled by backend (packages names with '*:' in the name)
# follow_project_links => only rebuild can follow the links, the inherited packages can also be rebuilt

# if not rebuilt then don't follow project links
# opts = { use_source: false,
# follow_project_links: true,
# follow_multibuild: true }
# Package.get_by_project_and_name(params[:project].to_s, params[:package].to_s, opts)

9 changes: 9 additions & 0 deletions src/api/app/policies/token/release_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Token
class ReleasePolicy < ApplicationPolicy
def initialize(_user, record)
super(record.user, record)
end

def create?; end
end
end
9 changes: 9 additions & 0 deletions src/api/app/policies/token/service_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Token
class ServicePolicy < ApplicationPolicy
def initialize(_user, record)
super(record.user, record)
end

def create?; end
end
end
17 changes: 12 additions & 5 deletions src/api/app/services/trigger_controller_service/token_extractor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ def initialize(http_request)
end

def call
if @token_id
extract_token_from_request_signature
else
extract_auth_token_from_headers
end
token = if @token_id
extract_token_from_request_signature
else
extract_auth_token_from_headers
end

# We need to store in memory the package in order to do authorization
token.package_from_association_or_params = token.package || Package.get_by_project_and_name(@http_request.params[:project], @http_request.params[:package],
token.package_find_options)
raise ActiveRecord::RecordNotFound if token.package_from_association_or_params.nil? # This can happen due to the Package.get_by_project_and_name method

token
end

private
Expand Down

0 comments on commit 026b699

Please sign in to comment.