Class: Toolchest::OauthAccessToken
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Toolchest::OauthAccessToken
- Defined in:
- app/models/toolchest/oauth_access_token.rb
Class Method Summary collapse
- .create_for(application:, resource_owner_id:, scopes:, mount_key: "default", expires_in: 7200) ⇒ Object
-
.find_by_refresh_token(raw_refresh, mount_key: nil) ⇒ Object
See find_by_token for timing safety rationale.
-
.find_by_token(raw_token, mount_key: nil) ⇒ Object
Timing-safe by design: we hash the raw token before lookup, so the database comparison runs against the hash (which the attacker doesn’t know).
- .revoke_all_for(application, resource_owner_id) ⇒ Object
Instance Method Summary collapse
- #accessible? ⇒ Boolean
- #expired? ⇒ Boolean
- #raw_refresh_token ⇒ Object
- #raw_token ⇒ Object
- #revoke! ⇒ Object
- #revoked? ⇒ Boolean
- #scopes_array ⇒ Object
Class Method Details
.create_for(application:, resource_owner_id:, scopes:, mount_key: "default", expires_in: 7200) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'app/models/toolchest/oauth_access_token.rb', line 31 def create_for(application:, resource_owner_id:, scopes:, mount_key: "default", expires_in: 7200) raw_token = SecureRandom.urlsafe_base64(32) raw_refresh = SecureRandom.urlsafe_base64(32) token = create!( application: application, resource_owner_id: resource_owner_id, token: Digest::SHA256.hexdigest(raw_token), refresh_token: Digest::SHA256.hexdigest(raw_refresh), scopes: scopes, mount_key: mount_key, expires_at: expires_in ? Time.current + expires_in.seconds : nil ) token.instance_variable_set(:@raw_token, raw_token) token.instance_variable_set(:@raw_refresh_token, raw_refresh) token end |
.find_by_refresh_token(raw_refresh, mount_key: nil) ⇒ Object
See find_by_token for timing safety rationale.
60 61 62 63 64 |
# File 'app/models/toolchest/oauth_access_token.rb', line 60 def find_by_refresh_token(raw_refresh, mount_key: nil) scope = active.where(refresh_token: Digest::SHA256.hexdigest(raw_refresh)) scope = scope.where(mount_key: mount_key) if mount_key scope.first end |
.find_by_token(raw_token, mount_key: nil) ⇒ Object
Timing-safe by design: we hash the raw token before lookup, so the database comparison runs against the hash (which the attacker doesn’t know). No constant-time comparison needed here.
53 54 55 56 57 |
# File 'app/models/toolchest/oauth_access_token.rb', line 53 def find_by_token(raw_token, mount_key: nil) scope = active.where(token: Digest::SHA256.hexdigest(raw_token)) scope = scope.where(mount_key: mount_key) if mount_key scope.first end |
.revoke_all_for(application, resource_owner_id) ⇒ Object
26 27 28 29 |
# File 'app/models/toolchest/oauth_access_token.rb', line 26 def revoke_all_for(application, resource_owner_id) where(application: application, resource_owner_id: resource_owner_id.to_s, revoked_at: nil) .update_all(revoked_at: Time.current) end |
Instance Method Details
#accessible? ⇒ Boolean
21 |
# File 'app/models/toolchest/oauth_access_token.rb', line 21 def accessible? = !revoked? && !expired? |
#expired? ⇒ Boolean
15 |
# File 'app/models/toolchest/oauth_access_token.rb', line 15 def expired? = expires_at.present? && expires_at < Time.current |
#raw_refresh_token ⇒ Object
69 |
# File 'app/models/toolchest/oauth_access_token.rb', line 69 def raw_refresh_token = @raw_refresh_token |
#raw_token ⇒ Object
67 |
# File 'app/models/toolchest/oauth_access_token.rb', line 67 def raw_token = @raw_token |
#revoke! ⇒ Object
19 |
# File 'app/models/toolchest/oauth_access_token.rb', line 19 def revoke! = update!(revoked_at: Time.current) |
#revoked? ⇒ Boolean
17 |
# File 'app/models/toolchest/oauth_access_token.rb', line 17 def revoked? = revoked_at.present? |
#scopes_array ⇒ Object
23 |
# File 'app/models/toolchest/oauth_access_token.rb', line 23 def scopes_array = (scopes || "").split(" ").reject(&:empty?) |