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
- .uid_from_access_token(access_token) ⇒ 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.
227 228 229 |
# File 'app/models/user.rb', line 227 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.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'app/models/user.rb', line 200 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
186 187 188 189 190 191 192 193 |
# File 'app/models/user.rb', line 186 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
97 98 99 100 101 102 103 104 105 |
# File 'app/models/user.rb', line 97 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
107 108 109 110 111 112 113 114 115 |
# File 'app/models/user.rb', line 107 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 51 |
# File 'app/models/user.rb', line 42 def self.from_entra(access_token) uid = uid_from_access_token(access_token) user = User.find_by(uid:) 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
117 118 119 |
# File 'app/models/user.rb', line 117 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.
145 146 147 148 149 150 151 152 153 |
# File 'app/models/user.rb', line 145 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.
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'app/models/user.rb', line 54 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
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'app/models/user.rb', line 163 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.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'app/models/user.rb', line 68 def self.new_from_entra(access_token) user = User.new email = email_from_access_token_entra(access_token) uid = uid_from_access_token(access_token) user.provider = access_token.provider user.uid = uid user.email = email user.given_name = access_token.info.first_name || uid # Harriet user.family_name = access_token.info.last_name || uid # Tubman user.full_name = access_token.info.name || 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
155 156 157 158 159 160 |
# File 'app/models/user.rb', line 155 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
92 93 94 95 |
# File 'app/models/user.rb', line 92 def self.safe_uid(uid) return uid if uid.blank? uid.gsub(/[^(0-9a-zA-Z_\-)]/, "_") end |
.uid_from_access_token(access_token) ⇒ Object
83 84 85 86 87 88 89 90 |
# File 'app/models/user.rb', line 83 def self.uid_from_access_token(access_token) unique_name = access_token.extra.raw_info.unique_name if unique_name.end_with?("@princeton.edu") && unique_name.split("@princeton.edu").first.present? safe_uid(unique_name.split("@princeton.edu").first) else safe_uid(unique_name) end end |
.update_super_admins ⇒ Object
218 219 220 221 222 223 |
# File 'app/models/user.rb', line 218 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
291 292 293 294 295 296 297 |
# File 'app/models/user.rb', line 291 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
307 308 309 310 311 |
# File 'app/models/user.rb', line 307 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
276 277 278 279 |
# File 'app/models/user.rb', line 276 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
270 271 272 273 |
# File 'app/models/user.rb', line 270 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.
261 262 263 264 265 266 267 |
# File 'app/models/user.rb', line 261 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
315 316 317 |
# File 'app/models/user.rb', line 315 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).
252 253 254 |
# File 'app/models/user.rb', line 252 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).
245 246 247 |
# File 'app/models/user.rb', line 245 def given_name_safe given_name.presence || uid end |
#moderator? ⇒ Boolean
256 257 258 |
# File 'app/models/user.rb', line 256 def moderator? admin_groups.count > 0 end |
#pending_notifications_count ⇒ Object
303 304 305 |
# File 'app/models/user.rb', line 303 def pending_notifications_count WorkActivityNotification.where(user_id: id, read_at: nil).count end |
#safe_uid_check ⇒ Object
319 320 321 |
# File 'app/models/user.rb', line 319 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
282 283 284 285 286 287 288 |
# File 'app/models/user.rb', line 282 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
299 300 301 |
# File 'app/models/user.rb', line 299 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.
235 236 237 238 239 240 |
# File 'app/models/user.rb', line 235 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).
124 125 126 127 128 129 130 131 132 |
# File 'app/models/user.rb', line 124 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
134 135 136 137 138 139 140 141 142 |
# File 'app/models/user.rb', line 134 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 |