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
|
end
|
||||||
|
|
||||||
before_create :generate_token
|
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
|
def url
|
||||||
if self.redirect_uri
|
if self.redirect_uri
|
||||||
@ -24,9 +28,36 @@ class RemoteStorageAuthorization < ApplicationRecord
|
|||||||
end
|
end
|
||||||
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
|
private
|
||||||
|
|
||||||
|
def redis
|
||||||
|
@redis ||= Redis.new(url: Setting.redis_url)
|
||||||
|
end
|
||||||
|
|
||||||
def generate_token(length=16)
|
def generate_token(length=16)
|
||||||
self.token = SecureRandom.hex(length) if self.token.blank?
|
self.token = SecureRandom.hex(length) if self.token.blank?
|
||||||
end
|
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
|
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