-
-
Notifications
You must be signed in to change notification settings - Fork 992
Expand file tree
/
Copy pathapi_key_roles_controller.rb
More file actions
86 lines (72 loc) · 2.29 KB
/
api_key_roles_controller.rb
File metadata and controls
86 lines (72 loc) · 2.29 KB
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
77
78
79
80
81
82
83
84
85
86
class Api::V1::OIDC::ApiKeyRolesController < Api::BaseController
include ApiKeyable
before_action :authenticate_with_api_key, except: :assume_role
before_action :verify_user_api_key, except: :assume_role
with_options only: :assume_role do
before_action :set_api_key_role
before_action :decode_jwt
before_action :verify_jwt
before_action :verify_access
end
class UnverifiedJWT < StandardError
end
rescue_from(
UnverifiedJWT,
JSON::JWT::VerificationFailed, JSON::JWK::Set::KidNotFound,
OIDC::AccessPolicy::AccessError,
with: :render_not_found
)
rescue_from ActiveRecord::RecordInvalid do |err|
render json: {
errors: err.record.errors
}, status: :unprocessable_entity
end
def index
render json: @api_key.user.oidc_api_key_roles
end
def show
render json: @api_key.user.oidc_api_key_roles.find_by!(token: params.require(:token))
end
def assume_role
key = nil
api_key = nil
ApiKey.transaction do
key = generate_unique_rubygems_key
api_key = @api_key_role.user.api_keys.create!(
hashed_key: hashed_key(key),
name: "#{@api_key_role.name}-#{@jwt[:jti]}",
**@api_key_role.api_key_permissions.create_params(@api_key_role.user)
)
OIDC::IdToken.create!(
api_key:,
jwt: { claims: @jwt, header: @jwt.header },
api_key_role: @api_key_role,
provider: @api_key_role.provider
)
Mailer.api_key_created(api_key.id).deliver_later
end
render json: {
rubygems_api_key: key,
name: api_key.name,
scopes: api_key.enabled_scopes,
gem: api_key.rubygem,
expires_at: api_key.expires_at
}.compact, status: :created
end
private
def set_api_key_role
@api_key_role = OIDC::ApiKeyRole.active.find_by!(token: params.require(:token))
end
def decode_jwt
@jwt = JSON::JWT.decode_compact_serialized(params.require(:jwt), @api_key_role.provider.jwks)
rescue JSON::ParserError
raise UnverifiedJWT, "Invalid JSON"
end
def verify_jwt
raise UnverifiedJWT, "Issuer mismatch" unless @api_key_role.provider.issuer == @jwt["iss"]
raise UnverifiedJWT, "Invalid time" unless (@jwt["nbf"]..@jwt["exp"]).cover?(Time.now.to_i)
end
def verify_access
@api_key_role.access_policy.verify_access!(@jwt)
end
end