Class: Fortifier::AuthUser
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Fortifier::AuthUser
- Defined in:
- app/models/fortifier/auth_user.rb
Constant Summary collapse
- ABAQIS =
1
- EMP_SAT =
2
Class Method Summary collapse
- .authenticate_batch_sso(account_uuid, token) ⇒ Object
- .authenticate_on_demand_sso(account_uuid, token) ⇒ Object
- .paged_and_sorted_search(params) ⇒ Object
Instance Method Summary collapse
- #authenticated?(secret_string) ⇒ Boolean
- #blocked? ⇒ Boolean
- #current_secret ⇒ Object
- #current_secret_non_token ⇒ Object
- #disable! ⇒ Object
- #disabled? ⇒ Boolean
- #email_is_correct_format ⇒ Object
- #email_is_correct_length ⇒ Object
- #email_is_unique ⇒ Object
- #login_is_correct_length ⇒ Object
-
#login_is_present ⇒ Object
NOTE: These custom validations are used so that symbols/codes can be returned to applications, rather than explicit text.
- #login_is_unique ⇒ Object
- #matching_whitelist_ip?(ip) ⇒ Boolean
- #name_is_correct_format ⇒ Object
- #name_is_correct_length ⇒ Object
- #note_is_correct_length ⇒ Object
- #public_attribute_hash ⇒ Object
- #secrets_match?(secret_string) ⇒ Boolean
- #successful_log_in? ⇒ Boolean
Class Method Details
.authenticate_batch_sso(account_uuid, token) ⇒ Object
114 115 116 117 118 119 120 121 122 123 |
# File 'app/models/fortifier/auth_user.rb', line 114 def self.authenticate_batch_sso(account_uuid, token) return nil if token.blank? AuthUser. joins(:secrets). where("find_in_set(? , account_uuids_csv) AND (expired IS NULL OR expired = false) AND enc_type = '#{Secret::SSO_TOKEN}' AND secret_value = ?", account_uuid, token). first end |
.authenticate_on_demand_sso(account_uuid, token) ⇒ Object
125 126 127 128 129 130 131 132 133 134 |
# File 'app/models/fortifier/auth_user.rb', line 125 def self.authenticate_on_demand_sso(account_uuid, token) return nil if token.blank? AuthUser. joins(:secrets). where("find_in_set(? , account_uuids_csv) AND (expired IS NULL OR expired = false) AND enc_type = '#{Secret::SSO_TOKEN}' AND secret_value = ?", account_uuid, token). first end |
.paged_and_sorted_search(params) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'app/models/fortifier/auth_user.rb', line 178 def self.paged_and_sorted_search(params) search = params[:search] sort_col = params[:sortcol] || 'name' sort_dir = params[:sortdir] || 'asc' per_page = (params[:per_page].blank? || params[:per_page]<25) ? 25 : params[:per_page] page = params[:page] || 1 app_uuid = params[:app_uuid] account_uuid = params[:account_uuid] search_keywords = params[:search_keywords] if search.blank? user_search_query = '' else user_search_query = [:login, :email, :name, :note].map{|f| "#{f} LIKE '%#{search}%'"}.join(" OR ") end # aggregate_query is conditional b/c account_uuid isn't always provided (such as the Users page for providigm users in abaqis) app_uuids_query = "app_uuids_csv = '#{app_uuid}'" account_uuids_query = account_uuid ? " AND account_uuids_csv = '#{account_uuid}'" : "" search_keywords_query = search_keywords ? " AND FIND_IN_SET ('#{search_keywords}', search_keywords_csv)" : '' undeleted_auth_user_clause = " AND deleted = 0 " aggregate_query = app_uuids_query + account_uuids_query + search_keywords_query + undeleted_auth_user_clause # b/c there's no 'enabled' field on auth user and abaqis allows this sorting (providigm/users in abaqis) if sort_col=='enabled' Fortifier::AuthUser.where(aggregate_query) .where(user_search_query) .order("app_uuids_csv #{sort_dir}, account_uuids_csv #{sort_dir}") .paginate(:page=>page, :per_page=>per_page) elsif sort_col=='last_login_at' # In other words, pull all users associated with the app in question (if available), # joined with their most recent AuthLog, # sort by the AuthLog created_at date (according to user preference), # then paginate with WillPaginate. Capisce? Fortifier::AuthUser.find_by_sql("SELECT * FROM fortifier_auth_users fau LEFT OUTER JOIN ( select auth_user_id, max(created_at) AS last_login_at FROM fortifier_auth_logs fal GROUP BY auth_user_id) AS last_seen ON fau.id = last_seen.auth_user_id #{'WHERE ' + aggregate_query} #{'AND ' + user_search_query if user_search_query.present?} ORDER BY last_login_at #{sort_dir}") .paginate(:page=>page, :per_page=>per_page) else Fortifier::AuthUser.where(aggregate_query) .where(user_search_query) .order("#{sort_col} #{sort_dir}") .paginate(:page=>page, :per_page=>per_page) end end |
Instance Method Details
#authenticated?(secret_string) ⇒ Boolean
101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'app/models/fortifier/auth_user.rb', line 101 def authenticated?(secret_string) # TODO: (DK) do not increase consecutive_failed_logins if user is attempting a pw change # move consecutive_failed_logins updates to a different method so this method # doesn't do multiple things (code smell) if self.secrets_match?(secret_string) self.update_column(:consecutive_failed_logins, 0) unless self.blocked? true else self.update_column(:consecutive_failed_logins, self.consecutive_failed_logins + 1) false end end |
#blocked? ⇒ Boolean
136 137 138 |
# File 'app/models/fortifier/auth_user.rb', line 136 def blocked? self.consecutive_failed_logins > 5 end |
#current_secret ⇒ Object
83 84 85 |
# File 'app/models/fortifier/auth_user.rb', line 83 def current_secret self.secrets.order("created_at, id asc").last end |
#current_secret_non_token ⇒ Object
87 88 89 |
# File 'app/models/fortifier/auth_user.rb', line 87 def current_secret_non_token self.secrets.where(enc_type: (Secret::BCRYPT || Secret::SHA)).order("created_at, id asc").last end |
#disable! ⇒ Object
140 141 142 143 |
# File 'app/models/fortifier/auth_user.rb', line 140 def disable! self.update_column(:app_uuids_csv, nil) self.update_column(:account_uuids_csv, nil) end |
#disabled? ⇒ Boolean
145 146 147 |
# File 'app/models/fortifier/auth_user.rb', line 145 def disabled? self.app_uuids.blank? && self.account_uuids.blank? end |
#email_is_correct_format ⇒ Object
61 62 63 64 65 |
# File 'app/models/fortifier/auth_user.rb', line 61 def email_is_correct_format return if (email.blank?) return if (Fortifier::Authentication::EMAIL_REGEX.match email).present? errors[:base] << :email_format_incorrect end |
#email_is_correct_length ⇒ Object
49 50 51 52 53 |
# File 'app/models/fortifier/auth_user.rb', line 49 def email_is_correct_length return if (email.blank?) return if (email.length >= 6 && email.length <= 100) errors[:base] << :email_length_incorrect end |
#email_is_unique ⇒ Object
55 56 57 58 59 |
# File 'app/models/fortifier/auth_user.rb', line 55 def email_is_unique return if (email.blank?) return if unique?(:email, email) errors[:base] << :email_not_unique end |
#login_is_correct_length ⇒ Object
36 37 38 39 40 |
# File 'app/models/fortifier/auth_user.rb', line 36 def login_is_correct_length return if login.blank? return if (login.length >= 3 && login.length <= 60) unless login.blank? errors[:base] << :login_length_incorrect end |
#login_is_present ⇒ Object
NOTE: These custom validations are used so that symbols/codes can be returned to applications, rather than explicit text. Fortifier provides the symbols and the apps are responsible for handling error messaging.
31 32 33 34 |
# File 'app/models/fortifier/auth_user.rb', line 31 def login_is_present return if login.present? errors[:base] << :login_blank end |
#login_is_unique ⇒ Object
42 43 44 45 46 47 |
# File 'app/models/fortifier/auth_user.rb', line 42 def login_is_unique return if login.blank? return if unique?(:login, login) errors[:base] << :login_not_unique end |
#matching_whitelist_ip?(ip) ⇒ Boolean
156 157 158 159 160 161 |
# File 'app/models/fortifier/auth_user.rb', line 156 def matching_whitelist_ip?(ip) return false if ip.blank? au_auth_rule_ids = AuthUsersAuthRule.where(auth_user_id: self.id).pluck(:auth_rule_id) auth_rule_ips = au_auth_rule_ids.map {|auid| AuthRule.find(auid).rule_value} auth_rule_ips.flatten.include?(ip) end |
#name_is_correct_format ⇒ Object
67 68 69 70 71 |
# File 'app/models/fortifier/auth_user.rb', line 67 def name_is_correct_format return if (name.blank?) return if (Fortifier::Authentication::NAME_REGEX.match name).present? errors[:base] << :name_format_incorrect end |
#name_is_correct_length ⇒ Object
73 74 75 76 |
# File 'app/models/fortifier/auth_user.rb', line 73 def name_is_correct_length return if (name.blank? || name.length <= 100) errors[:base] << :name_length_incorrect end |
#note_is_correct_length ⇒ Object
78 79 80 81 |
# File 'app/models/fortifier/auth_user.rb', line 78 def note_is_correct_length return if (note.blank? || note.length <= 255) errors[:base] << :note_length_incorrect end |
#public_attribute_hash ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'app/models/fortifier/auth_user.rb', line 163 def public_attribute_hash auth_log = self.auth_logs.last { uuid: self.uuid, email: self.email, login: self.login, name: self.name, note: self.note, disabled: self.disabled?, deleted: self.deleted?, blocked: self.blocked?, last_auth_log: ({user_agent: auth_log.user_agent, status: auth_log.status, created_at: auth_log.created_at.to_time} if auth_log) } end |
#secrets_match?(secret_string) ⇒ Boolean
91 92 93 94 95 96 97 98 99 |
# File 'app/models/fortifier/auth_user.rb', line 91 def secrets_match?(secret_string) current_secret_model = current_secret_non_token return false if current_secret_model.blank? auth_result = current_secret_model.matches?(secret_string) current_secret_model.update_encryption_method(secret_string) if (auth_result && current_secret_model.enc_type == "SHA") return auth_result end |
#successful_log_in? ⇒ Boolean
149 150 151 152 153 154 |
# File 'app/models/fortifier/auth_user.rb', line 149 def successful_log_in? # TODO: clarify this so there's no confusion (user can be logged out with a count of 0, # so technically they wouldn't be succesfully logged in, even though this method would # say otherwise). self.consecutive_failed_logins == 0 end |