aboutsummaryrefslogtreecommitdiff
path: root/app/jobs/agency_watcher_job.rb
diff options
context:
space:
mode:
authorhellekin <hellekin@cepheide.org>2020-10-06 00:26:44 +0200
committerhellekin <hellekin@cepheide.org>2020-10-06 00:26:44 +0200
commit09ac92747bfbda80a54e44b22576d29d9dfc63c3 (patch)
treef76d590bc8cc979d9a42527afe940c7fe00ff315 /app/jobs/agency_watcher_job.rb
parentf0a00d02d30509b3b56026e9e4d119bce3a82d99 (diff)
downloadincommon-map-09ac92747bfbda80a54e44b22576d29d9dfc63c3.tar.gz
Extract Role check to a background job
When using SSO, the Discourse sends a list of the user groups. We take the opportunity to update Agency information for the user. This is performed as a background job, as it involves networked requests to the Discourse, e.g., to verify group ownership...
Diffstat (limited to 'app/jobs/agency_watcher_job.rb')
-rw-r--r--app/jobs/agency_watcher_job.rb54
1 files changed, 54 insertions, 0 deletions
diff --git a/app/jobs/agency_watcher_job.rb b/app/jobs/agency_watcher_job.rb
new file mode 100644
index 0000000..5cc0256
--- /dev/null
+++ b/app/jobs/agency_watcher_job.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+# = AgencyWatcherJob
+#
+# This job performs checks on existing records for the given user and group
+# names and updates Agencies accordingly.
+#
+# @param user (User) currently logged in user
+# @param groups (Array) a list of group names
+#
+class AgencyWatcherJob < ApplicationJob
+ queue_as :default
+
+ def perform(user, groups)
+ # Check groups against user agents
+ existing_agents = Agent.where(name: groups)
+ existing_agent_names = existing_agents.map(&:name)
+
+ groups.each do |g|
+ # Only work with existing agents
+ next unless existing_agent_names.include?(g)
+
+ a = existing_agents.select { |a| a.name = g }.first
+
+ Rails.logger.debug("AgencyWatcher checking roles for %s in %s" % [user.username, g])
+ # Check if user is a group owner
+ r = a.agencies.find_or_create_by(user: user)
+ if !r.leader? && is_group_owner?(g, user.username)
+ Rails.logger.debug("AgencyWatcher: grant leader to %s in %s" % [user.username, g])
+ # Grant leader
+ r.grant(:leader)
+ elsif r.roles == 0
+ # No role: grant editor
+ Rails.logger.debug("AgencyWatcher: grant editor to %s in %s" % [user.username, g])
+ r.grant(:observer)
+ else
+ # No change
+ Rails.logger.debug("AgencyWatcher: %s's roles in %s are %s" % [user.username, g, r.bitfield_values(:roles)])
+ end
+ end
+ end
+
+ private
+
+ # Connect to Discourse and check whether current user is a group owner
+ def is_group_owner?(group, username)
+ c = ::DiscourseApi::Client.new('https://talk.incommon.cc')
+ c.api_key = Rails.application.credentials.talk_api_key
+ c.api_username = username
+
+ group = c.group(group)
+ group['group']['is_group_owner'] == true
+ end
+end