From cfd0935bdcd39e4606d8ea2caf07776e785a912a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Mon, 20 Nov 2023 18:22:28 +0100 Subject: [PATCH] Notify user about new RS authorizations --- app/mailers/notification_mailer.rb | 7 ++ app/models/remote_storage_authorization.rb | 20 +++- app/services/router.rb | 7 ++ .../remotestorage_auth_created.text.erb | 23 ++++ .../remote_storage_authorization_spec.rb | 105 +++++++++++------- 5 files changed, 121 insertions(+), 41 deletions(-) create mode 100644 app/services/router.rb create mode 100644 app/views/notification_mailer/remotestorage_auth_created.text.erb diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index 84f7dd5..19fc8ec 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -5,4 +5,11 @@ class NotificationMailer < ApplicationMailer @subject = "Sats received" mail to: @user.email, subject: @subject end + + def remotestorage_auth_created + @user = params[:user] + @auth = params[:auth] + @subject = "New app connected to your storage" + mail to: @user.email, subject: @subject + end end diff --git a/app/models/remote_storage_authorization.rb b/app/models/remote_storage_authorization.rb index 53ca1b1..2e574d5 100644 --- a/app/models/remote_storage_authorization.rb +++ b/app/models/remote_storage_authorization.rb @@ -18,7 +18,7 @@ class RemoteStorageAuthorization < ApplicationRecord before_create :store_token_in_redis before_create :find_or_create_web_app after_create :schedule_token_expiry - # after_create :notify_user + after_create :notify_user before_destroy :delete_token_from_redis after_destroy :remove_token_expiry_job @@ -93,4 +93,22 @@ class RemoteStorageAuthorization < ApplicationRecord rescue URI::InvalidURIError false end + + def notify_user + notify = user.preferences[:remotestorage_notify_auth_created] + + case notify + when "xmpp" + router = Router.new + payload = { + type: "normal", to: user.address, + from: Setting.xmpp_notifications_from_address, + body: "You have just granted '#{self.client_id}' access to your Kosmos Storage. Visit your Storage dashboard to check on your connected apps and revoke permissions anytime: #{router.services_storage_url}" + } + XmppSendMessageJob.perform_later(payload) + when "email" + NotificationMailer.with(user: user, auth: self) + .remotestorage_auth_created.deliver_later + end + end end diff --git a/app/services/router.rb b/app/services/router.rb new file mode 100644 index 0000000..a7536ff --- /dev/null +++ b/app/services/router.rb @@ -0,0 +1,7 @@ +class Router + include Rails.application.routes.url_helpers + + def self.default_url_options + ActionMailer::Base.default_url_options + end +end diff --git a/app/views/notification_mailer/remotestorage_auth_created.text.erb b/app/views/notification_mailer/remotestorage_auth_created.text.erb new file mode 100644 index 0000000..cc8cd31 --- /dev/null +++ b/app/views/notification_mailer/remotestorage_auth_created.text.erb @@ -0,0 +1,23 @@ +Hi <%= @user.display_name.presence || @user.cn %>, + +You have just granted '<%= @auth.client_id %>' access to your Kosmos Storage, with the following permissions: + +<% @permissions.each do |p| %> +* <%= p %> +<% end %> + +Visit your Storage dashboard to check on your connected apps and revoke permissions anytime: + +<%= services_storage_url %> + +Have fun! + +--- + +You can disable email notifications for new app authorizations in your account settings: +<%= setting_path(:remotestorage) %> + +<% if Setting.discourse_enabled %> +If you have any questions, please visit our community forums: +<%= Setting.discourse_public_url %> +<% end %> diff --git a/spec/models/remote_storage_authorization_spec.rb b/spec/models/remote_storage_authorization_spec.rb index 8fadd34..3673bde 100644 --- a/spec/models/remote_storage_authorization_spec.rb +++ b/spec/models/remote_storage_authorization_spec.rb @@ -245,44 +245,69 @@ RSpec.describe RemoteStorageAuthorization, type: :model do end end - # describe "auth notifications" do - # context "with auth notifications enabled" do - # before do - # ResqueSpec.reset! - # user.push(mailing_lists: "rs-auth-notifications-#{Rails.env}") - # auth = user.remote_storage_authorizations.create!( - # :permissions => %w(documents photos contacts:rw videos:r tasks/work:r), - # :client_id => "example.com", - # :redirect_uri => "https://example.com" - # ) - # end - # - # it "notifies the user via email" do - # expect(enqueued_jobs.size).to eq(1) - # job = enqueued_jobs.first - # expect(job).to eq( - # job: ActionMailer::DeliveryJob, - # args: ['StorageAuthorizationMailer', 'authorized_rs_app', 'deliver_now', - # auth.id.to_s], - # queue: 'mailers' - # ) - # end - # end - # - # context "with auth notifications disabled" do - # before do - # ResqueSpec.reset! - # user.pull(mailing_lists: "rs-auth-notifications-#{Rails.env}") - # auth = user.remote_storage_authorizations.create!( - # :permissions => %w(documents photos contacts:rw videos:r tasks/work:r), - # :client_id => "example.com", - # :redirect_uri => "https://example.com" - # ) - # end - # - # it "does not notify the user via email about new RS app" do - # expect(enqueued_jobs.size).to eq(0) - # end - # end - # end + describe "notifications" do + include ActiveJob::TestHelper + + after(:each) { clear_enqueued_jobs } + after(:all) { redis_rs_delete_keys("authorizations:*") } + + before { allow(user).to receive(:display_name).and_return("Jimmy") } + + context "with notifications disabled" do + before do + user.preferences.merge!({ remotestorage_notify_auth_created: "off" }) + user.save! + user.remote_storage_authorizations.create!( + :permissions => %w(photos), :client_id => "app.example.com", + :redirect_uri => "https://app.example.com" + ) + end + + it "does not notify the user via email about new RS app" do + expect(enqueued_jobs.size).to eq(0) + end + end + + context "with email notifications enabled" do + before do + user.preferences.merge!({ remotestorage_notify_auth_created: "email" }) + user.save! + user.remote_storage_authorizations.create!( + :permissions => %w(photos), :client_id => "app.example.com", + :redirect_uri => "https://app.example.com" + ) + end + + it "notifies the user via email" do + expect(enqueued_jobs.size).to eq(1) + job = enqueued_jobs.select{|j| j['job_class'] == "ActionMailer::MailDeliveryJob"}.first + expect(job['arguments'][0]).to eq('NotificationMailer') + expect(job['arguments'][1]).to eq('remotestorage_auth_created') + expect(job['arguments'][3]['params']['user']['_aj_globalid']).to eq('gid://akkounts/User/1') + expect(job['arguments'][3]['params']['auth']['_aj_globalid']).to eq('gid://akkounts/RemoteStorageAuthorization/1') + end + end + + context "with XMPP notifications enabled" do + before do + Setting.xmpp_notifications_from_address = "botka@kosmos.org" + user.preferences.merge!({ remotestorage_notify_auth_created: "xmpp" }) + user.save! + user.remote_storage_authorizations.create!( + :permissions => %w(photos), :client_id => "app.example.com", + :redirect_uri => "https://app.example.com" + ) + end + + it "sends an XMPP message to the account owner's JID" do + expect(enqueued_jobs.size).to eq(1) + expect(enqueued_jobs.first["job_class"]).to eq("XmppSendMessageJob") + msg = enqueued_jobs.first["arguments"].first + expect(msg["type"]).to eq("normal") + expect(msg["from"]).to eq("botka@kosmos.org") + expect(msg["to"]).to eq(user.address) + expect(msg["body"]).to match(/granted 'app\.example\.com' access to your Kosmos Storage/) + end + end + end end