Module: Lesli::UserSecurity

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

Instance Method Summary collapse

Instance Method Details

#abilities_by_controllerObject

Return a hash that contains all the abilities grouped by controller and define every action privilege. It also evaluate if the user has the ability no matter if is given to the user by role or by itself.



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'app/models/concerns/lesli/user_security.rb', line 204

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_id) ⇒ Boolean

Check if user has enough privilege to work with the given role

Returns:

  • (Boolean)


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'app/models/concerns/lesli/user_security.rb', line 66

def can_work_with_role?(role_id)

    # get the role if only id is given
    role = self..roles.find_by(:id => role_id)

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

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

    # get the max level permission from the roles the user has assigned
    user_role_max_level_permission = self.roles.map(&:level_permission).max()

    # check if user can work with the level permission of the role is trying to modify
    # Note: user only can assigned an level permission below the max of his own roles
    # Current user cannot assign role if role to assign is the same of the greater role 
    # assigned to the current user
    user_role_max_level_permission >= role.level_permission
end

#confirm_telephone_numberObject

Mark telephone number as valid and confirmed



193
194
195
196
197
198
# File 'app/models/concerns/lesli/user_security.rb', line 193

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

Change user password forcing user to reset the password



166
167
168
169
170
171
172
173
174
# File 'app/models/concerns/lesli/user_security.rb', line 166

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

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

#generate_telephone_token(length = 4) ⇒ Object

Generate a token to validate telephone number



177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'app/models/concerns/lesli/user_security.rb', line 177

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?Boolean

Returns:

  • (Boolean)


155
156
157
158
# File 'app/models/concerns/lesli/user_security.rb', line 155

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

check the privilege cache to check if user is able to perform a specific action in a specific controller

Returns:

  • (Boolean)


53
54
55
56
57
58
59
60
61
62
63
# File 'app/models/concerns/lesli/user_security.rb', line 53

def has_privileges_for?(controller, action)
    begin
        return self.privileges.where(
            controller: controller,
            action: action,
            active: true
        ).exists?
    rescue => exception
        return false
    end
end

#has_role_limited_to_path?Boolean

Checks configuration of all the roles assigned to the user if user has a role limited to a defined path if user has a high privilege role that overrides any other role configuration

Returns:

  • (Boolean)


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'app/models/concerns/lesli/user_security.rb', line 119

def has_role_limited_to_path?()

    # get the roles ordering in descendant mode because we must
    # keep the path of the hightest 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 level permission
    role = self.roles.order(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 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?Boolean

Checks configuration of all the roles assigned to the user 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:

  • (Boolean)


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'app/models/concerns/lesli/user_security.rb', line 91

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 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 level permission
    role = role.order(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 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) ⇒ Boolean

check if user has roles with specific names

Returns:

  • (Boolean)


47
48
49
# File 'app/models/concerns/lesli/user_security.rb', line 47

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

#has_telephone_confirmed?Boolean

Check if user has a confirmed telephone number

Returns:

  • (Boolean)


161
162
163
# File 'app/models/concerns/lesli/user_security.rb', line 161

def has_telephone_confirmed?
    !!self.telephone_confirmed_at
end

#max_level_permissionObject



40
41
42
43
44
# File 'app/models/concerns/lesli/user_security.rb', line 40

def max_level_permission

    # get the max level permission from roles assigned to the user
    self.lesliroles.maximum(:permission_level) || 0
end

#revoke_accessObject

Sets this user as inactive and removes complete access to the platform



141
142
143
# File 'app/models/concerns/lesli/user_security.rb', line 141

def revoke_access
    self.update(active: false)
end

#set_password_as_expiredObject

Change user password forcing user to reset the password



146
147
148
# File 'app/models/concerns/lesli/user_security.rb', line 146

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

#set_password_for_resetObject



151
152
153
# File 'app/models/concerns/lesli/user_security.rb', line 151

def set_password_for_reset
    generate_password_reset_token()
end