Class: StandardId::AuthorizationCode
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- StandardId::AuthorizationCode
- Defined in:
- app/models/standard_id/authorization_code.rb
Class Method Summary collapse
- .default_ttl ⇒ Object
- .hash_for(plaintext_code) ⇒ Object
- .issue!(plaintext_code:, client_id:, redirect_uri:, scope: nil, audience: nil, account: nil, code_challenge: nil, code_challenge_method: nil, metadata: {}) ⇒ Object
- .lookup(plaintext_code) ⇒ Object
Instance Method Summary collapse
- #expired? ⇒ Boolean
- #mark_as_used! ⇒ Object
- #pkce_valid?(code_verifier) ⇒ Boolean
- #valid_for_client?(client_id) ⇒ Boolean
Class Method Details
.default_ttl ⇒ Object
43 44 45 |
# File 'app/models/standard_id/authorization_code.rb', line 43 def self.default_ttl 10.minutes end |
.hash_for(plaintext_code) ⇒ Object
39 40 41 |
# File 'app/models/standard_id/authorization_code.rb', line 39 def self.hash_for(plaintext_code) Digest::SHA256.hexdigest("#{plaintext_code}:#{Rails.configuration.secret_key_base}") end |
.issue!(plaintext_code:, client_id:, redirect_uri:, scope: nil, audience: nil, account: nil, code_challenge: nil, code_challenge_method: nil, metadata: {}) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'app/models/standard_id/authorization_code.rb', line 19 def self.issue!(plaintext_code:, client_id:, redirect_uri:, scope: nil, audience: nil, account: nil, code_challenge: nil, code_challenge_method: nil, metadata: {}) create!( account: account, code_hash: hash_for(plaintext_code), client_id: client_id, redirect_uri: redirect_uri, scope: scope, audience: audience, code_challenge: code_challenge, code_challenge_method: code_challenge_method, issued_at: Time.current, expires_at: Time.current + default_ttl, metadata: || {} ) end |
.lookup(plaintext_code) ⇒ Object
35 36 37 |
# File 'app/models/standard_id/authorization_code.rb', line 35 def self.lookup(plaintext_code) find_by(code_hash: hash_for(plaintext_code)) end |
Instance Method Details
#expired? ⇒ Boolean
51 52 53 |
# File 'app/models/standard_id/authorization_code.rb', line 51 def expired? expires_at <= Time.current end |
#mark_as_used! ⇒ Object
71 72 73 74 75 76 77 |
# File 'app/models/standard_id/authorization_code.rb', line 71 def mark_as_used! with_lock do raise StandardId::InvalidGrantError, "Authorization code already used" if consumed_at.present? raise StandardId::InvalidGrantError, "Authorization code expired" if expired? update!(consumed_at: Time.current) end end |
#pkce_valid?(code_verifier) ⇒ Boolean
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'app/models/standard_id/authorization_code.rb', line 55 def pkce_valid?(code_verifier) return true if code_challenge.blank? return false if code_verifier.blank? case (code_challenge_method || "plain").downcase when "s256" expected = Base64.urlsafe_encode64(Digest::SHA256.digest(code_verifier)).delete("=") ActiveSupport::SecurityUtils.secure_compare(expected, code_challenge) when "plain" ActiveSupport::SecurityUtils.secure_compare(code_verifier, code_challenge) else false end end |
#valid_for_client?(client_id) ⇒ Boolean
47 48 49 |
# File 'app/models/standard_id/authorization_code.rb', line 47 def valid_for_client?(client_id) self.client_id == client_id && consumed_at.nil? && !expired? end |