Class: User
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- User
- Extended by:
- FriendlyId
- Defined in:
- app/models/user.rb
Overview
rubocop:disable Metrics/ClassLength
Instance Attribute Summary collapse
-
#just_created ⇒ Object
Returns the value of attribute just_created.
Class Method Summary collapse
-
.all_uids_string ⇒ Object
Returns a string with the UID (netid) for all the users.
-
.create_default_users ⇒ Object
Creates the default users as indicated in the super_admin config file and the default administrators and submitters for each group.
-
.create_users_from_csv(csv) ⇒ Object
rubocop:enable Metrics/MethodLength.
- .email_from_access_token(access_token) ⇒ Object
- .email_from_access_token_entra(access_token) ⇒ Object
- .from_cas(access_token) ⇒ Object
- .from_entra(access_token) ⇒ Object
- .looks_like_email_address?(value) ⇒ Boolean
-
.new_for_uid(uid, default_group_id = nil) ⇒ Object
Creates a new user by uid.
-
.new_from_cas(access_token) ⇒ Object
Create a new user with some basic information from CAS.
-
.new_from_csv_params(csv_params) ⇒ Object
rubocop:disable Metrics/MethodLength.
-
.new_from_entra(access_token) ⇒ Object
Create a new user with some basic information from Entra.
- .new_super_admin(uid) ⇒ Object
- .safe_uid(uid) ⇒ Object
- .update_super_admins ⇒ Object
Instance Method Summary collapse
-
#admin_groups ⇒ Object
Returns the list of groups where the user is an administrator.
- #assign_default_role ⇒ Object
-
#can_admin?(group) ⇒ Boolean
Returns true if the user can admin the group.
-
#can_submit?(group) ⇒ Boolean
True if the user can submit datasets to the group.
-
#default_group ⇒ Object
Returns a reference to the user's default group.
-
#email_messages_enabled? ⇒ Boolean
Returns true if the user has notification e-mails enabled.
-
#full_name_safe ⇒ Object
Returns a full name that always has a value This is needed because we have records in the Users table that are created automatically in which the only value we have for sure its their uid (aka NetID).
-
#given_name_safe ⇒ Object
Returns a display name that always has a value This is needed because we have records in the Users table that are created automatically in which the only value we have for sure its their uid (aka NetID).
- #moderator? ⇒ Boolean
- #pending_notifications_count ⇒ Object
- #safe_uid_check ⇒ Object
-
#submitter_groups ⇒ Object
Returns the list of groups where the user can submit datasets.
- #submitter_or_admin_groups ⇒ Object
-
#super_admin? ⇒ Boolean
Is this user a super_admin? super_admins automatically get admin status in every group, and they can make new groups.
-
#update_with_cas(access_token) ⇒ Object
Updates an existing User record with some information from CAS.
- #update_with_entra(access_token) ⇒ Object
Instance Attribute Details
#just_created ⇒ Object
Returns the value of attribute just_created.
23 24 25 |
# File 'app/models/user.rb', line 23 def just_created @just_created end |
Class Method Details
.all_uids_string ⇒ Object
Returns a string with the UID (netid) for all the users. We use this string to power the JavaScript @mention functionality when adding messages to works.
215 216 217 |
# File 'app/models/user.rb', line 215 def self.all_uids_string User.all.map { |user| '"' + user.uid + '"' }.join(", ") end |
.create_default_users ⇒ Object
Creates the default users as indicated in the super_admin config file and the default administrators and submitters for each group. It only creates missing records, i.e. if the records already exist it will not create a duplicate. It also does not remove already configured access to other groups.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'app/models/user.rb', line 188 def self.create_default_users update_super_admins Group.find_each do |group| Rails.logger.info "Setting up admins for group #{group.title}" group.default_admins_list.each do |uid| user = User.new_for_uid(uid) user.add_role :group_admin, group end Rails.logger.info "Setting up submitters for group #{group.title}" group.default_submitters_list.each do |uid| user = User.new_for_uid(uid) user.add_role :submitter, group end end end |
.create_users_from_csv(csv) ⇒ Object
rubocop:enable Metrics/MethodLength
174 175 176 177 178 179 180 181 |
# File 'app/models/user.rb', line 174 def self.create_users_from_csv(csv) users = [] CSV.foreach(csv, headers: true) do |row| next if row["Net ID"] == "N/A" users << new_from_csv_params(row.to_hash) end users end |
.email_from_access_token(access_token) ⇒ Object
85 86 87 88 89 90 91 92 93 |
# File 'app/models/user.rb', line 85 def self.email_from_access_token(access_token) if !access_token.extra.mail.nil? # For typical Princeton accounts the email comes on the `email` field access_token.extra.mail elsif User.looks_like_email_address?(access_token.extra.givenname) # For Guest Access Accounts (GAP) the email comes in the `givenname` access_token.extra.givenname end end |
.email_from_access_token_entra(access_token) ⇒ Object
95 96 97 98 99 100 101 102 103 |
# File 'app/models/user.rb', line 95 def self.email_from_access_token_entra(access_token) if !access_token.info.email.nil? # For Entra accounts the email comes on the `info.email` field access_token.info.email elsif User.looks_like_email_address?(access_token.extra.raw_info.preferred_username) # For Entra Guest Access Accounts (GAP) the email comes in the `info.given_name` access_token.extra.raw_info.preferred_username end end |
.from_cas(access_token) ⇒ Object
32 33 34 35 36 37 38 39 40 |
# File 'app/models/user.rb', line 32 def self.from_cas(access_token) user = User.find_by(uid: safe_uid(access_token.uid)) if user.nil? user = new_from_cas(access_token) elsif user.provider.blank? user.update_with_cas(access_token) end user end |
.from_entra(access_token) ⇒ Object
42 43 44 45 46 47 48 49 50 |
# File 'app/models/user.rb', line 42 def self.from_entra(access_token) user = User.find_by(email: access_token.info.email) # uid from entra is not the same as the netid, so we cannot use it to find the user. We need to find the user by email instead. if user.nil? user = new_from_entra(access_token) elsif user.provider.blank? user.update_with_entra(access_token) end user end |
.looks_like_email_address?(value) ⇒ Boolean
105 106 107 |
# File 'app/models/user.rb', line 105 def self.looks_like_email_address?(value) URI::MailTo::EMAIL_REGEXP.match?(value) end |
.new_for_uid(uid, default_group_id = nil) ⇒ Object
Creates a new user by uid. If the user already exists it returns the existing user.
133 134 135 136 137 138 139 140 141 |
# File 'app/models/user.rb', line 133 def self.new_for_uid(uid, default_group_id = nil) user = User.find_by(uid:) if user.nil? user = User.new(uid:, email: "#{uid}@princeton.edu") user.default_group_id = default_group_id user.save! end user end |
.new_from_cas(access_token) ⇒ Object
Create a new user with some basic information from CAS.
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'app/models/user.rb', line 53 def self.new_from_cas(access_token) user = User.new user.provider = access_token.provider user.uid = safe_uid(access_token.uid) # this is the netid user.email = User.email_from_access_token(access_token) user.given_name = access_token.extra.givenname || access_token.uid # Harriet user.family_name = access_token.extra.sn || access_token.uid # Tubman user.full_name = access_token.extra.displayname || access_token.uid # "Harriet Tubman" user.default_group_id = Group.default_for_department(access_token.extra.departmentnumber)&.id user.save! user end |
.new_from_csv_params(csv_params) ⇒ Object
rubocop:disable Metrics/MethodLength
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'app/models/user.rb', line 151 def self.new_from_csv_params(csv_params) email = "#{csv_params['Net ID']}@princeton.edu" uid = csv_params["Net ID"] given_name = csv_params["First Name"] family_name = csv_params["Last Name"] full_name = "#{given_name} #{family_name}" orcid = csv_params["ORCID ID"] user = User.where(email:).first_or_create params_hash = { email:, uid:, orcid:, full_name: (full_name if user.full_name.blank?), family_name: (family_name if user.family_name.blank?), given_name: (given_name if user.given_name.blank?) }.compact user.update(params_hash) Rails.logger.info "Successfully created or updated #{user.email}" user end |
.new_from_entra(access_token) ⇒ Object
Create a new user with some basic information from Entra.
67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'app/models/user.rb', line 67 def self.new_from_entra(access_token) user = User.new user.provider = access_token.provider user.uid = safe_uid(access_token.uid) # this is a long token string, not the netid. How do we handle this? user.email = User.email_from_access_token_entra(access_token) user.given_name = access_token.info.first_name || access_token.uid # Harriet user.family_name = access_token.info.last_name || access_token.uid # Tubman user.full_name = access_token.info.name || access_token.uid # "Harriet Tubman" # user.default_group_id = Group.default_for_department(access_token.extra.departmentnumber)&.id # Department number is not available in Entra, so we cannot set a default group based on that. user.save! user end |
.new_super_admin(uid) ⇒ Object
143 144 145 146 147 148 |
# File 'app/models/user.rb', line 143 def self.new_super_admin(uid) user = new_for_uid(uid) user.add_role(:super_admin) unless user.has_role?(:super_admin) user.add_role(:group_admin) unless user.has_role?(:group_admin) user end |
.safe_uid(uid) ⇒ Object
80 81 82 83 |
# File 'app/models/user.rb', line 80 def self.safe_uid(uid) return uid if uid.blank? uid.gsub(/[^(0-9a-zA-Z_\-)]/, "_") end |
.update_super_admins ⇒ Object
206 207 208 209 210 211 |
# File 'app/models/user.rb', line 206 def self.update_super_admins Rails.logger.info "Setting super administrators" Rails.configuration.super_admins.each do |uid| new_super_admin(uid) end end |
Instance Method Details
#admin_groups ⇒ Object
Returns the list of groups where the user is an administrator
279 280 281 282 283 284 285 |
# File 'app/models/user.rb', line 279 def admin_groups @admin_groups ||= if super_admin? Group.all.to_a else Group.with_role(:group_admin, self) end end |
#assign_default_role ⇒ Object
295 296 297 298 299 |
# File 'app/models/user.rb', line 295 def assign_default_role @just_created = true add_role(:submitter, default_group) unless has_role?(:submitter, default_group) default_group.(user: self) end |
#can_admin?(group) ⇒ Boolean
Returns true if the user can admin the group
264 265 266 267 |
# File 'app/models/user.rb', line 264 def can_admin?(group) return true if super_admin? has_role?(:group_admin, group) end |
#can_submit?(group) ⇒ Boolean
True if the user can submit datasets to the group
258 259 260 261 |
# File 'app/models/user.rb', line 258 def can_submit?(group) return true if super_admin? has_role?(:submitter, group) end |
#default_group ⇒ Object
Returns a reference to the user's default group.
249 250 251 252 253 254 255 |
# File 'app/models/user.rb', line 249 def default_group if default_group_id.nil? Group.default else Group.find(default_group_id) end end |
#email_messages_enabled? ⇒ Boolean
Returns true if the user has notification e-mails enabled
303 304 305 |
# File 'app/models/user.rb', line 303 def end |
#full_name_safe ⇒ Object
Returns a full name that always has a value This is needed because we have records in the Users table that are created automatically in which the only value we have for sure its their uid (aka NetID).
240 241 242 |
# File 'app/models/user.rb', line 240 def full_name_safe full_name&.strip.presence || uid end |
#given_name_safe ⇒ Object
Returns a display name that always has a value This is needed because we have records in the Users table that are created automatically in which the only value we have for sure its their uid (aka NetID).
233 234 235 |
# File 'app/models/user.rb', line 233 def given_name_safe given_name.presence || uid end |
#moderator? ⇒ Boolean
244 245 246 |
# File 'app/models/user.rb', line 244 def moderator? admin_groups.count > 0 end |
#pending_notifications_count ⇒ Object
291 292 293 |
# File 'app/models/user.rb', line 291 def pending_notifications_count WorkActivityNotification.where(user_id: id, read_at: nil).count end |
#safe_uid_check ⇒ Object
307 308 309 |
# File 'app/models/user.rb', line 307 def safe_uid_check self.uid = self.class.safe_uid(uid) end |
#submitter_groups ⇒ Object
Returns the list of groups where the user can submit datasets
270 271 272 273 274 275 276 |
# File 'app/models/user.rb', line 270 def submitter_groups @submitter_groups = if super_admin? Group.all.to_a else (Group.with_role(:submitter, self) + Group.with_role(:group_admin, self)).uniq end end |
#submitter_or_admin_groups ⇒ Object
287 288 289 |
# File 'app/models/user.rb', line 287 def submitter_or_admin_groups submitter_groups | admin_groups end |
#super_admin? ⇒ Boolean
Is this user a super_admin? super_admins automatically get admin status in every group, and they can make new groups.
223 224 225 226 227 228 |
# File 'app/models/user.rb', line 223 def super_admin? has_role? :super_admin rescue => ex Rails.logger.error("Unexpected error checking super_admin: #{ex}") false end |
#update_with_cas(access_token) ⇒ Object
Updates an existing User record with some information from CAS. This is useful for records created before the user ever logged in (e.g. to grant them permissions to groups).
112 113 114 115 116 117 118 119 120 |
# File 'app/models/user.rb', line 112 def update_with_cas(access_token) self.provider = access_token.provider self.email = User.email_from_access_token(access_token) self.given_name = access_token.extra.givenname || access_token.uid # Harriet self.family_name = access_token.extra.sn || access_token.uid # Tubman self.full_name = access_token.extra.displayname || access_token.uid # "Harriet Tubman" self.default_group_id ||= Group.default_for_department(access_token.extra.departmentnumber)&.id save! end |
#update_with_entra(access_token) ⇒ Object
122 123 124 125 126 127 128 129 130 |
# File 'app/models/user.rb', line 122 def update_with_entra(access_token) self.provider = access_token.info.provider self.email = User.email_from_access_token_entra(access_token) self.given_name = access_token.info.first_name || access_token.uid # Harriet self.family_name = access_token.info.last_name || access_token.uid # Tubman self.full_name = access_token.info.name || access_token.uid # "Harriet Tubman" # self.default_group_id ||= Group.default_for_department(access_token.info.department_number)&.id save! end |