Class: ApiKeys::ApiKey
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- ApiKeys::ApiKey
- Defined in:
- lib/api_keys/models/api_key.rb
Overview
The core ActiveRecord model representing an API key.
Instance Attribute Summary collapse
-
#token ⇒ Object
readonly
Attributes & Serialization == Expose the plaintext token only immediately after creation.
Instance Method Summary collapse
- #active? ⇒ Boolean
-
#allows_permission?(required_permission) ⇒ Boolean
Check if this key has a specific permission (alias for allows_scope?).
-
#allows_scope?(required_scope) ⇒ Boolean
Basic scope check.
-
#destroy ⇒ Object
Override destroy to prevent destroying non-revocable keys.
- #destroy! ⇒ Object
-
#environment_config ⇒ Object
Returns the configuration hash for this key's environment.
- #expired? ⇒ Boolean
-
#key_type_config ⇒ Object
Returns the configuration hash for this key's type.
-
#masked_token ⇒ Object
Provides a masked version of the token for display (e.g., ak_live_••••rj4p) Requires the plaintext token to be available (only right after creation).
-
#permissions ⇒ Array<String>
Alias for scopes - provides a more user-friendly API that matches the configuration DSL where key types use
permissionsfor scope ceiling. -
#public_key_type? ⇒ Boolean
Returns true if this key type is configured as public AND non-revocable.
-
#revocable? ⇒ Boolean
Returns true if this key can be revoked/destroyed Keys without a key_type (legacy) are always revocable Keys with a key_type check the configuration.
-
#revoke! ⇒ Object
Instance Methods ==.
- #revoked? ⇒ Boolean
-
#scopes=(value) ⇒ Object
Override scopes setter to auto-clean blank values.
-
#viewable_token ⇒ String?
Returns the stored plaintext token for public, non-revocable keys.
Instance Attribute Details
#token ⇒ Object (readonly)
Attributes & Serialization ==
Expose the plaintext token only immediately after creation
20 21 22 |
# File 'lib/api_keys/models/api_key.rb', line 20 def token @token end |
Instance Method Details
#active? ⇒ Boolean
131 132 133 |
# File 'lib/api_keys/models/api_key.rb', line 131 def active? !revoked? && !expired? end |
#allows_permission?(required_permission) ⇒ Boolean
Check if this key has a specific permission (alias for allows_scope?)
218 219 220 |
# File 'lib/api_keys/models/api_key.rb', line 218 def () allows_scope?() end |
#allows_scope?(required_scope) ⇒ Boolean
Basic scope check. Assumes scopes are stored as an array of strings.
Behavior depends on whether key_types mode is enabled:
- Simple mode (no key_types): blank scopes means "unrestricted" (all scopes allowed). This preserves backwards compatibility for apps that don't use scopes at all.
- Key types mode: blank scopes means "no permissions". When you've configured key types with permission ceilings, an empty scope list should deny access, not silently bypass the entire permission system.
194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/api_keys/models/api_key.rb', line 194 def allows_scope?(required_scope) return true unless respond_to?(:scopes) # Guard clause if loaded before attribute definition if scopes.blank? # In key_types mode, blank scopes = no access (deny by default) # In simple mode, blank scopes = unrestricted (allow by default) return !ApiKeys.configuration.key_types.present? end scopes.include?(required_scope.to_s) end |
#destroy ⇒ Object
Override destroy to prevent destroying non-revocable keys
176 177 178 179 |
# File 'lib/api_keys/models/api_key.rb', line 176 def destroy raise ApiKeys::Errors::KeyNotRevocableError unless revocable? super end |
#destroy! ⇒ Object
181 182 183 184 |
# File 'lib/api_keys/models/api_key.rb', line 181 def destroy! raise ApiKeys::Errors::KeyNotRevocableError unless revocable? super end |
#environment_config ⇒ Object
Returns the configuration hash for this key's environment
152 153 154 155 |
# File 'lib/api_keys/models/api_key.rb', line 152 def environment_config return nil if environment.blank? ApiKeys.configuration.environments&.dig(environment.to_sym) end |
#expired? ⇒ Boolean
127 128 129 |
# File 'lib/api_keys/models/api_key.rb', line 127 def expired? expires_at? && expires_at <= Time.current end |
#key_type_config ⇒ Object
Returns the configuration hash for this key's type
146 147 148 149 |
# File 'lib/api_keys/models/api_key.rb', line 146 def key_type_config return nil if key_type.blank? ApiKeys.configuration.key_types&.dig(key_type.to_sym) end |
#masked_token ⇒ Object
Provides a masked version of the token for display (e.g., ak_live_••••rj4p) Requires the plaintext token to be available (only right after creation).
224 225 226 227 228 229 230 231 232 233 |
# File 'lib/api_keys/models/api_key.rb', line 224 def masked_token # return "[Token not available]" unless token # No longer needed # Show prefix, 4 bullets, last 4 chars of the random part # random_part = token.delete_prefix(prefix) # No longer needed # "#{prefix}••••#{random_part.last(4)}" # No longer needed # Use the stored prefix and last4 attributes return "[Invalid Key Data]" unless prefix.present? && last4.present? "#{prefix}••••#{last4}" end |
#permissions ⇒ Array<String>
Alias for scopes - provides a more user-friendly API that matches
the configuration DSL where key types use permissions for scope ceiling.
Note: We use a method instead of alias_method because scopes is defined
dynamically via the attribute API in the engine initializer.
211 212 213 |
# File 'lib/api_keys/models/api_key.rb', line 211 def scopes end |
#public_key_type? ⇒ Boolean
Returns true if this key type is configured as public AND non-revocable. Only these keys have their plaintext token stored in metadata for later viewing. This is used for publishable keys that are designed to be embedded in distributed apps.
160 161 162 163 164 165 |
# File 'lib/api_keys/models/api_key.rb', line 160 def public_key_type? return false if key_type.blank? config = key_type_config return false if config.nil? config[:public] == true && config[:revocable] == false end |
#revocable? ⇒ Boolean
Returns true if this key can be revoked/destroyed Keys without a key_type (legacy) are always revocable Keys with a key_type check the configuration
138 139 140 141 142 143 |
# File 'lib/api_keys/models/api_key.rb', line 138 def revocable? return true if key_type.blank? config = key_type_config return true if config.nil? config.fetch(:revocable, true) end |
#revoke! ⇒ Object
Instance Methods ==
118 119 120 121 |
# File 'lib/api_keys/models/api_key.rb', line 118 def revoke! raise ApiKeys::Errors::KeyNotRevocableError unless revocable? update!(revoked_at: Time.current) end |
#revoked? ⇒ Boolean
123 124 125 |
# File 'lib/api_keys/models/api_key.rb', line 123 def revoked? revoked_at.present? end |
#scopes=(value) ⇒ Object
Override scopes setter to auto-clean blank values. This handles the common case where form checkboxes submit empty strings. Works for both create and update operations.
28 29 30 31 32 33 34 35 |
# File 'lib/api_keys/models/api_key.rb', line 28 def scopes=(value) cleaned = if value.is_a?(Array) value.reject { |s| s.blank? } else value end super(cleaned) end |
#viewable_token ⇒ String?
Returns the stored plaintext token for public, non-revocable keys. Returns nil for all other key types (the token is only available at creation time).
170 171 172 173 |
# File 'lib/api_keys/models/api_key.rb', line 170 def viewable_token return nil unless public_key_type? &.dig("token") end |