Class: Mcp::Auth::Services::AuthorizationService
- Inherits:
-
Object
- Object
- Mcp::Auth::Services::AuthorizationService
- Defined in:
- lib/mcp/auth/services/authorization_service.rb
Class Method Summary collapse
-
.consume_authorization_code(code) ⇒ Object
Consume authorization code (one-time use).
-
.generate_authorization_code(params, user:, org:) ⇒ Object
Generate authorization code with PKCE support.
-
.validate_authorization_code(code) ⇒ Object
Validate authorization code without consuming it.
-
.validate_pkce?(code_challenge, code_verifier) ⇒ Boolean
Validate PKCE challenge (RFC 7636).
Class Method Details
.consume_authorization_code(code) ⇒ Object
Consume authorization code (one-time use)
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/mcp/auth/services/authorization_service.rb', line 56 def (code) = Mcp::Auth::AuthorizationCode.find_by(code: code) return nil unless code_data = { client_id: .client_id, redirect_uri: .redirect_uri, code_challenge: .code_challenge, code_challenge_method: .code_challenge_method, resource: .resource, scope: .scope, user_id: .user_id, org_id: .org_id, created_at: .created_at.to_i } .destroy Rails.logger.info "[AuthorizationService] Authorization code consumed" code_data end |
.generate_authorization_code(params, user:, org:) ⇒ Object
Generate authorization code with PKCE support
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 |
# File 'lib/mcp/auth/services/authorization_service.rb', line 9 def (params, user:, org:) code = SecureRandom.hex(32) # Use provided scope or default to all registered scopes scope = params[:scope].presence || Mcp::Auth::ScopeRegistry.default_scope_string = Mcp::Auth::AuthorizationCode.create!( code: code, client_id: params[:client_id], redirect_uri: params[:redirect_uri], code_challenge: params[:code_challenge], code_challenge_method: params[:code_challenge_method], resource: params[:resource], scope: scope, user: user, org: org, expires_at: .minutes.from_now ) Rails.logger.info "[AuthorizationService] Authorization code generated for user #{user.id}" .code rescue ActiveRecord::RecordInvalid => e Rails.logger.error "[AuthorizationService] Failed to create authorization code: #{e.}" nil end |
.validate_authorization_code(code) ⇒ Object
Validate authorization code without consuming it
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/mcp/auth/services/authorization_service.rb', line 36 def (code) return nil if code.blank? = Mcp::Auth::AuthorizationCode.active.find_by(code: code) return nil unless { client_id: .client_id, redirect_uri: .redirect_uri, code_challenge: .code_challenge, code_challenge_method: .code_challenge_method, resource: .resource, scope: .scope, user_id: .user_id, org_id: .org_id, created_at: .created_at.to_i } end |
.validate_pkce?(code_challenge, code_verifier) ⇒ Boolean
Validate PKCE challenge (RFC 7636)
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/mcp/auth/services/authorization_service.rb', line 78 def validate_pkce?(code_challenge, code_verifier) return false if code_verifier.blank? || code_challenge.blank? # S256 method: BASE64URL(SHA256(code_verifier)) computed_challenge = Base64.urlsafe_encode64( Digest::SHA256.digest(code_verifier), padding: false ) ActiveSupport::SecurityUtils.secure_compare(computed_challenge, code_challenge) rescue StandardError => e Rails.logger.error "[AuthorizationService] PKCE validation error: #{e.}" false end |