• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Build has been canceled!

curationexperts / laevigata / 90fcbe81-971e-4d3f-858a-e0ec8e932fa6

01 Jul 2025 05:37PM UTC coverage: 97.424%. Remained the same
90fcbe81-971e-4d3f-858a-e0ec8e932fa6

Pull #2468

circleci

mark-dce
Fix redlock deprecation warnings

**ISSUE**
After the `Redis.current` fix, we are now seeing significant numbers
of deprecations warnings like:
```
Passing 'call' command to redis as is; blind passthrough has been
  deprecated and will be removed in redis-namespace 2.0
  (at /Users/mark/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/
   redlock-2.0.6/lib/redlock/client.rb:214:in `block (2 levels) in unlock')
```

**DIAGNOSIS**
We were passing a RedisNamespace object to Redlock instead of a
plain Redis connection specifier. RedisNamespace was complaining
any time an admin (not-namespace-able) command was received.

**RESOLUTION**
Pass a Redis URI to RedLock instead of a RedisNamespace object.
Pull Request #2468: Fix redlock deprecation warnings

2 of 2 new or added lines in 1 file covered. (100.0%)

122 existing lines in 26 files now uncovered.

2837 of 2912 relevant lines covered (97.42%)

52.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/lib/workflow_setup.rb
1
# Set up the AdminSets and Workflow for Laevigata
2
require File.expand_path('../../config/environment', __FILE__)
4✔
3
require 'yaml'
4✔
4

5
# Set up the application's initial state: load required roles, create required AdminSets, load appropriate users and workflows
6
class WorkflowSetup
4✔
7
  include SemanticLogger::Loggable
4✔
8

9
  attr_reader :admin_set_owner
4✔
10
  attr_reader :admin_sets_config
4✔
11
  attr_accessor :superusers_config
4✔
12
  ADMIN_SET_OWNER = "admin_set_owner".freeze
4✔
13
  NOTIFICATION_OWNER = "notification_owner".freeze
4✔
14
  DEFAULT_SUPERUSERS_CONFIG = "#{::Rails.root}/config/emory/superusers.yml".freeze
4✔
15
  DEFAULT_ADMIN_SETS_CONFIG = "#{::Rails.root}/config/emory/admin_sets.yml".freeze
4✔
16

17
  # Set up the parameters for
18
  # @param [String] superusers_config a file containing the email addresses of the application's superusers
19
  # @param [String] config_file_dir the directory where the config files reside
20
  # @param [String] schools_config
21
  # @param [String] log_location where should the log files write? Default is STDOUT. /dev/null is also an option for CI builds
22
  def initialize(superusers_config = DEFAULT_SUPERUSERS_CONFIG, admin_sets_config = DEFAULT_ADMIN_SETS_CONFIG, _log_location = STDOUT)
4✔
23
    raise "File #{superusers_config} does not exist" unless File.exist?(superusers_config)
68✔
24
    @superusers_config = YAML.safe_load(File.read(superusers_config))
68✔
25
    raise "File #{admin_sets_config} does not exist" unless File.exist?(admin_sets_config)
68✔
26
    @admin_sets_config = YAML.safe_load(File.read(admin_sets_config))
68✔
27
    logger.info "Initializing new workflow setup with superusers file #{superusers_config} and admin_sets_config files from #{admin_sets_config}"
68✔
28
    Hyrax::RoleRegistry.new.persist_registered_roles! # Ensure we have a managing and a depositing role
68✔
29
    @admin_set_owner = make_superuser(ADMIN_SET_OWNER)
68✔
30
  end
31

32
  # Load the superusers
33
  # Make an AdminSet for each school, with the proper workflow
34
  # Allow any registered user to deposit into any of the AdminSets
35
  # Give superusers every available role in all workflows in all AdminSets
36
  def setup
4✔
37
    make_notification_owner
46✔
38
    load_superusers
46✔
39
    admin_sets.each do |as|
46✔
40
      logger.debug "Attempting to make admin set for #{as}"
54✔
41
      make_admin_set_from_config(as)
54✔
42
    end
43
    load_workflows
46✔
44
    everyone_can_deposit_everywhere
46✔
45
    give_superusers_superpowers
46✔
46
  end
47

48
  # A ::User to own notifications
49
  def make_notification_owner
4✔
50
    u = ::User.find_or_create_by(uid: NOTIFICATION_OWNER)
47✔
51
    u.ppid = NOTIFICATION_OWNER
47✔
52
    u.display_name = "ETD Notification System"
47✔
53
    u.save
47✔
54
  end
55

56
  # Make an AdminSet and assign it a one step mediated deposit workflow
57
  # @param [String] admin_set_title The title of the admin set to create
58
  # @param [String] workflow_name The name of the mediated deposit workflow to enable
59
  def make_mediated_deposit_admin_set(admin_set_title, workflow_name = "emory_one_step_approval")
4✔
60
    a = make_admin_set(admin_set_title)
62✔
61
    activate_mediated_deposit(a, workflow_name)
62✔
62
    a
62✔
63
  end
64

65
  # Given an admin set and a role, return relevant Array of Sipity::Users for the
66
  # currently active workflow
67
  # @param [AdminSet] admin_set
68
  # @param [String|Sipity::Role] role e.g., "approving" "depositing" "managing"
69
  # @return [Array<Sipity::Agent>] An array of Sipity::Agent objects
70
  def users_in_role(admin_set, role)
4✔
71
    return [] unless admin_set.permission_template.available_workflows.exists?(active: true)
231✔
72

73
    role     = Sipity::Role.find_by!(name: role) unless role.is_a?(Sipity::Role)
231✔
74
    workflow = admin_set.permission_template.available_workflows.find_by(active: true)
231✔
75
    wf_role  = Sipity::WorkflowRole.find_by(workflow: workflow, role_id: role)
231✔
76
    return [] unless wf_role
231✔
77

78
    Sipity::Agent.where(id: wf_role.workflow_responsibilities.pluck(:agent_id),
231✔
79
                        proxy_for_type: 'User').to_a
80
  end
81

82
  # Read a config file to figure out what workflow to enable and how to grant approving_role
83
  # @param [String] admin_set_title
84
  # @return [AdminSet]
85
  def make_admin_set_from_config(admin_set_title)
4✔
86
    config = admin_set_config(admin_set_title)
59✔
87
    config["workflow"] || config["workflow"] = "emory_one_step_approval"
59✔
88
    admin_set = make_mediated_deposit_admin_set(admin_set_title, config["workflow"])
59✔
89
    approving_users = []
59✔
90
    config["approving"].each do |approver_uid|
59✔
91
      u = ::User.find_or_create_by(uid: approver_uid)
108✔
92
      u.password = "123456" if set_default_password?
108✔
93
      u.provider = "shibboleth"
108✔
94
      u.ppid = approver_uid # temporary ppid, will get replaced when user signs in with shibboleth
108✔
95
      u.save
108✔
96
      approving_users << u.to_sipity_agent
108✔
97
    end
98
    approval_role = Sipity::Role.find_by!(name: 'approving')
59✔
99
    workflow = admin_set.active_workflow
59✔
100
    workflow.update_responsibilities(role: approval_role, agents: (approving_users.concat users_in_role(admin_set, "approving")))
59✔
101
    if workflow.workflow_roles.map { |workflow_role| workflow_role.role.name }.include?("reviewing")
295✔
102
      reviewing_role = Sipity::Role.find_by!(name: 'reviewing')
59✔
103
      workflow.update_responsibilities(role: reviewing_role, agents: (approving_users.concat users_in_role(admin_set, "reviewing")))
59✔
104
    end
105
    admin_set
59✔
106
  end
107

108
  # Create the admin role, or find it if it exists already
109
  # @return [Role] the admin Role
110
  def admin_role
4✔
111
    Role.find_or_create_by(name: "admin")
1,185✔
112
  end
113

114
  # Load the superusers from a config file
115
  def load_superusers
4✔
116
    admin_role.users = [] # Remove all the admin users every time you reload
57✔
117
    admin_role.save
57✔
118
    @superusers_config["superusers"].each_key do |provider|
57✔
119
      @superusers_config["superusers"][provider].each do |s|
114✔
120
        make_superuser(s, provider)
171✔
121
      end
122
    end
123
  end
124

125
  # Make a superuser
126
  # @param [String] the uid of the superuser
127
  # @return [User] the superuser who was just created
128
  def make_superuser(uid, provider = "database")
4✔
129
    logger.debug "Making superuser #{uid}"
245✔
130
    admin_user = ::User.find_or_create_by(uid: uid)
245✔
131
    admin_user.password = "123456" if set_default_password?
245✔
132
    admin_user.ppid = uid # temporary ppid, will get replaced when user signs in with shibboleth
245✔
133
    admin_user.provider = provider
245✔
134
    admin_user.save
245✔
135
    admin_role.users << admin_user
245✔
136
    admin_role.save
245✔
137
    admin_user
245✔
138
  end
139

140
  # Don't set default passwords in production mode
141
  def set_default_password?
4✔
142
    AuthConfig.use_database_auth? && !Rails.env.production?
353✔
143
  end
144

145
  # return an array of all current superusers
146
  # @return [Array(User)]
147
  def superusers
4✔
148
    raise "No superusers are defined" unless admin_role.users.count > 0
289✔
149
    admin_role.users
289✔
150
  end
151

152
  # Allow anyone with a registered account to deposit into any of the AdminSets
153
  def everyone_can_deposit_everywhere
4✔
154
    AdminSet.all.each do |admin_set|
47✔
155
      next if Hyrax::PermissionTemplateAccess
55✔
156
                .find_by(permission_template_id: admin_set.permission_template.id,
157
                         agent_id:   'registered',
158
                         access:     'deposit',
159
                         agent_type: 'group')
160

161
      admin_set.permission_template.access_grants.create(agent_type: 'group', agent_id: 'registered', access: 'deposit')
55✔
162
      deposit = Sipity::Role.find_by!(name: 'depositing')
55✔
163
      admin_set.permission_template.available_workflows.each do |workflow|
55✔
164
        workflow.update_responsibilities(role: deposit, agents: Hyrax::Group.new('registered'))
110✔
165
      end
166
    end
167
  end
168

169
  # Give superusers the managing role in all AdminSets
170
  # Also give them all workflow roles for all AdminSets
171
  def give_superusers_superpowers
4✔
172
    logger.info "Giving superuser powers to #{superusers.pluck(:ppid)}"
48✔
173
    give_superusers_managing_role
48✔
174
    give_superusers_workflow_roles
48✔
175
  end
176

177
  def superusers_as_sipity_agents
4✔
178
    superusers.map(&:to_sipity_agent)
224✔
179
  end
180

181
  # Give all superusers the managing role all workflows
182
  def give_superusers_managing_role
4✔
183
    AdminSet.all.each do |admin_set|
48✔
184
      admin_set.permission_template.available_workflows.each do |workflow| # .where(active: true) ?
56✔
185
        workflow.update_responsibilities(role: Sipity::Role.where(name: "managing").first, agents: superusers_as_sipity_agents)
112✔
186
      end
187
    end
188
  end
189

190
  def give_superusers_workflow_roles
4✔
191
    AdminSet.all.each do |admin_set|
48✔
192
      admin_set.permission_template.available_workflows.where(active: true).each do |workflow|
56✔
193
        workflow_roles = Sipity::WorkflowRole.where(workflow_id: workflow.id)
56✔
194
        workflow_roles.each do |workflow_role|
56✔
195
          workflow_role_name = Sipity::Role.where(id: workflow_role.role_id).first.name
224✔
196
          next if workflow_role_name == "depositing" || workflow_role_name == "managing"
224✔
197
          union_of_users = superusers_as_sipity_agents.concat(users_in_role(admin_set, workflow_role_name)).uniq
112✔
198
          logger.debug "Granting #{workflow_role_name} to #{union_of_users.map { |u| User.where(id: u.proxy_for_id).first.ppid }.to_sentence}"
760✔
199
          workflow.update_responsibilities(role: Sipity::Role.where(id: workflow_role.role_id), agents: union_of_users)
112✔
200
        end
201
      end
202
    end
203
  end
204

205
  # Make an AdminSet with the given title, belonging to the @admin_set_owner
206
  # @return [AdminSet] the admin set that was just created, or the one that existed already
207
  def make_admin_set(admin_set_title)
4✔
208
    if AdminSet.where(title_sim: admin_set_title).count > 0
66✔
209
      logger.debug "AdminSet #{admin_set_title} already exists."
1✔
210
      return AdminSet.where(title_sim: admin_set_title).first
1✔
211
    end
212
    a = AdminSet.create(title: [admin_set_title])
65✔
213
    Hyrax::AdminSetCreateService.call(admin_set: a, creating_user: @admin_set_owner)
65✔
214
    a
65✔
215
  end
216

217
  # Load the workflows from config/workflows
218
  # Does the same thing as `bin/rails hyrax:workflow:load`
219
  # Note: You MUST create an AdminSet (and its associated PermissionTemplate first)
220
  # If you think you have the right AdminSet, but workflows won't load, check that
221
  # the permission templates didn't get wiped from the database somehow
222
  def load_workflows
4✔
223
    raise "Can't load workflows without a Permission Template. Do you need to make an AdminSet first?" if Hyrax::PermissionTemplate.all.empty?
46✔
224
    Hyrax::Workflow::WorkflowImporter.load_workflows(logger: logger)
46✔
225
    errors = Hyrax::Workflow::WorkflowImporter.load_errors
46✔
226
    abort("Failed to process all workflows:\n  #{errors.join('\n  ')}") unless errors.empty?
46✔
227
  end
228

229
  # Activate a mediated deposit workflow for the given admin_set.
230
  # Default is emory_one_step_approval, but a different value can be passed in.
231
  # The activate! method will DEactivate it if it was already active, so be careful.
232
  # @return [Boolean] true if successful
233
  def activate_mediated_deposit(admin_set, workflow_name = "emory_one_step_approval")
4✔
234
    osmd = admin_set.permission_template.available_workflows.where(name: workflow_name).first
63✔
235
    if osmd.active == true
63✔
236
      logger.debug "AdminSet #{admin_set.title.first} already had workflow #{admin_set.permission_template.available_workflows.where(active: true).first.name}. Not making any changes."
47✔
237
      return true
47✔
238
    end
UNCOV
239
    Sipity::Workflow.activate!(
16✔
240
      permission_template: admin_set.permission_template,
241
      workflow_id: osmd.id
242
    )
UNCOV
243
    logger.debug "AdminSet #{admin_set.title.first} has workflow #{admin_set.permission_template.available_workflows.where(active: true).first.name}"
16✔
UNCOV
244
    true
16✔
245
  end
246

247
  # Return an array of AdminSets that should be set up for the initial workflow
248
  # @return [Array(String)]
249
  def admin_sets
4✔
250
    @admin_sets_config.keys
54✔
251
  end
252

253
  # Given the name of a school, read its config into a Hash
254
  # @param [String] the name of an admin_set
255
  # @return [Hash] a Hash containing approvers and (optionally) workflow for this school
256
  def admin_set_config(school_name)
4✔
257
    raise "Couldn't find expected config for #{school_name}" unless @admin_sets_config[school_name]
61✔
258
    @admin_sets_config[school_name]
60✔
259
  end
260
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc