1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
module Jwt
class DockerAuthenticationService < BaseService
def execute
if params[:offline_token]
return error('forbidden', 403) unless current_user
end
{ token: token.encoded }
end
def self.full_access_token(*names)
registry = Gitlab.config.registry
token = ::Jwt::RSAToken.new(registry.key)
token.issuer = registry.issuer
token.audience = 'docker'
token[:access] = names.map do |name|
{ type: 'repository', name: name, actions: %w(pull push) }
end
token.encoded
end
private
def token
token = ::Jwt::RSAToken.new(registry.key)
token.issuer = registry.issuer
token.audience = params[:service]
token.subject = current_user.try(:username)
token[:access] = access
token
end
def access
return unless params[:scope]
scope = process_scope(params[:scope])
[scope].compact
end
def process_scope(scope)
type, name, actions = scope.split(':', 3)
actions = actions.split(',')
case type
when 'repository'
process_repository_access(type, name, actions)
end
end
def process_repository_access(type, name, actions)
current_project = Project.find_with_namespace(name)
return unless current_project
actions = actions.select do |action|
can_access?(current_project, action)
end
{ type: type, name: name, actions: actions } if actions
end
def can_access?(current_project, action)
case action
when 'pull'
current_project == project || can?(current_user, :download_code, current_project)
when 'push'
current_project == project || can?(current_user, :push_code, current_project)
else
false
end
end
def registry
Gitlab.config.registry
end
end
end
|