lesli 5.0.2 → 5.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/config/lesli_manifest.js +2 -1
- data/app/assets/javascripts/lesli/users/confirmations.js +32 -0
- data/app/assets/javascripts/lesli/users/passwords.js +3 -3
- data/app/assets/javascripts/lesli/users/registrations.js +2 -2
- data/app/assets/javascripts/lesli/users/sessions.js +2 -2
- data/app/assets/stylesheets/lesli/users/confirmations.scss +28 -6
- data/app/controllers/lesli/abouts_controller.rb +66 -0
- data/app/controllers/lesli/interfaces/application/authorization.rb +2 -2
- data/app/controllers/lesli/interfaces/application/logger.rb +14 -38
- data/app/controllers/lesli/roles_controller.rb +3 -1
- data/app/controllers/users/confirmations_controller.rb +63 -27
- data/app/controllers/users/passwords_controller.rb +70 -30
- data/app/controllers/users/sessions_controller.rb +2 -4
- data/app/lib/lesli/system.rb +13 -5
- data/app/mailers/lesli/application_lesli_mailer.rb +8 -19
- data/app/mailers/lesli/devise_mailer.rb +29 -3
- data/app/models/concerns/account_initializer.rb +91 -0
- data/app/models/concerns/{user_guard.rb → user_security.rb} +7 -8
- data/app/models/lesli/account.rb +8 -26
- data/app/models/lesli/application_lesli_record.rb +1 -0
- data/app/models/lesli/descriptor/privilege.rb +38 -0
- data/app/models/lesli/descriptor.rb +18 -1
- data/app/models/lesli/role/power.rb +70 -0
- data/app/models/lesli/role/privilege.rb +38 -0
- data/app/models/lesli/role.rb +20 -15
- data/app/models/lesli/user/{role.rb → power.rb} +1 -1
- data/app/{services/lesli/role_service.rb → models/lesli/user/setting.rb} +10 -9
- data/app/models/lesli/user.rb +11 -20
- data/app/operators/lesli/descriptor_privilege_operator.rb +75 -0
- data/app/operators/lesli/role_power_operator.rb +108 -0
- data/app/operators/lesli/user_registration_operator.rb +121 -0
- data/app/services/lesli/user_service.rb +2 -4
- data/app/services/lesli/{user/session_service.rb → user_session_service.rb} +11 -4
- data/app/views/devise/confirmations/new.html.erb +0 -14
- data/app/views/devise/confirmations/show.html.erb +63 -0
- data/app/views/devise/passwords/edit.html.erb +78 -24
- data/app/views/devise/passwords/new.html.erb +1 -2
- data/app/views/lesli/emails/devise_mailer/confirmation_instructions.html.erb +1 -1
- data/app/views/lesli/emails/devise_mailer/reset_password_instructions.html.erb +23 -0
- data/app/views/lesli/partials/_application-lesli-header.html.erb +3 -1
- data/config/initializers/devise.rb +2 -0
- data/config/routes.rb +2 -0
- data/db/migrate/v1.0/0010000110_create_lesli_accounts.rb +2 -0
- data/db/{tables/0010001010_create_account_settings.rb → migrate/v1.0/0010001010_create_lesli_account_settings.rb} +5 -5
- data/db/{tables/0010003110_create_user_settings.rb → migrate/v1.0/0010003110_create_lesli_user_settings.rb} +4 -4
- data/db/migrate/v1.0/0010003210_create_lesli_user_sessions.rb +6 -2
- data/db/migrate/v1.0/{0010003410_create_lesli_user_roles.rb → 0010003410_create_lesli_user_powers.rb} +4 -4
- data/db/migrate/v1.0/0010005010_create_lesli_descriptors.rb +1 -1
- data/db/migrate/v1.0/{0010003910_create_lesli_user_agents.rb → 0010005510_create_lesli_role_powers.rb} +7 -9
- data/db/{tables/0010005710_create_role_privileges.rb → migrate/v1.0/0010005710_create_lesli_role_privileges.rb} +6 -6
- data/db/seed/development/users.rb +4 -4
- data/db/seed/tools.rb +4 -4
- data/lib/lesli/engine.rb +33 -10
- data/lib/lesli/version.rb +1 -1
- data/lib/sass/lesli/bulma/loader.scss +3 -0
- data/lib/sass/lesli/pages/devise-simple.scss +2 -1
- data/lib/tasks/lesli/controllers.rake +3 -6
- data/lib/tasks/lesli/db.rake +11 -1
- data/lib/tasks/lesli/role.rake +54 -0
- data/lib/vue/application.js +9 -2
- data/lib/vue/devise/passwords.js +3 -3
- data/lib/vue/layouts/application-header.vue +10 -3
- data/lib/webpack/core.js +2 -1
- data/readme.md +23 -7
- data/vendor/bulma/LICENSE +21 -0
- data/vendor/bulma/bulma.sass +10 -0
- data/vendor/bulma/css/bulma-rtl.css +11851 -0
- data/vendor/bulma/css/bulma-rtl.min.css +1 -0
- data/vendor/bulma/css/bulma.css +11851 -0
- data/vendor/bulma/css/bulma.min.css +1 -0
- data/vendor/bulma/sass/base/_all.sass +6 -0
- data/vendor/bulma/sass/base/animations.sass +5 -0
- data/vendor/bulma/sass/base/generic.sass +145 -0
- data/vendor/bulma/sass/base/helpers.sass +1 -0
- data/vendor/bulma/sass/base/minireset.sass +79 -0
- data/vendor/bulma/sass/components/_all.sass +15 -0
- data/vendor/bulma/sass/components/breadcrumb.sass +77 -0
- data/vendor/bulma/sass/components/card.sass +103 -0
- data/vendor/bulma/sass/components/dropdown.sass +83 -0
- data/vendor/bulma/sass/components/level.sass +79 -0
- data/vendor/bulma/sass/components/media.sass +59 -0
- data/vendor/bulma/sass/components/menu.sass +59 -0
- data/vendor/bulma/sass/components/message.sass +101 -0
- data/vendor/bulma/sass/components/modal.sass +117 -0
- data/vendor/bulma/sass/components/navbar.sass +446 -0
- data/vendor/bulma/sass/components/pagination.sass +167 -0
- data/vendor/bulma/sass/components/panel.sass +121 -0
- data/vendor/bulma/sass/components/tabs.sass +176 -0
- data/vendor/bulma/sass/elements/_all.sass +16 -0
- data/vendor/bulma/sass/elements/box.sass +26 -0
- data/vendor/bulma/sass/elements/button.sass +357 -0
- data/vendor/bulma/sass/elements/container.sass +29 -0
- data/vendor/bulma/sass/elements/content.sass +162 -0
- data/vendor/bulma/sass/elements/form.sass +1 -0
- data/vendor/bulma/sass/elements/icon.sass +46 -0
- data/vendor/bulma/sass/elements/image.sass +73 -0
- data/vendor/bulma/sass/elements/notification.sass +52 -0
- data/vendor/bulma/sass/elements/other.sass +31 -0
- data/vendor/bulma/sass/elements/progress.sass +73 -0
- data/vendor/bulma/sass/elements/table.sass +134 -0
- data/vendor/bulma/sass/elements/tag.sass +140 -0
- data/vendor/bulma/sass/elements/title.sass +70 -0
- data/vendor/bulma/sass/form/_all.sass +9 -0
- data/vendor/bulma/sass/form/checkbox-radio.sass +22 -0
- data/vendor/bulma/sass/form/file.sass +184 -0
- data/vendor/bulma/sass/form/input-textarea.sass +66 -0
- data/vendor/bulma/sass/form/select.sass +88 -0
- data/vendor/bulma/sass/form/shared.sass +60 -0
- data/vendor/bulma/sass/form/tools.sass +215 -0
- data/vendor/bulma/sass/grid/_all.sass +5 -0
- data/vendor/bulma/sass/grid/columns.sass +513 -0
- data/vendor/bulma/sass/grid/tiles.sass +36 -0
- data/vendor/bulma/sass/helpers/_all.sass +12 -0
- data/vendor/bulma/sass/helpers/color.sass +39 -0
- data/vendor/bulma/sass/helpers/flexbox.sass +35 -0
- data/vendor/bulma/sass/helpers/float.sass +10 -0
- data/vendor/bulma/sass/helpers/other.sass +14 -0
- data/vendor/bulma/sass/helpers/overflow.sass +2 -0
- data/vendor/bulma/sass/helpers/position.sass +7 -0
- data/vendor/bulma/sass/helpers/spacing.sass +31 -0
- data/vendor/bulma/sass/helpers/typography.sass +103 -0
- data/vendor/bulma/sass/helpers/visibility.sass +122 -0
- data/vendor/bulma/sass/layout/_all.sass +6 -0
- data/vendor/bulma/sass/layout/footer.sass +11 -0
- data/vendor/bulma/sass/layout/hero.sass +153 -0
- data/vendor/bulma/sass/layout/section.sass +17 -0
- data/vendor/bulma/sass/utilities/_all.sass +9 -0
- data/vendor/bulma/sass/utilities/animations.sass +1 -0
- data/vendor/bulma/sass/utilities/controls.sass +49 -0
- data/vendor/bulma/sass/utilities/derived-variables.sass +114 -0
- data/vendor/bulma/sass/utilities/extends.sass +25 -0
- data/vendor/bulma/sass/utilities/functions.sass +135 -0
- data/vendor/bulma/sass/utilities/initial-variables.sass +79 -0
- data/vendor/bulma/sass/utilities/mixins.sass +303 -0
- data/vendor/lesli-css/_index.scss +34 -0
- data/vendor/lesli-css/lesli.scss +51 -0
- data/vendor/lesli-css/license +28 -0
- data/vendor/lesli-css/src/base/fonts.scss +50 -0
- data/vendor/lesli-css/src/base/normalize.scss +118 -0
- data/vendor/lesli-css/src/components/blockquote.scss +61 -0
- data/vendor/lesli-css/src/components/columns.scss +92 -0
- data/vendor/lesli-css/src/components/container.scss +47 -0
- data/vendor/lesli-css/src/components/grid.scss +0 -0
- data/vendor/lesli-css/src/components/navigation.scss +59 -0
- data/vendor/lesli-css/src/functions/colors.scss +184 -0
- data/vendor/lesli-css/src/helpers/units.scss +44 -0
- data/vendor/lesli-css/src/mixins/breakpoint.scss +184 -0
- data/vendor/lesli-css/src/mixins/flex.scss +80 -0
- data/vendor/lesli-css/src/mixins/scrollbar.scss +46 -0
- data/vendor/lesli-css/src/settings/variables.scss +26 -0
- data/vendor/lesli-css/tests/base/normalize.spec.scss +125 -0
- data/vendor/lesli-css/tests/functions/colors.spec.scss +117 -0
- data/vendor/lesli-css/tests/mixins/breakpoint.spec.scss +429 -0
- data/vendor/lesli-css/tests/mixins/scrollbar.spec.scss +82 -0
- data/vendor/lesli-css/vendor/normalize.scss +351 -0
- data/vendor/remixicon/License +201 -0
- data/vendor/remixicon/fonts/remixicon.css +2583 -0
- metadata +116 -18
- data/app/models/concerns/account_engines.rb +0 -249
- data/app/models/concerns/user_polyfill.rb +0 -134
- data/config/locales/translations.en.yml +0 -7
- data/config/locales/translations.es.yml +0 -7
- data/db/migrate/v1.0/0010001510_create_lesli_account_requests.rb +0 -45
- data/db/migrate/v1.0/0010003810_create_lesli_user_requests.rb +0 -44
- data/db/tables/0010005510_create_role_descriptors.rb +0 -44
|
@@ -64,15 +64,14 @@ module Lesli
|
|
|
64
64
|
|
|
65
65
|
def log_account_requests
|
|
66
66
|
return unless Lesli.config.security.dig(:enable_analytics)
|
|
67
|
+
return unless defined?(LesliAudit)
|
|
67
68
|
return unless current_user
|
|
68
|
-
return unless session[:user_session_id]
|
|
69
69
|
|
|
70
70
|
# Try to save a unique record for this request configuration
|
|
71
|
-
current_user.account.
|
|
71
|
+
current_user.account.audit.account_requests.upsert(
|
|
72
72
|
{
|
|
73
73
|
request_controller: controller_path,
|
|
74
74
|
request_action: action_name,
|
|
75
|
-
request_method: request.method,
|
|
76
75
|
request_count: 1
|
|
77
76
|
},
|
|
78
77
|
|
|
@@ -80,7 +79,7 @@ module Lesli
|
|
|
80
79
|
unique_by: %i[request_controller request_action created_at account_id],
|
|
81
80
|
|
|
82
81
|
# if request id is not unique, increase the counter for this configuration
|
|
83
|
-
on_duplicate: Arel.sql("request_count =
|
|
82
|
+
on_duplicate: Arel.sql("request_count = lesli_audit_account_requests.request_count + 1")
|
|
84
83
|
)
|
|
85
84
|
end
|
|
86
85
|
|
|
@@ -88,55 +87,32 @@ module Lesli
|
|
|
88
87
|
# this is disabled by default in the settings file
|
|
89
88
|
def log_user_requests
|
|
90
89
|
return unless Lesli.config.security.dig(:enable_analytics)
|
|
90
|
+
return unless defined?(LesliAudit)
|
|
91
91
|
return unless current_user
|
|
92
92
|
return unless session[:user_session_id]
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
# Try to save a unique record for this request configuration
|
|
95
|
-
current_user.
|
|
95
|
+
current_user.account.audit.user_requests.upsert(
|
|
96
96
|
{
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
request_controller: controller_path,
|
|
98
|
+
request_action: action_name,
|
|
99
|
+
session_id: session[:user_session_id],
|
|
100
|
+
user_id: current_user.id,
|
|
101
|
+
request_count: 1
|
|
99
102
|
},
|
|
100
|
-
|
|
103
|
+
|
|
101
104
|
# group of columns to consider a request as unique
|
|
102
|
-
unique_by: %i[created_at user_id session_id],
|
|
105
|
+
unique_by: %i[request_controller request_action created_at user_id session_id],
|
|
103
106
|
|
|
104
107
|
# if request id is not unique
|
|
105
108
|
# - increase the counter for this configuration
|
|
106
109
|
# - update the datetime of the last request
|
|
107
110
|
on_duplicate: Arel.sql(
|
|
108
|
-
'request_count =
|
|
109
|
-
'updated_at = current_timestamp'
|
|
111
|
+
'request_count = lesli_audit_user_requests.request_count + 1'
|
|
110
112
|
)
|
|
111
113
|
)
|
|
112
114
|
end
|
|
113
115
|
|
|
114
|
-
# Track user agents
|
|
115
|
-
# this is disabled by default in the settings file
|
|
116
|
-
def log_user_agent
|
|
117
|
-
return unless Lesli.config.security.dig(:enable_analytics)
|
|
118
|
-
return unless current_user
|
|
119
|
-
return unless session[:user_session_id]
|
|
120
|
-
|
|
121
|
-
user_agent = get_user_agent(false)
|
|
122
|
-
|
|
123
|
-
# Try to save a unique record for this agent configuration
|
|
124
|
-
current_user.agents.upsert(
|
|
125
|
-
{
|
|
126
|
-
os: user_agent[:os] || "unknown",
|
|
127
|
-
platform: user_agent[:platform] || "unknown",
|
|
128
|
-
browser: user_agent[:browser] || "unknown",
|
|
129
|
-
version: user_agent[:version] || "unknown",
|
|
130
|
-
count: 1
|
|
131
|
-
},
|
|
132
|
-
# group of columns to consider a agent as unique
|
|
133
|
-
unique_by: %i[platform os browser version user_id],
|
|
134
|
-
|
|
135
|
-
# if request id is not unique, increase the counter for this configuration
|
|
136
|
-
on_duplicate: Arel.sql("count = lesli_user_agents.count + 1")
|
|
137
|
-
)
|
|
138
|
-
end
|
|
139
|
-
|
|
140
116
|
# Track specific account activity
|
|
141
117
|
# this is disabled by default in the settings file
|
|
142
118
|
def log_account_activity(system_module, system_process, title = nil, payload = nil, description = nil)
|
|
@@ -36,7 +36,9 @@ module Lesli
|
|
|
36
36
|
|
|
37
37
|
def list
|
|
38
38
|
respond_to do |format|
|
|
39
|
-
format.json {
|
|
39
|
+
format.json {
|
|
40
|
+
respond_with_successful(Role.list(current_user, query, params))
|
|
41
|
+
}
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
end
|
|
@@ -1,30 +1,66 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
2
|
class Users::ConfirmationsController < Devise::ConfirmationsController
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
3
|
+
|
|
4
|
+
def show
|
|
5
|
+
|
|
6
|
+
# delete all previus messages
|
|
7
|
+
flash.clear
|
|
8
|
+
|
|
9
|
+
# get the confirmation token sent through get params
|
|
10
|
+
token = params[:confirmation_token]
|
|
11
|
+
|
|
12
|
+
# validate that token were sent
|
|
13
|
+
if token.blank?
|
|
14
|
+
return flash[:danger] = I18n.t("core.users/confirmations.messages_warning_invalid_token")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# check if token belongs to a unconfirmed user
|
|
18
|
+
user = Lesli::User.find_by(:confirmation_token => token, :confirmed_at => nil)
|
|
19
|
+
|
|
20
|
+
# validate that user were found
|
|
21
|
+
if user.blank?
|
|
22
|
+
return flash[:danger] = I18n.t("core.users/confirmations.messages_warning_invalid_token")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# register a log with a validation atempt for the user
|
|
26
|
+
log = user.logs.create({ description: "confirmation_atempt_successful" })
|
|
27
|
+
|
|
28
|
+
registration_operator = Lesli::User::RegistrationOperator.new(user)
|
|
29
|
+
|
|
30
|
+
# confirm the user
|
|
31
|
+
registration_operator.confirm
|
|
32
|
+
|
|
33
|
+
# let the user knows that the confirmation is done
|
|
34
|
+
flash[:success] = I18n.t("core.users/confirmations.messages_success_email_updated")
|
|
35
|
+
|
|
36
|
+
# if new account, launch account onboarding in another thread,
|
|
37
|
+
# so the user can continue with the registration process
|
|
38
|
+
registration_operator.create_account if user.account.blank?
|
|
39
|
+
#Thread.new { registration_operator.create_account } if user.account.blank?
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# @controller_action_param :email [String] The registered user email
|
|
45
|
+
# @return [Json] Json that contains wheter the email confirmation was sent or not.
|
|
46
|
+
# If it is not successful, it returs an error message
|
|
47
|
+
# @description Resends a email confirmation an already registered user
|
|
48
|
+
# @example
|
|
49
|
+
# # Executing this controller's action from javascript's frontend
|
|
50
|
+
# let email = 'john.doe@email.com';
|
|
51
|
+
# let data = {
|
|
52
|
+
# user: {
|
|
53
|
+
# email: email
|
|
54
|
+
# }
|
|
55
|
+
# };
|
|
56
|
+
# this.http.post('127.0.0.1/conformation', data);
|
|
57
|
+
def create
|
|
58
|
+
super do |resource|
|
|
59
|
+
if successfully_sent?(resource)
|
|
60
|
+
return respond_with_successful
|
|
61
|
+
else
|
|
62
|
+
return respond_with_error(resource.errors.full_messages.to_sentence)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
30
66
|
end
|
|
@@ -1,34 +1,74 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Users::PasswordsController < Devise::PasswordsController
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
4
|
+
|
|
5
|
+
# Sends an email with a token, so the user can reset their password
|
|
6
|
+
def create
|
|
7
|
+
|
|
8
|
+
if params[:user].blank?
|
|
9
|
+
#Account::Activity.log("core", "/password/create", "password_creation_failed", "no_valid_email")
|
|
10
|
+
return respond_with_error(I18n.t("core.shared.messages_warning_user_not_found"))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if params[:user][:email].blank?
|
|
14
|
+
#Account::Activity.log("core", "/password/create", "password_creation_failed", "no_valid_email")
|
|
15
|
+
return respond_with_error(I18n.t("core.shared.messages_warning_user_not_found"))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
user = Lesli::User.find_by(:email => params[:user][:email])
|
|
19
|
+
|
|
20
|
+
if user.blank?
|
|
21
|
+
# Account::Activity.log("core", "/password/create", "password_creation_failed", "no_valid_email", {
|
|
22
|
+
# email: (params[:user][:email] || "")
|
|
23
|
+
# })
|
|
24
|
+
return respond_with_error(I18n.t("core.shared.messages_warning_user_not_found"))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
unless user.active
|
|
28
|
+
# user.logs.create({title: "password_creation_failed", description: "user_not_active"})
|
|
29
|
+
# Account::Activity.log("core", "/password/create", "password_creation_failed", "user_not_active")
|
|
30
|
+
return respond_with_error(I18n.t("core.users/passwords.messages_danger_inactive_user"))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
token = user.generate_password_reset_token
|
|
34
|
+
|
|
35
|
+
#user.logs.create({ title: "password_creation_successful" })
|
|
36
|
+
|
|
37
|
+
# begin
|
|
38
|
+
# #UserMailer.with(user: user, token: token).reset_password_instructions.deliver_now
|
|
39
|
+
#super()
|
|
40
|
+
Lesli::DeviseMailer.reset_password_instructions(user, token)
|
|
41
|
+
respond_with_successful
|
|
42
|
+
# rescue => exception
|
|
43
|
+
# #Honeybadger.notify(exception)
|
|
44
|
+
# respond_with_error(exception.message)
|
|
45
|
+
# end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def update
|
|
50
|
+
super do |resource|
|
|
51
|
+
|
|
52
|
+
# check if password update was ok
|
|
53
|
+
if resource.errors.empty?
|
|
54
|
+
|
|
55
|
+
# reset password expiration due the user just updated his password
|
|
56
|
+
if resource.has_expired_password?
|
|
57
|
+
resource.update(password_expiration_at: nil)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
resource.logs.create(title: "password_reset_successful")
|
|
61
|
+
|
|
62
|
+
return respond_with_successful
|
|
63
|
+
|
|
64
|
+
else
|
|
65
|
+
|
|
66
|
+
resource.logs.create(title: "password_reset_error") if resource.id
|
|
67
|
+
|
|
68
|
+
return respond_with_error(resource.errors.full_messages.to_sentence)
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
end
|
|
34
74
|
end
|
|
@@ -89,7 +89,8 @@ class Users::SessionsController < Devise::SessionsController
|
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
# create a new session for the user
|
|
92
|
-
current_session = Lesli::
|
|
92
|
+
current_session = Lesli::UserSessionService.new(user)
|
|
93
|
+
.create(get_user_agent(false), request.remote_ip)
|
|
93
94
|
|
|
94
95
|
# make session id globally available
|
|
95
96
|
session[:user_session_id] = current_session[:id]
|
|
@@ -109,9 +110,6 @@ class Users::SessionsController < Devise::SessionsController
|
|
|
109
110
|
# respond successful and send the path user should go
|
|
110
111
|
#respond_with_successful({ default_path: user.has_role_with_default_path?() })
|
|
111
112
|
respond_with_successful({ default_path: "/" })
|
|
112
|
-
|
|
113
|
-
log_user_agent()
|
|
114
|
-
|
|
115
113
|
end
|
|
116
114
|
|
|
117
115
|
private
|
data/app/lib/lesli/system.rb
CHANGED
|
@@ -17,17 +17,17 @@ GNU General Public License for more details.
|
|
|
17
17
|
You should have received a copy of the GNU General Public License
|
|
18
18
|
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
19
|
|
|
20
|
-
Lesli ·
|
|
20
|
+
Lesli · Ruby on Rails SaaS Development Framework.
|
|
21
21
|
|
|
22
22
|
Made with ♥ by https://www.lesli.tech
|
|
23
23
|
Building a better future, one line of code at a time.
|
|
24
24
|
|
|
25
25
|
@contact hello@lesli.tech
|
|
26
|
-
@website https://lesli.tech
|
|
26
|
+
@website https://www.lesli.tech
|
|
27
27
|
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
28
|
|
|
29
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
-
// ·
|
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
+
// ·
|
|
31
31
|
=end
|
|
32
32
|
|
|
33
33
|
module Lesli
|
|
@@ -81,6 +81,14 @@ module Lesli
|
|
|
81
81
|
name.sub("Lesli", "")
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
LESLI_ENGINES = [
|
|
84
|
+
LESLI_ENGINES = [
|
|
85
|
+
"Lesli",
|
|
86
|
+
"LesliAdmin",
|
|
87
|
+
"LesliBabel",
|
|
88
|
+
"LesliAudit",
|
|
89
|
+
"LesliBell",
|
|
90
|
+
"LesliDriver",
|
|
91
|
+
"LesliVault"
|
|
92
|
+
]
|
|
85
93
|
end
|
|
86
94
|
end
|
|
@@ -75,26 +75,27 @@ module Lesli
|
|
|
75
75
|
=end
|
|
76
76
|
#after_action :log_mail_requests
|
|
77
77
|
|
|
78
|
-
default(template_path: "lesli/emails/devise_mailer")
|
|
78
|
+
#default(template_path: "lesli/emails/devise_mailer")
|
|
79
79
|
|
|
80
80
|
def initialize
|
|
81
81
|
|
|
82
82
|
super
|
|
83
83
|
|
|
84
84
|
# some @email data is defined on: LesliMails/src/partials/data.html
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
@email = {}
|
|
87
|
-
@
|
|
88
|
-
@
|
|
87
|
+
@custom = {}
|
|
88
|
+
@params = {
|
|
89
|
+
:host => default_url_options[:host] || ""
|
|
90
|
+
}
|
|
89
91
|
|
|
90
92
|
end
|
|
91
93
|
|
|
92
94
|
protected
|
|
93
95
|
|
|
94
|
-
def email(
|
|
96
|
+
def email(params={}, user:nil, to:, subject:, template_name:)
|
|
95
97
|
|
|
96
|
-
@
|
|
97
|
-
@data = @data.merge(data)
|
|
98
|
+
@params = @params.merge(params)
|
|
98
99
|
|
|
99
100
|
mail(
|
|
100
101
|
to: to,
|
|
@@ -106,18 +107,6 @@ module Lesli
|
|
|
106
107
|
|
|
107
108
|
private
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
def build_data_from_params(params, data={})
|
|
111
|
-
|
|
112
|
-
# make custom data available in mailer method and mailer template
|
|
113
|
-
@data = @data.merge(data)
|
|
114
|
-
|
|
115
|
-
build_app_from_params(params)
|
|
116
|
-
|
|
117
|
-
build_customization_from_params(params)
|
|
118
|
-
|
|
119
|
-
end
|
|
120
|
-
|
|
121
110
|
def build_app_from_params(params)
|
|
122
111
|
|
|
123
112
|
@app[:host] = default_url_options[:host]
|
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
module Lesli
|
|
2
2
|
class DeviseMailer < ApplicationLesliMailer
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
default(template_path: "lesli/emails/devise_mailer")
|
|
5
|
+
|
|
6
|
+
# Sends an email with instructions to allow the user reset the password
|
|
7
|
+
def reset_password_instructions(user, token, opts = {})
|
|
8
|
+
|
|
9
|
+
# defaults for new accounts/users
|
|
10
|
+
email_template = "reset_password_instructions"
|
|
11
|
+
email_subject = I18n.t("core.users/confirmations.mailer_email_verification")
|
|
12
|
+
|
|
13
|
+
# email parameters
|
|
14
|
+
params = {
|
|
15
|
+
url: "/password/edit?reset_password_token=#{token}",
|
|
16
|
+
user_name: user.full_name
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# send email
|
|
20
|
+
email(
|
|
21
|
+
params,
|
|
22
|
+
to: user.email,
|
|
23
|
+
subject: email_subject,
|
|
24
|
+
template_name: email_template
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Sends an email to allow the user confirm the email address
|
|
29
|
+
def confirmation_instructions(user, token, opts = {})
|
|
4
30
|
|
|
5
31
|
# defaults for new accounts/users
|
|
6
32
|
email_template = "confirmation_instructions"
|
|
@@ -14,9 +40,9 @@ module Lesli
|
|
|
14
40
|
|
|
15
41
|
# Depending on wheter there is a new user or they are changing their email,
|
|
16
42
|
# one or another field will be used
|
|
17
|
-
email_recipient =
|
|
43
|
+
email_recipient = user.unconfirmed_email || user.email
|
|
18
44
|
|
|
19
|
-
# email
|
|
45
|
+
# email parameters
|
|
20
46
|
params = {
|
|
21
47
|
url: "/confirmation?confirmation_token=#{token}"
|
|
22
48
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
|
|
3
|
+
Lesli
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
+
|
|
20
|
+
Lesli · Ruby on Rails SaaS Development Framework.
|
|
21
|
+
|
|
22
|
+
Made with ♥ by https://www.lesli.tech
|
|
23
|
+
Building a better future, one line of code at a time.
|
|
24
|
+
|
|
25
|
+
@contact hello@lesli.tech
|
|
26
|
+
@website https://www.lesli.tech
|
|
27
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
+
|
|
29
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
+
// ·
|
|
31
|
+
=end
|
|
32
|
+
|
|
33
|
+
module AccountInitializer
|
|
34
|
+
extend ActiveSupport::Concern
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# initialize minimum resources needed for the account
|
|
38
|
+
def initialize_account
|
|
39
|
+
|
|
40
|
+
# create initial descriptors
|
|
41
|
+
descriptor_owner = self.descriptors.find_or_create_by(name: "owner")
|
|
42
|
+
descriptor_sysadmin = self.descriptors.find_or_create_by(name: "sysadmin")
|
|
43
|
+
descriptor_profile = self.descriptors.find_or_create_by(name: "profile")
|
|
44
|
+
|
|
45
|
+
# create default roles for the new account
|
|
46
|
+
owner = self.roles.create({ name: "owner", active: true, object_level_permission: 2147483647 })
|
|
47
|
+
|
|
48
|
+
# platform administrator role
|
|
49
|
+
sysadmin = self.roles.create({ name: "sysadmin", active: true, object_level_permission: 100000 })
|
|
50
|
+
|
|
51
|
+
# access only to user profile
|
|
52
|
+
limited = self.roles.create({ name: "limited", active: true, object_level_permission: 10, path_default: "/administration/profile" })
|
|
53
|
+
|
|
54
|
+
# assign descriptors with appropriate privileges
|
|
55
|
+
owner.powers.create(:descriptor => descriptor_owner)
|
|
56
|
+
sysadmin.powers.create(:descriptor => descriptor_sysadmin)
|
|
57
|
+
limited.powers.create(:descriptor => descriptor_profile)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# initialize engines for new accounts
|
|
62
|
+
def initialize_engines
|
|
63
|
+
|
|
64
|
+
# 01.01 LesliAdmin - Lesli administration area
|
|
65
|
+
if defined? LesliAdmin
|
|
66
|
+
if self.admin.blank?
|
|
67
|
+
self.admin = LesliAdmin::Account.new
|
|
68
|
+
self.admin.account = self
|
|
69
|
+
self.admin.save!
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# 03.01 LesliDriver - Unified calendar app
|
|
74
|
+
if defined? LesliDriver
|
|
75
|
+
if self.driver.blank?
|
|
76
|
+
self.driver = LesliDriver::Account.new
|
|
77
|
+
self.driver.account = self
|
|
78
|
+
self.driver.save!
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# 08.03 LesliAudit - System analytics
|
|
83
|
+
if defined? LesliAudit
|
|
84
|
+
if self.audit.blank?
|
|
85
|
+
self.audit = LesliAudit::Account.new
|
|
86
|
+
self.audit.account = self
|
|
87
|
+
self.audit.save!
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -33,7 +33,7 @@ Building a better future, one line of code at a time.
|
|
|
33
33
|
|
|
34
34
|
# User extension methods
|
|
35
35
|
# Custom methods that belongs to a instance user
|
|
36
|
-
module
|
|
36
|
+
module UserSecurity
|
|
37
37
|
extend ActiveSupport::Concern
|
|
38
38
|
|
|
39
39
|
|
|
@@ -71,14 +71,13 @@ module UserGuard
|
|
|
71
71
|
# actions = ["index", "update"]
|
|
72
72
|
#
|
|
73
73
|
# current_user.has_privileges?(controllers, actions)
|
|
74
|
-
def
|
|
74
|
+
def has_privileges_for?(controller, action)
|
|
75
75
|
begin
|
|
76
|
-
!self.privileges
|
|
77
|
-
.where("
|
|
78
|
-
.where("
|
|
79
|
-
.first.blank?
|
|
76
|
+
return !self.privileges
|
|
77
|
+
.where("lesli_role_privileges.controller = ?", controller)
|
|
78
|
+
.where("lesli_role_privileges.action = ?", action)
|
|
79
|
+
.first.blank?
|
|
80
80
|
rescue => exception
|
|
81
|
-
#Honeybadger.notify(exception)
|
|
82
81
|
return false
|
|
83
82
|
end
|
|
84
83
|
end
|
|
@@ -191,7 +190,7 @@ module UserGuard
|
|
|
191
190
|
role = role.first
|
|
192
191
|
|
|
193
192
|
# return the path of the role if is limited to a that specific path
|
|
194
|
-
return role.
|
|
193
|
+
return role.path_default if role.path_limited == true
|
|
195
194
|
|
|
196
195
|
# return nil if role has no limits
|
|
197
196
|
return nil
|
data/app/models/lesli/account.rb
CHANGED
|
@@ -33,6 +33,8 @@ Building a better future, one line of code at a time.
|
|
|
33
33
|
module Lesli
|
|
34
34
|
class Account < ApplicationLesliRecord
|
|
35
35
|
|
|
36
|
+
include AccountInitializer
|
|
37
|
+
|
|
36
38
|
|
|
37
39
|
# accounts always belongs to a user
|
|
38
40
|
belongs_to :user, optional: true
|
|
@@ -48,10 +50,13 @@ module Lesli
|
|
|
48
50
|
has_many :locations
|
|
49
51
|
has_many :feedbacks
|
|
50
52
|
has_many :descriptors
|
|
51
|
-
has_many :activities
|
|
52
|
-
has_many :currencies
|
|
53
|
+
has_many :activities
|
|
54
|
+
has_many :currencies
|
|
53
55
|
has_many :logs
|
|
54
56
|
|
|
57
|
+
has_one :audit, class_name: "LesliAudit::Account"
|
|
58
|
+
has_one :admin, class_name: "LesliAdmin::Account"
|
|
59
|
+
has_one :driver, class_name: "LesliDriver::Account"
|
|
55
60
|
|
|
56
61
|
|
|
57
62
|
# account statuses
|
|
@@ -77,30 +82,7 @@ module Lesli
|
|
|
77
82
|
|
|
78
83
|
# initializers for new accounts
|
|
79
84
|
after_create :initialize_account
|
|
85
|
+
after_create :initialize_engines
|
|
80
86
|
|
|
81
|
-
|
|
82
|
-
def initialize_account
|
|
83
|
-
|
|
84
|
-
# create initial descriptors
|
|
85
|
-
descriptor_owner = self.descriptors.find_or_create_by(name: "owner")
|
|
86
|
-
descriptor_sysadmin = self.descriptors.find_or_create_by(name: "sysadmin")
|
|
87
|
-
descriptor_profile = self.descriptors.find_or_create_by(name: "profile")
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
# create default roles for the new account
|
|
91
|
-
owner = self.roles.create({ name: "owner", active: true, object_level_permission: 2147483647 })
|
|
92
|
-
|
|
93
|
-
# platform administrator role
|
|
94
|
-
sysadmin = self.roles.create({ name: "sysadmin", active: true, object_level_permission: 100000 })
|
|
95
|
-
|
|
96
|
-
# access only to user profile
|
|
97
|
-
limited = self.roles.create({ name: "limited", active: true, object_level_permission: 10, path_default: "/administration/profile" })
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
# assign descriptors with appropriate privileges
|
|
101
|
-
#owner.descriptors.create(:descriptor => descriptor_owner)
|
|
102
|
-
#sysadmin.descriptors.create(:descriptor => descriptor_sysadmin)
|
|
103
|
-
#limited.descriptors.create(:descriptor => descriptor_profile)
|
|
104
|
-
end
|
|
105
87
|
end
|
|
106
88
|
end
|