diff options
Diffstat (limited to 'lib/api/resource_access_tokens.rb')
-rw-r--r-- | lib/api/resource_access_tokens.rb | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/lib/api/resource_access_tokens.rb b/lib/api/resource_access_tokens.rb new file mode 100644 index 00000000000..66948f9eaf3 --- /dev/null +++ b/lib/api/resource_access_tokens.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +module API + class ResourceAccessTokens < ::API::Base + include PaginationParams + + before { authenticate! } + + feature_category :authentication_and_authorization + + %w[project].each do |source_type| + resource source_type.pluralize, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do + desc 'Get list of all access tokens for the specified resource' do + detail 'This feature was introduced in GitLab 13.9.' + end + params do + requires :id, type: String, desc: "The #{source_type} ID" + end + get ":id/access_tokens" do + resource = find_source(source_type, params[:id]) + + next unauthorized! unless has_permission_to_read?(resource) + + tokens = PersonalAccessTokensFinder.new({ user: resource.bots, impersonation: false }).execute + + present paginate(tokens), with: Entities::PersonalAccessToken + end + + desc 'Revoke a resource access token' do + detail 'This feature was introduced in GitLab 13.9.' + end + params do + requires :id, type: String, desc: "The #{source_type} ID" + requires :token_id, type: String, desc: "The ID of the token" + end + delete ':id/access_tokens/:token_id' do + resource = find_source(source_type, params[:id]) + token = find_token(resource, params[:token_id]) + + if token.nil? + next not_found!("Could not find #{source_type} access token with token_id: #{params[:token_id]}") + end + + service = ::ResourceAccessTokens::RevokeService.new( + current_user, + resource, + token + ).execute + + service.success? ? no_content! : bad_request!(service.message) + end + + desc 'Create a resource access token' do + detail 'This feature was introduced in GitLab 13.9.' + end + params do + requires :id, type: String, desc: "The #{source_type} ID" + requires :name, type: String, desc: "Resource access token name" + requires :scopes, type: Array[String], desc: "The permissions of the token" + optional :expires_at, type: Date, desc: "The expiration date of the token" + end + post ':id/access_tokens' do + resource = find_source(source_type, params[:id]) + + token_response = ::ResourceAccessTokens::CreateService.new( + current_user, + resource, + declared_params + ).execute + + if token_response.success? + present token_response.payload[:access_token], with: Entities::PersonalAccessToken + else + bad_request!(token_response.message) + end + end + end + end + + helpers do + def find_source(source_type, id) + public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend + end + + def find_token(resource, token_id) + PersonalAccessTokensFinder.new({ user: resource.bots, impersonation: false }).find_by_id(token_id) + end + + def has_permission_to_read?(resource) + can?(current_user, :project_bot_access, resource) || can?(current_user, :admin_resource_access_tokens, resource) + end + end + end +end |