• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pulibrary / pdc_describe / 8e9732e2-83fa-4961-bdbf-17cf01e42d76

03 Jul 2024 11:54AM UTC coverage: 95.605% (-0.3%) from 95.894%
8e9732e2-83fa-4961-bdbf-17cf01e42d76

push

circleci

carolyncole
Making the UID not include unsafe characters for routing
external uids are the entire email
refs #1823

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

10 existing lines in 2 files now uncovered.

3263 of 3413 relevant lines covered (95.61%)

196.25 hits per line

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

93.18
/app/models/user.rb
1
# frozen_string_literal: true
2
require "csv"
1✔
3

4
# rubocop:disable Metrics/ClassLength
5
class User < ApplicationRecord
1✔
6
  rolify
1✔
7
  extend FriendlyId
1✔
8
  friendly_id :uid
1✔
9

10
  devise :rememberable, :omniauthable
1✔
11

12
  # GroupOptions model extensible options set for Groups and Users
13
  has_many :group_options, dependent: :destroy
1✔
14
  has_many :group_messaging_options, -> { where(option_type: GroupOption::EMAIL_MESSAGES) }, class_name: "GroupOption", dependent: :destroy
1✔
15

16
  has_many :groups_with_options, through: :group_options, source: :group
1✔
17
  has_many :groups_with_messaging, through: :group_messaging_options, source: :group
1✔
18

19
  after_create :assign_default_role
1✔
20

21
  attr_accessor :just_created
1✔
22

23
  validate do |user|
1✔
24
    user.orcid&.strip!
1,284✔
25
    if user.orcid.present? && Orcid.invalid?(user.orcid)
1,284✔
26
      user.errors.add :base, "Invalid format for ORCID"
1✔
27
    end
28
  end
29

30
  def self.from_cas(access_token)
1✔
31
    user = User.find_by(uid: safe_uid(access_token.uid))
12✔
32
    if user.nil?
12✔
33
      user = new_from_cas(access_token)
12✔
UNCOV
34
    elsif user.provider.blank?
×
UNCOV
35
      user.update_with_cas(access_token)
×
36
    end
37
    user
12✔
38
  end
39

40
  # Create a new user with some basic information from CAS.
41
  def self.new_from_cas(access_token)
1✔
42
    user = User.new
12✔
43
    user.provider = access_token.provider
12✔
44
    user.uid = safe_uid(access_token.uid) # this is the netid
12✔
45
    user.email = access_token.extra.mail
12✔
46
    user.given_name = access_token.extra.givenname || access_token.uid # Harriet
12✔
47
    user.family_name = access_token.extra.sn || access_token.uid # Tubman
12✔
48
    user.full_name = access_token.extra.displayname || access_token.uid # "Harriet Tubman"
12✔
49
    user.default_group_id = Group.default_for_department(access_token.extra.departmentnumber)&.id
12✔
50
    user.save!
12✔
51
    user
12✔
52
  end
53

54
  def self.safe_uid(uid)
1✔
55
    return uid if uid.blank?
30✔
56
    uid.gsub(/[^(a-zA-Z_\-)]/,"_")
30✔
57
  end
58

59
  # Updates an existing User record with some information from CAS. This is useful
60
  # for records created before the user ever logged in (e.g. to gran them permissions
61
  # to groups).
62
  def update_with_cas(access_token)
1✔
UNCOV
63
    self.provider = access_token.provider
×
UNCOV
64
    self.email = access_token.extra.mail
×
UNCOV
65
    self.given_name = access_token.extra.givenname || access_token.uid # Harriet
×
UNCOV
66
    self.family_name = access_token.extra.sn || access_token.uid # Tubman
×
UNCOV
67
    self.full_name = access_token.extra.displayname || access_token.uid # "Harriet Tubman"
×
UNCOV
68
    self.default_group_id ||= Group.default_for_department(access_token.extra.departmentnumber)&.id
×
UNCOV
69
    save!
×
70
  end
71

72
  # Creates a new user by uid. If the user already exists it returns the existing user.
73
  def self.new_for_uid(uid)
1✔
74
    user = User.find_by(uid:)
70✔
75
    if user.nil?
70✔
76
      user = User.new(uid:, email: "#{uid}@princeton.edu")
22✔
77
      user.save!
22✔
78
    end
79
    user
70✔
80
  end
81

82
  def self.new_super_admin(uid)
1✔
83
    user = new_for_uid(uid)
50✔
84
    user.add_role(:super_admin) unless user.has_role?(:super_admin)
50✔
85
    user.add_role(:group_admin) unless user.has_role?(:group_admin)
50✔
86
    user
50✔
87
  end
88

89
  # rubocop:disable Metrics/MethodLength
90
  def self.new_from_csv_params(csv_params)
1✔
91
    email = "#{csv_params['Net ID']}@princeton.edu"
7✔
92
    uid = csv_params["Net ID"]
7✔
93
    given_name = csv_params["First Name"]
7✔
94
    family_name = csv_params["Last Name"]
7✔
95
    full_name = "#{given_name} #{family_name}"
7✔
96
    orcid = csv_params["ORCID ID"]
7✔
97
    user = User.where(email:).first_or_create
7✔
98
    params_hash = {
99
      email:,
7✔
100
      uid:,
101
      orcid:,
102
      full_name: (full_name if user.full_name.blank?),
7✔
103
      family_name: (family_name if user.family_name.blank?),
7✔
104
      given_name: (given_name if user.given_name.blank?)
7✔
105
    }.compact
106

107
    user.update(params_hash)
7✔
108
    Rails.logger.info "Successfully created or updated #{user.email}"
7✔
109
    user
7✔
110
  end
111
  # rubocop:enable Metrics/MethodLength
112

113
  def self.create_users_from_csv(csv)
1✔
114
    users = []
1✔
115
    CSV.foreach(csv, headers: true) do |row|
1✔
116
      next if row["Net ID"] == "N/A"
3✔
117
      users << new_from_csv_params(row.to_hash)
3✔
118
    end
119
    users
1✔
120
  end
121

122
  # Creates the default users as indicated in the super_admin config file
123
  # and the default administrators and submitters for each group.
124
  # It only creates missing records, i.e. if the records already exist it
125
  # will not create a duplicate. It also does _not_ remove already configured
126
  # access to other groups.
127
  def self.create_default_users
1✔
128
    update_super_admins
1✔
129

130
    Group.find_each do |group|
1✔
131
      Rails.logger.info "Setting up admins for group #{group.title}"
2✔
132
      group.default_admins_list.each do |uid|
2✔
133
        user = User.new_for_uid(uid)
1✔
134
        user.add_role :group_admin, group
1✔
135
      end
136

137
      Rails.logger.info "Setting up submitters for group #{group.title}"
2✔
138
      group.default_submitters_list.each do |uid|
2✔
139
        user = User.new_for_uid(uid)
2✔
140
        user.add_role :submitter, group
2✔
141
      end
142
    end
143
  end
144

145
  def self.update_super_admins
1✔
146
    Rails.logger.info "Setting super administrators"
2✔
147
    Rails.configuration.super_admins.each do |uid|
2✔
148
      new_super_admin(uid)
2✔
149
    end
150
  end
151

152
  # Returns a string with the UID (netid) for all the users.
153
  # We use this string to power the JavaScript @mention functionality when adding messages to works.
154
  def self.all_uids_string
1✔
155
    User.all.map { |user| '"' + user.uid + '"' }.join(", ")
257✔
156
  end
157

158
  ##
159
  # Is this user a super_admin? super_admins automatically get admin status in every
160
  # group, and they can make new groups.
161
  # @return [Boolean]
162
  def super_admin?
1✔
163
    has_role? :super_admin
4,465✔
164
  rescue => ex
165
    Rails.logger.error("Unexpected error checking super_admin: #{ex}")
1✔
166
    false
1✔
167
  end
168

169
  # Returns a display name that always has a value
170
  # This is needed because we have records in the Users table that are created automatically
171
  # in which the only value we have for sure its their uid (aka NetID).
172
  def given_name_safe
1✔
173
    given_name.presence || uid
208✔
174
  end
175

176
  # Returns a full name that always has a value
177
  # This is needed because we have records in the Users table that are created automatically
178
  # in which the only value we have for sure its their uid (aka NetID).
179
  def full_name_safe
1✔
180
    full_name&.strip.presence || uid
36✔
181
  end
182

183
  def moderator?
1✔
184
    admin_groups.count > 0
815✔
185
  end
186

187
  # Returns a reference to the user's default group.
188
  def default_group
1✔
189
    if default_group_id.nil?
3,848✔
190
      Group.default
2,987✔
191
    else
192
      Group.find(default_group_id)
861✔
193
    end
194
  end
195

196
  # True if the user can submit datasets to the group
197
  def can_submit?(group)
1✔
198
    return true if super_admin?
1,339✔
199
    has_role?(:submitter, group)
1,337✔
200
  end
201

202
  # Returns true if the user can admin the group
203
  def can_admin?(group)
1✔
204
    return true if super_admin?
1,999✔
205
    has_role? :group_admin, group
1,865✔
206
  end
207

208
  # Returns the list of groups where the user can submit datasets
209
  def submitter_groups
1✔
210
    @submitter_groups = if super_admin?
98✔
211
                          Group.all.to_a
10✔
212
                        else
213
                          (Group.with_role(:submitter, self) + Group.with_role(:group_admin, self)).uniq
88✔
214
                        end
215
  end
216

217
  # Returns the list of groups where the user is an administrator
218
  def admin_groups
1✔
219
    @admin_groups ||= if super_admin?
1,117✔
220
                        Group.all.to_a
48✔
221
                      else
222
                        Group.with_role(:group_admin, self)
397✔
223
                      end
224
  end
225

226
  def submitter_or_admin_groups
1✔
227
    submitter_groups | admin_groups
9✔
228
  end
229

230
  def pending_notifications_count
1✔
231
    WorkActivityNotification.where(user_id: id, read_at: nil).count
62✔
232
  end
233

234
  def assign_default_role
1✔
235
    @just_created = true
1,261✔
236
    add_role(:submitter, default_group) unless has_role?(:submitter, default_group)
1,261✔
237
    default_group.enable_messages_for(user: self)
1,261✔
238
  end
239

240
  # Returns true if the user has notification e-mails enabled
241
  # @return [Boolean]
242
  def email_messages_enabled?
1✔
243
    email_messages_enabled
196✔
244
  end
245
end
246
# rubocop:enable Metrics/ClassLength
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

© 2025 Coveralls, Inc