Class: ApiKey
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- ApiKey
- Defined in:
- app/models/api_key.rb
Defined Under Namespace
Classes: KeyAccessError
Class Method Summary collapse
- .hash_key(key) ⇒ Object
- .last_used_epoch ⇒ Object
- .revoke_max_life_keys! ⇒ Object
- .revoke_unused_keys! ⇒ Object
Instance Method Summary collapse
- #generate_key ⇒ Object
- #key ⇒ Object
- #key_available? ⇒ Boolean
- #request_allowed?(env) ⇒ Boolean
- #update_last_used!(now = Time.zone.now) ⇒ Object
Class Method Details
.hash_key(key) ⇒ Object
98 99 100 |
# File 'app/models/api_key.rb', line 98 def self.hash_key(key) Digest::SHA256.hexdigest key end |
.last_used_epoch ⇒ Object
43 44 45 |
# File 'app/models/api_key.rb', line 43 def self.last_used_epoch SiteSetting.api_key_last_used_epoch.presence end |
.revoke_max_life_keys! ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'app/models/api_key.rb', line 74 def self.revoke_max_life_keys! return if SiteSetting.revoke_api_keys_maxlife_days == 0 revoke_days_ago = SiteSetting.revoke_api_keys_maxlife_days.days.ago to_revoke = ApiKey.active.where("created_at < ?", revoke_days_ago) to_revoke.find_each do |api_key| ApiKey.transaction do api_key.update!(revoked_at: Time.zone.now) StaffActionLogger.new(Discourse.system_user).log_api_key( api_key, UserHistory.actions[:api_key_update], changes: api_key.saved_changes, context: I18n.t( "staff_action_logs.api_key.automatic_revoked_max_life", count: SiteSetting.revoke_api_keys_maxlife_days, ), ) end end end |
.revoke_unused_keys! ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'app/models/api_key.rb', line 47 def self.revoke_unused_keys! return if SiteSetting.revoke_api_keys_unused_days == 0 # Never expire keys to_revoke = active.where( "GREATEST(last_used_at, created_at, updated_at, :epoch) < :threshold", epoch: last_used_epoch, threshold: SiteSetting.revoke_api_keys_unused_days.days.ago, ) to_revoke.find_each do |api_key| ApiKey.transaction do api_key.update!(revoked_at: Time.zone.now) StaffActionLogger.new(Discourse.system_user).log_api_key( api_key, UserHistory.actions[:api_key_update], changes: api_key.saved_changes, context: I18n.t( "staff_action_logs.api_key.automatic_revoked", count: SiteSetting.revoke_api_keys_unused_days, ), ) end end end |
Instance Method Details
#generate_key ⇒ Object
24 25 26 27 28 29 30 |
# File 'app/models/api_key.rb', line 24 def generate_key if !self.key_hash @key ||= SecureRandom.hex(32) # Not saved to DB self.truncated_key = key[0..3] self.key_hash = ApiKey.hash_key(key) end end |
#key ⇒ Object
32 33 34 35 36 37 |
# File 'app/models/api_key.rb', line 32 def key unless key_available? raise KeyAccessError.new "API key is only accessible immediately after creation" end @key end |
#key_available? ⇒ Boolean
39 40 41 |
# File 'app/models/api_key.rb', line 39 def key_available? @key.present? end |
#request_allowed?(env) ⇒ Boolean
102 103 104 105 106 107 108 109 |
# File 'app/models/api_key.rb', line 102 def request_allowed?(env) if allowed_ips.present? && allowed_ips.none? { |ip| ip.include?(Rack::Request.new(env).ip) } return false end return true if RouteMatcher.new(methods: :get, actions: "session#scopes").match?(env: env) api_key_scopes.blank? || api_key_scopes.any? { |s| s.permits?(env) } end |
#update_last_used!(now = Time.zone.now) ⇒ Object
111 112 113 114 115 116 |
# File 'app/models/api_key.rb', line 111 def update_last_used!(now = Time.zone.now) return if last_used_at && (last_used_at > 1.minute.ago) # using update_column to avoid the AR transaction update_column(:last_used_at, now) end |