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.



189
190
191
192
193
194
195
# File 'app/models/user.rb', line 189

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



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

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


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

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.



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

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)


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

def developer?
  return true if developer
  super
end

#display_name_only_safeString

Return the display name only (no uid) if it exists, otherwise return the uid

Returns:

  • (String)


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

def display_name_only_safe
  return uid if given_name.blank? && family_name.blank?
  [given_name, family_name].compact.join(" ")
end

#display_name_safeString

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

Returns:

  • (String)


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

def display_name_safe
  return uid if given_name.blank? && family_name.blank?
  [given_name, family_name, "(#{uid})"].compact.join(" ")
end

#eligible_data_user?Boolean

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

Returns:

  • (Boolean)


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

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)


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

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)


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

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)


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

def eligible_sysadmin?
  (!Rails.env.production? && (developer || sysadmin)) || (Rails.env.production? && sysadmin)
end

#eligible_to_create_new?Boolean

Returns:

  • (Boolean)


138
139
140
141
142
# File 'app/models/user.rb', line 138

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



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

def latest_downloads(limit: 10)
  @latest_downloads ||= begin
                          downloads = UserRequest.where(user_id: id).where(["completion_time > ?", 7.days.ago]).order(created_at: "DESC").limit(limit)
                          downloads.map{|download| UserRequestPresenter.new(download)}
                        end
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