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.



15
16
17
# File 'app/models/user.rb', line 15

def mediaflux_session
  @mediaflux_session
end

Class Method Details

.from_cas(access_token) ⇒ Object



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

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

.manager_usersObject

Users that can be data managers



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

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

.mediaflux_roles(user:) ⇒ Object

Returns the roles in Mediaflux for the user in the session. This method is meant to be used only for the current logged in user since the roles depend on the Mediaflux session.



180
181
182
183
184
185
186
# File 'app/models/user.rb', line 180

def self.mediaflux_roles(user:)
  raise "User.mediaflux_roles called with for a user without a Mediaflux session" if user.mediaflux_session.nil?

  request = Mediaflux::ActorSelfDescribeRequest.new(session_token: user.mediaflux_session)
  request.resolve
  request.roles
end

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



157
158
159
# File 'app/models/user.rb', line 157

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


151
152
153
154
155
# File 'app/models/user.rb', line 151

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



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

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

.update_user_roles(user:) ⇒ Object

Updates the user’s roles (sys admin, developer) depending on the information on Mediaflux. This method is meant to be used only for the current logged in user since the roles depend on the Mediaflux session.



168
169
170
171
172
173
174
175
176
# File 'app/models/user.rb', line 168

def self.update_user_roles(user:)
  raise "User.update_user_roles called with for a user without a Mediaflux session" if user.mediaflux_session.nil?

  mediaflux_roles = mediaflux_roles(user:)
  update_developer_status(user:, mediaflux_roles:)
  update_sysadmin_status(user:, mediaflux_roles:)
rescue => ex
  Rails.logger.error("Error updating roles for user (id: #{user.id}) status, error: #{ex.message}")
end

Instance Method Details

#clear_mediaflux_session(session) ⇒ Object



44
45
46
47
48
# File 'app/models/user.rb', line 44

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

#developer?Boolean

Returns:

  • (Boolean)


114
115
116
117
# File 'app/models/user.rb', line 114

def developer?
  return true if developer
  super
end

#display_name_safeString

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

Returns:

  • (String)


94
95
96
97
98
# File 'app/models/user.rb', line 94

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)


121
122
123
124
# File 'app/models/user.rb', line 121

def eligible_data_user?
  return true if developer
  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)


109
110
111
112
# File 'app/models/user.rb', line 109

def eligible_manager?
  return true if developer
  super
end

#eligible_sponsor?Boolean

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

Returns:

  • (Boolean)


102
103
104
105
# File 'app/models/user.rb', line 102

def eligible_sponsor?
  return true if developer
  super
end

#eligible_sysadmin?Boolean

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

Returns:

  • (Boolean)


128
129
130
# File 'app/models/user.rb', line 128

def eligible_sysadmin?
  return true if developer || sysadmin
end

#eligible_to_create_new?Boolean

Returns:

  • (Boolean)


132
133
134
135
136
# File 'app/models/user.rb', line 132

def eligible_to_create_new?
  return true if eligible_sysadmin?

  !Rails.env.production? && (eligible_sponsor? && trainer?)
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.



86
87
88
89
90
# File 'app/models/user.rb', line 86

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



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

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

#mediaflux_from_session(session) ⇒ Object



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

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

#mediaflux_login(token, session) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/models/user.rb', line 61

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}"

  User.update_user_roles(user: self)
end

#terminate_mediaflux_sessionObject



76
77
78
79
80
81
82
# File 'app/models/user.rb', line 76

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