Class: RailsApiKeys::ApiKey

Inherits:
ApplicationRecord show all
Defined in:
app/models/rails_api_keys/api_key.rb

Overview

Persists personal API keys for a polymorphic owner.

Raw tokens are returned only from ApiKey.generate_for! and are never stored. Authentication matches against a SHA-256 digest and refuses revoked or inactive-owner keys.

Constant Summary collapse

DISPLAY_PREFIX_LENGTH =
12
TOKEN_BYTES =
32

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.authenticate(raw_token) ⇒ Object

Returns an active key for raw_token, or nil. Touches last_used_at.



44
45
46
47
48
49
50
51
52
53
# File 'app/models/rails_api_keys/api_key.rb', line 44

def authenticate(raw_token)
  return if raw_token.blank?

  key = active.find_by(token_digest: digest(raw_token))
  return unless key
  return unless RailsApiKeys.configuration.owner_active?(key.owner)

  key.touch_last_used!
  key
end

.build_raw_tokenObject



59
60
61
# File 'app/models/rails_api_keys/api_key.rb', line 59

def build_raw_token
  "#{RailsApiKeys.configuration.resolved_token_prefix}#{SecureRandom.urlsafe_base64(TOKEN_BYTES)}"
end

.digest(raw_token) ⇒ Object



55
56
57
# File 'app/models/rails_api_keys/api_key.rb', line 55

def digest(raw_token)
  Digest::SHA256.hexdigest(raw_token.to_s)
end

.display_prefix_for(raw_token) ⇒ Object



63
64
65
# File 'app/models/rails_api_keys/api_key.rb', line 63

def display_prefix_for(raw_token)
  raw_token.to_s[0, DISPLAY_PREFIX_LENGTH]
end

.generate_for!(owner:, name:, permission:) ⇒ Object

Creates a key and returns [record, raw_token]. Show raw_token once.



31
32
33
34
35
36
37
38
39
40
41
# File 'app/models/rails_api_keys/api_key.rb', line 31

def generate_for!(owner:, name:, permission:)
  raw_token = build_raw_token
  record = create!(
    owner: owner,
    name: name,
    permission: permission,
    token_digest: digest(raw_token),
    token_display_prefix: display_prefix_for(raw_token)
  )
  [ record, raw_token ]
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'app/models/rails_api_keys/api_key.rb', line 77

def active?
  !revoked?
end

#allows_read?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'app/models/rails_api_keys/api_key.rb', line 81

def allows_read?
  read? || read_write?
end

#allows_write?Boolean

Returns:

  • (Boolean)


85
86
87
# File 'app/models/rails_api_keys/api_key.rb', line 85

def allows_write?
  read_write?
end

#revoke!Object

Soft-revokes the key so authenticate no longer accepts it.



69
70
71
# File 'app/models/rails_api_keys/api_key.rb', line 69

def revoke!
  update!(revoked_at: Time.current)
end

#revoked?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'app/models/rails_api_keys/api_key.rb', line 73

def revoked?
  revoked_at.present?
end

#touch_last_used!Object



89
90
91
# File 'app/models/rails_api_keys/api_key.rb', line 89

def touch_last_used!
  update_column(:last_used_at, Time.current)
end