Class: User

Inherits:
ApplicationRecord show all
Defined in:
app/models/user.rb

Direct Known Subclasses

ReadOnlyUser

Constant Summary collapse

USER_REGISTRATION_LIST =
Rails.root.join("data", "user_registration_list_#{Rails.env}.csv")

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#mediaflux_sessionObject

Returns the value of attribute mediaflux_session.



13
14
15
# File 'app/models/user.rb', line 13

def mediaflux_session
  @mediaflux_session
end

Class Method Details

.csv_dataCSV::Table

Parse the USER_REGISTRATION_LIST csv

Returns:

  • (CSV::Table)


125
126
127
# File 'app/models/user.rb', line 125

def self.csv_data
  CSV.parse(File.read(USER_REGISTRATION_LIST), headers: true)
end

.from_cas(access_token) ⇒ Object



15
16
17
18
19
20
21
22
# File 'app/models/user.rb', line 15

def self.from_cas(access_token)
  user = User.find_by(provider: access_token.provider, uid: access_token.uid)
  if user.present? && user.given_name.nil? # fix any users that do not have the name information loaded
    user.initialize_name_values(access_token.extra)
    user.save
  end
  user
end

.load_registration_listObject

Load the user registration list from the CSV file. Select the file that matches the rails environment.



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'app/models/user.rb', line 131

def self.load_registration_list
  User.csv_data.each do |line|
    user = User.find_by(uid: line["uid"]) || User.new
    user.uid = line["uid"]
    user.family_name = line["family_name"]
    user.display_name = line["display_name"]
    user.email = user.uid + "@princeton.edu"
    # If we don't say that this is a cas user, they won't be able to log in with CAS
    user.provider = "cas"
    user.eligible_sponsor = line["eligible_sponsor"] == "TRUE"
    user.eligible_manager = line["eligible_manager"] == "TRUE"
    user.superuser = line["superuser"] == "TRUE"
    user.sysadmin = line["sysadmin"] == "TRUE"
    user.trainer = line["tester_trainer"] == "TRUE"
    user.save
  end
end

.manager_usersObject

Users that can be data managers



34
35
36
37
38
39
40
# File 'app/models/user.rb', line 34

def self.manager_users
  if Rails.env.development? || Rails.env.staging?
    User.where(eligible_manager: true).or(User.where(superuser: true))
  else
    User.where(eligible_manager: true)
  end
end

.serialize_from_session(key, _salt, _opts = {}) ⇒ Object



168
169
170
# File 'app/models/user.rb', line 168

def self.serialize_from_session(key, _salt, _opts = {})
  User.where(uid: key)&.first
end

.serialize_into_session(record) ⇒ Object

Methods serialize_into_session() and serialize_from_session() are called by Warden/Devise to calculate what information will be stored in the session and to serialize an object back from the session.

By default Warden/Devise store the database ID of the record (e.g. User.id) but this causes problems if we repopulate our User table and the IDs change. The implementation provided below uses the User.uid field (which is unique, does not change, and it’s required) as the value to store in the session to prevent this issue.

References:

https://stackoverflow.com/questions/23597718/what-is-the-warden-data-in-a-rails-devise-session-composed-of/23683925#23683925
https://web.archive.org/web/20211028103224/https://tadas-s.github.io/ruby-on-rails/2020/08/02/devise-serialize-into-session-trick/
https://github.com/wardencommunity/warden/wiki/Setup


162
163
164
165
166
# File 'app/models/user.rb', line 162

def self.serialize_into_session(record)
  # The return value _must_ have at least two elements since the serialize_from_session() requires
  # two arguments (see below)
  [record.uid, ""]
end

Users that can be project sponsors



25
26
27
28
29
30
31
# File 'app/models/user.rb', line 25

def self.sponsor_users
  if Rails.env.development? || Rails.env.staging?
    User.where(eligible_sponsor: true).or(User.where(superuser: true))
  else
    User.where(eligible_sponsor: true)
  end
end

Instance Method Details

#clear_mediaflux_session(session) ⇒ Object



42
43
44
45
46
# File 'app/models/user.rb', line 42

def clear_mediaflux_session(session)
  Rails.logger.debug("!!!!!!! Clearing Mediaflux session !!!!!!!!")
  @mediaflux_session = nil
  session[:mediaflux_session] = nil
end

#display_name_safeString

Return the display name if it exists, otherwise return the uid

Returns:

  • (String)


90
91
92
93
94
# File 'app/models/user.rb', line 90

def display_name_safe
  return uid if display_name.blank?

  display_name
end

#eligible_data_user?Boolean

Is this user eligible to be a data user in this environment?

Returns:

  • (Boolean)


112
113
114
115
# File 'app/models/user.rb', line 112

def eligible_data_user?
  return true if superuser
  return true if !eligible_sponsor? && !eligible_manager
end

#eligible_manager?Boolean

Is this user eligible to be a data manger in this environment?

Returns:

  • (Boolean)


105
106
107
108
# File 'app/models/user.rb', line 105

def eligible_manager?
  return true if superuser
  super
end

#eligible_sponsor?Boolean

Is this user eligible to be a data sponsor in this environment?

Returns:

  • (Boolean)


98
99
100
101
# File 'app/models/user.rb', line 98

def eligible_sponsor?
  return true if superuser
  super
end

#eligible_sysadmin?Boolean

Is this user eligible to be a sysadmin in this environment?

Returns:

  • (Boolean)


119
120
121
# File 'app/models/user.rb', line 119

def eligible_sysadmin?
  return true if superuser || sysadmin
end

#initialize_name_values(extra_cas_info) ⇒ Object

Initialize the name values from the CAS information. Our name fields do not match their name fields, so we need to translate.



82
83
84
85
86
# File 'app/models/user.rb', line 82

def initialize_name_values(extra_cas_info)
  self.given_name = extra_cas_info.givenname
  self.family_name =  extra_cas_info.sn
  self.display_name = extra_cas_info.pudisplayname
end

#latest_downloads(limit: 10) ⇒ Object

Fetches the most recent download jobs for the user



173
174
175
# File 'app/models/user.rb', line 173

def latest_downloads(limit: 10)
  @latest_downloads ||= UserRequest.where(user_id: id).where(["completion_time > ?", 7.days.ago]).order(created_at: "DESC").limit(limit)
end

#medaiflux_login(token, session) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
# File 'app/models/user.rb', line 59

def (token, session)
  logger.debug("mediaflux session created for #{uid}")
  logon_request = Mediaflux::LogonRequest.new(identity_token: token, token_type: "cas")
  if logon_request.error?
    raise "Invalid Logon #{logon_request.response_error}"
  end
  @mediaflux_session = logon_request.session_token
  @active_web_user = true
  session[:mediaflux_session] = @mediaflux_session
  session[:active_web_user] = @active_web_user
  logger.debug "Login Session #{session[:mediaflux_session]} cas: #{session[:active_web_user]}  user: #{uid}"
end

#mediaflux_from_session(session) ⇒ Object



48
49
50
51
52
53
54
55
56
57
# File 'app/models/user.rb', line 48

def mediaflux_from_session(session)
  logger.debug "Session Get #{session[:mediaflux_session]} cas: #{session[:active_web_user]}  user: #{uid}"
  if session[:mediaflux_session].blank?
    logger.debug("!!!! Creating a new session !!! #{uid}")
    session[:mediaflux_session] = SystemUser.mediaflux_session
    session[:active_web_user] = false
  end
  @active_web_user = session[:active_web_user]
  @mediaflux_session = session[:mediaflux_session]
end

#terminate_mediaflux_sessionObject



72
73
74
75
76
77
78
# File 'app/models/user.rb', line 72

def terminate_mediaflux_session
  return if @mediaflux_session.nil? # nothing to terminate
  logger.debug "!!!! Terminating mediaflux session"

  Mediaflux::LogoutRequest.new(session_token: @mediaflux_session).response_body
  @mediaflux_session = nil
end