Module: UserSecurity

Extended by:
ActiveSupport::Concern
Included in:
Lesli::User
Defined in:
app/models/concerns/user_security.rb

Overview

User extension methods Custom methods that belongs to a instance user

Instance Method Summary collapse

Instance Method Details

#abilities_by_controllerHash

Returns:

  • (Hash)


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'app/models/concerns/user_security.rb', line 91

def abilities_by_controller

    # Abilities hash where we will save all the privileges the user has to
    abilities = {}

    # We check all the privileges the user has in the cache table according to his roles
    # and create a key per controller (with the full controller name) that contains an array of all the 
    # methods/actions with permission
    # self.privileges.all.each do |privilege|
    #     abilities[privilege.controller] = [] if abilities[privilege.controller].nil?
    #     abilities[privilege.controller] << privilege.action
    # end

    abilities

end

#can_work_with_role?(role) ⇒ Boolean

Returns Boolean.

Returns:

  • (Boolean)

    Boolean



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'app/models/concerns/user_security.rb', line 111

def can_work_with_role?(role)

    # get the role if only id is given
    role = self..roles.find_by(:id => role) unless role.class.name == "Lesli::Role"

    # false if role not found
    return false if role.blank?

    # not valid role without object levelpermission defined
    return false if role.object_level_permission.blank?

    # owner role can work with all the roles
    return true if !self.roles.find_by(name: 'owner').blank?

    # get the max object level permission from the roles the user has assigned
    user_role_level_max = self.roles.map(&:object_level_permission).max()

    # check if user can work with the object level permission of the role is trying to modify
    # Note: user only can assigned an object level permission below the max of his own roles
    # Current user cannot assign role if
    #       role to assign has greater object level permission than the greater role assigned to the current user
    #       role to assign is the same of the greater role assigned to the current user
    #       current user is not sysadmin or owner
    return false if role.object_level_permission >= user_role_level_max

    # user can work with this role :)
    return true

end

#confirm_telephone_numberObject

Returns String.

Returns:

  • String



270
271
272
273
274
275
# File 'app/models/concerns/user_security.rb', line 270

def confirm_telephone_number
    self.telephone_confirmation_token   = nil
    self.telephone_confirmation_sent_at = nil
    self.telephone_confirmed_at = Time.now.utc
    save(validate: false)
end

#generate_password_reset_tokenObject

Returns String.

Returns:

  • String



237
238
239
240
241
242
243
244
# File 'app/models/concerns/user_security.rb', line 237

def generate_password_reset_token
    raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)

    self.reset_password_token   = enc
    self.reset_password_sent_at = Time.now.utc
    save(validate: false)
    raw
end

#generate_telephone_token(length = 4) ⇒ Object

Returns String.

Returns:

  • String



256
257
258
259
260
261
262
263
264
265
# File 'app/models/concerns/user_security.rb', line 256

def generate_telephone_token(length=4)

    raw, enc = Devise.token_generator.create(self.class, :telephone_confirmation_token, type:'number', length:length)

    self.telephone_confirmation_token   = enc
    self.telephone_confirmation_sent_at = Time.now.utc
    self.telephone_confirmed_at = nil
    save(validate: false)
    raw
end

#has_expired_password?void

This method returns an undefined value.



229
230
231
232
# File 'app/models/concerns/user_security.rb', line 229

def has_expired_password?
    return false if self.password_expiration_at.blank?
    return Time.current > self.password_expiration_at
end

#has_privileges_for?(controller, action) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
83
# File 'app/models/concerns/user_security.rb', line 74

def has_privileges_for?(controller, action)
    begin
        return !self.privileges
        .where("lesli_role_privileges.controller = ?", controller)
        .where("lesli_role_privileges.action = ?", action)
        .first.blank?            
    rescue => exception
        return false
    end
end

#has_role_limited_to_path?nil, string

if user has a role limited to a defined path if user has a high privilege role that overrides any other role configuration

Returns:

  • (nil, string)


178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'app/models/concerns/user_security.rb', line 178

def has_role_limited_to_path?()

    # get the roles ordering in descendant mode because we must
    # keep the path of the hightest object level permission role.
    # Example: we should use the path of the admin role if user has
    # admin & employee roles, also order by default_path, so we get first 
    # the roles with path in case the user has roles with the same object level permission
    role = self.roles.order(object_level_permission: :desc).order(:path_default)

    # get the first role found, due previously we sort in a descendant order
    # the first role is going to be the one with highest object level permission
    # this is going to return nil if no role was found
    role = role.first

    # return the path of the role if is limited to a that specific path
    return role.path_default if role.path_limited == true 

    # return nil if role has no limits
    return nil
end

#has_role_with_default_path?nil, string

if user has a role with “default path” to use as home to redirect after login IMPORTANT: This home path is used only the send the user after login, the user

and the role are not limited by this configuration

Returns:

  • (nil, string)


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'app/models/concerns/user_security.rb', line 147

def has_role_with_default_path?()

    # get the roles that contains a path
    role = self.roles.where.not(path_default: [nil, ""])

    # here we must order the results descendant because we must
    # keep the path of the hightest object level permission role.
    # Example: we should use the path of the admin role if user has
    # admin & employee roles, also order by default_path, so we get first 
    # the roles with path in case the user has roles with the same object level permission
    role = role.order(object_level_permission: :desc).order(:path_default)

    # get the first role found, due previously we sort in a descendant order
    # the first role is going to be the one with highest object level permission
    # this is going to return nil if no role was found
    default_path = role.first&.path_default  || "/"

    # if first loggin for account owner send him to the onboarding page
    if self..onboarding? && self.has_roles?("owner")
        default_path = "/onboarding"
    end

    default_path

end

#has_roles?(*roles) ⇒ void

This method returns an undefined value.

check role of the user

Parameters:

  • *roles (String)

    One or more roles to be checked



59
60
61
# File 'app/models/concerns/user_security.rb', line 59

def has_roles? *roles
    !roles.intersection(self.roles.map{ |r| r[:name] }).empty?
end

#max_object_level_permissionObject



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'app/models/concerns/user_security.rb', line 40

def max_object_level_permission

    # get the max object level permission from roles assigned to the user
    level = self.roles.maximum(:object_level_permission)

    # if user has no roles assigned, we return the lowest role available 
    # NOTE: This should not be possible due the user needs a role to login
    unless level 
        return (self..roles.minimum(:object_level_permission))
    end

    # return the level found
    level
end

#password_resetvoid

TODO:

validate object level permission

This method returns an undefined value.



220
221
222
223
224
# File 'app/models/concerns/user_security.rb', line 220

def password_reset
    pass = SecureRandom.hex(10)
    self.update(password: pass)
    pass
end

#revoke_accessvoid

This method returns an undefined value.

Examples:

old_user = User.last
old_user.revoke_access


205
206
207
# File 'app/models/concerns/user_security.rb', line 205

def revoke_access
    self.update(active: false)
end

#set_password_as_expiredvoid

This method returns an undefined value.



212
213
214
# File 'app/models/concerns/user_security.rb', line 212

def set_password_as_expired
    self.update(password_expiration_at: Time.current)
end

#telephone_confirmed?Boolean

Returns:

  • (Boolean)


249
250
251
# File 'app/models/concerns/user_security.rb', line 249

def telephone_confirmed?
    !!self.telephone_confirmed_at
end