2021-01-29 21:09:34 +00:00
# frozen_string_literal: true
module API
class ResourceAccessTokens < :: API :: Base
include PaginationParams
2022-11-01 22:00:04 +00:00
ALLOWED_RESOURCE_ACCESS_LEVELS = Gitlab :: Access . options_with_owner . freeze
2021-01-29 21:09:34 +00:00
before { authenticate! }
feature_category :authentication_and_authorization
2022-01-08 00:14:32 +00:00
%w[ project group ] . each do | source_type |
2021-01-29 21:09:34 +00:00
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 ] )
2021-03-26 21:09:22 +00:00
next unauthorized! unless current_user . can? ( :read_resource_access_tokens , resource )
2021-01-29 21:09:34 +00:00
2021-06-24 12:08:07 +00:00
tokens = PersonalAccessTokensFinder . new ( { user : resource . bots , impersonation : false } ) . execute . preload_users
2021-01-29 21:09:34 +00:00
2022-01-08 00:14:32 +00:00
resource . members . load
present paginate ( tokens ) , with : Entities :: ResourceAccessToken , resource : resource
2021-01-29 21:09:34 +00:00
end
2022-03-23 03:07:30 +00:00
desc 'Get an access token for the specified resource by ID' do
detail 'This feature was introduced in GitLab 14.10.'
end
params do
requires :id , type : String , desc : " The #{ source_type } ID "
requires :token_id , type : String , desc : " The ID of the token "
end
get " :id/access_tokens/:token_id " do
resource = find_source ( source_type , params [ :id ] )
next unauthorized! unless current_user . can? ( :read_resource_access_tokens , resource )
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
resource . members . load
present token , with : Entities :: ResourceAccessToken , resource : resource
end
2021-01-29 21:09:34 +00:00
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 "
2022-11-01 22:00:04 +00:00
requires :scopes , type : Array [ String ] , values : :: Gitlab :: Auth . resource_bot_scopes . map ( & :to_s ) , desc : " The permissions of the token "
optional :access_level , type : Integer , values : ALLOWED_RESOURCE_ACCESS_LEVELS . values , default : Gitlab :: Access :: MAINTAINER , desc : " The access level of the token in the #{ source_type } "
2021-01-29 21:09:34 +00:00
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?
2022-01-08 00:14:32 +00:00
present token_response . payload [ :access_token ] , with : Entities :: ResourceAccessTokenWithToken , resource : resource
2021-01-29 21:09:34 +00:00
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
end
end
end