Persist RS auth tokens in Redis
This commit is contained in:
parent
dabd892a25
commit
42af148168
10
app/jobs/expire_remote_storage_authorization_job.rb
Normal file
10
app/jobs/expire_remote_storage_authorization_job.rb
Normal file
@ -0,0 +1,10 @@
|
||||
class ExpireRemoteStorageAuthorizationJob < ApplicationJob
|
||||
queue_as :remote_storage
|
||||
|
||||
def perform(rs_auth_id)
|
||||
rs_auth = RemoteStorageAuthorization.find rs_auth_id
|
||||
return unless rs_auth.expire_at.nil? || rs_auth.expire_at <= DateTime.now
|
||||
|
||||
rs_auth.destroy!
|
||||
end
|
||||
end
|
@ -14,6 +14,10 @@ class RemoteStorageAuthorization < ApplicationRecord
|
||||
end
|
||||
|
||||
before_create :generate_token
|
||||
before_create :store_token_in_redis
|
||||
after_create :schedule_token_expiry
|
||||
before_destroy :delete_token_from_redis
|
||||
after_destroy :remove_token_expiry_job
|
||||
|
||||
def url
|
||||
if self.redirect_uri
|
||||
@ -24,9 +28,36 @@ class RemoteStorageAuthorization < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
def delete_token_from_redis
|
||||
key = "rs:authorizations:#{user.address}:#{token}"
|
||||
# You can't delete multiple members of a set with Redis 2
|
||||
redis.smembers(key).each { |auth| redis.srem(key, auth) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redis
|
||||
@redis ||= Redis.new(url: Setting.redis_url)
|
||||
end
|
||||
|
||||
def generate_token(length=16)
|
||||
self.token = SecureRandom.hex(length) if self.token.blank?
|
||||
end
|
||||
|
||||
def store_token_in_redis
|
||||
redis.sadd "rs:authorizations:#{user.address}:#{token}", permissions
|
||||
end
|
||||
|
||||
def schedule_token_expiry
|
||||
return unless expire_at.present?
|
||||
ExpireRemoteStorageAuthorizationJob.set(wait_unil: expire_at).perform_later(id)
|
||||
end
|
||||
|
||||
def remove_token_expiry_job
|
||||
queue = Sidekiq::Queue.new(ExpireRemoteStorageAuthorizationJob.queue_name)
|
||||
queue.each do |job|
|
||||
next unless job.display_class == "ExpireRemoteStorageAuthorizationJob"
|
||||
job.delete if job.display_args == [id]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
9
spec/factories/remote_storage_authorizations.rb
Normal file
9
spec/factories/remote_storage_authorizations.rb
Normal file
@ -0,0 +1,9 @@
|
||||
FactoryBot.define do
|
||||
factory :remote_storage_authorization do
|
||||
permissions { ["documents:rw"] }
|
||||
client_id { "some-fancy-app" }
|
||||
redirect_uri { "https://example.com/some-fancy-app" }
|
||||
app_name { "Fancy App" }
|
||||
expire_at { nil }
|
||||
end
|
||||
end
|
36
spec/jobs/expire_remote_storage_authorization_job_spec.rb
Normal file
36
spec/jobs/expire_remote_storage_authorization_job_spec.rb
Normal file
@ -0,0 +1,36 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ExpireRemoteStorageAuthorizationJob, type: :job do
|
||||
before do
|
||||
@user = create :user, cn: "ronald", ou: "kosmos.org"
|
||||
@rs_authorization = create :remote_storage_authorization, user: @user, expire_at: 1.day.ago
|
||||
end
|
||||
|
||||
after do
|
||||
clear_enqueued_jobs
|
||||
clear_performed_jobs
|
||||
end
|
||||
|
||||
subject(:job) {
|
||||
described_class.perform_later(@rs_authorization.id)
|
||||
}
|
||||
|
||||
let(:redis) {
|
||||
@redis ||= Redis.new(url: Setting.redis_url)
|
||||
}
|
||||
|
||||
it "removes the RS authorization from redis" do
|
||||
redis_key = "rs:authorizations:#{@user.address}:#{@rs_authorization.token}"
|
||||
expect(redis.keys(redis_key)).to_not be_empty
|
||||
|
||||
perform_enqueued_jobs { job }
|
||||
|
||||
expect(redis.keys(redis_key)).to be_empty
|
||||
end
|
||||
|
||||
it "deletes the RS authorization object" do
|
||||
expect {
|
||||
perform_enqueued_jobs { job }
|
||||
}.to change(RemoteStorageAuthorization, :count).by(-1)
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user