lesli_shield 1.0.3 → 1.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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/lesli_shield/confirmations.css +18732 -0
  3. data/app/assets/stylesheets/lesli_shield/passwords.css +2 -238
  4. data/app/assets/stylesheets/lesli_shield/registrations.css +2 -238
  5. data/app/assets/stylesheets/lesli_shield/sessions.css +2 -238
  6. data/app/controllers/lesli_shield/dashboards_controller.rb +1 -8
  7. data/app/controllers/lesli_shield/invites_controller.rb +80 -0
  8. data/app/controllers/lesli_shield/role/actions_controller.rb +32 -20
  9. data/app/controllers/lesli_shield/roles_controller.rb +16 -8
  10. data/app/controllers/lesli_shield/sessions_controller.rb +5 -8
  11. data/app/controllers/lesli_shield/user/roles_controller.rb +62 -0
  12. data/app/controllers/lesli_shield/users_controller.rb +57 -20
  13. data/app/controllers/users/confirmations_controller.rb +42 -8
  14. data/app/controllers/users/passwords_controller.rb +52 -37
  15. data/app/controllers/users/registrations_controller.rb +2 -8
  16. data/app/controllers/users/sessions_controller.rb +57 -50
  17. data/app/helpers/lesli_shield/invites_helper.rb +4 -0
  18. data/app/helpers/lesli_shield/user/roles_helper.rb +4 -0
  19. data/app/interfaces/lesli_shield/authorization_interface.rb +8 -2
  20. data/app/mailers/lesli_shield/devise_mailer.rb +98 -0
  21. data/app/mailers/lesli_shield/invitation.html.erb +23 -0
  22. data/app/models/concerns/lesli_shield/user_security.rb +222 -0
  23. data/app/models/lesli_shield/account.rb +1 -1
  24. data/app/models/lesli_shield/dashboard.rb +1 -4
  25. data/app/models/lesli_shield/invite.rb +24 -0
  26. data/{lib/vue/confirmations.js → app/models/lesli_shield/role/action.rb} +17 -10
  27. data/{db/migrate/v1/0801003010_create_lesli_shield_dashboards.rb → app/models/lesli_shield/role/privilege.rb} +5 -4
  28. data/app/models/lesli_shield/user/role.rb +8 -0
  29. data/app/models/lesli_shield/user/session.rb +80 -0
  30. data/app/services/lesli_shield/invite_service.rb +43 -0
  31. data/app/services/lesli_shield/role_action_service.rb +118 -0
  32. data/app/services/lesli_shield/role_privilege_service.rb +112 -0
  33. data/app/{operators/lesli_shield/user_registration_operator.rb → services/lesli_shield/user_registration_service.rb} +26 -29
  34. data/app/services/lesli_shield/user_session_service.rb +78 -0
  35. data/app/services/lesli_shield/user_validator_service.rb +221 -0
  36. data/app/views/devise/confirmations/show.html.erb +4 -6
  37. data/app/views/devise/passwords/edit.html.erb +1 -2
  38. data/app/views/devise/passwords/new.html.erb +1 -1
  39. data/app/views/devise/registrations/new.html.erb +5 -4
  40. data/app/views/devise/sessions/new.html.erb +3 -2
  41. data/app/views/devise/shared/_application-devise-simple.erb +59 -0
  42. data/app/views/devise/shared/_application-devise.html.erb +76 -0
  43. data/app/views/lesli_shield/dashboards/_component-calendar.html.erb +1 -0
  44. data/app/views/lesli_shield/dashboards/_component-chart-bar.html.erb +6 -0
  45. data/app/views/lesli_shield/dashboards/_component-chart-line.html.erb +8 -0
  46. data/app/views/lesli_shield/dashboards/_component-count.html.erb +1 -0
  47. data/app/views/lesli_shield/dashboards/_component-date.html.erb +1 -0
  48. data/app/views/lesli_shield/dashboards/_component-weather.html.erb +1 -0
  49. data/app/views/lesli_shield/invites/_form.html.erb +10 -0
  50. data/app/views/lesli_shield/invites/_invite.html.erb +2 -0
  51. data/app/views/lesli_shield/invites/edit.html.erb +12 -0
  52. data/app/views/lesli_shield/invites/index.html.erb +66 -0
  53. data/{db/migrate/v1/0801001710_create_lesli_shield_settings.rb → app/views/lesli_shield/invites/new.html.erb} +9 -10
  54. data/{lib/vue/apps/dashboards/components/engine-version.vue → app/views/lesli_shield/invites/show.html.erb} +26 -43
  55. data/app/views/lesli_shield/partials/_navigation.html.erb +2 -4
  56. data/app/views/lesli_shield/{roles/_form-privileges.html.erb → role/actions/_form.html.erb} +5 -30
  57. data/app/views/lesli_shield/role/actions/index.html.erb +14 -0
  58. data/app/views/lesli_shield/roles/index.html.erb +2 -6
  59. data/app/views/lesli_shield/roles/new.html.erb +0 -11
  60. data/app/views/lesli_shield/roles/show.html.erb +5 -8
  61. data/app/views/lesli_shield/user/roles/_form.html.erb +17 -0
  62. data/app/views/lesli_shield/user/roles/_role.html.erb +2 -0
  63. data/app/views/lesli_shield/user/roles/edit.html.erb +12 -0
  64. data/app/views/lesli_shield/user/roles/index.html.erb +16 -0
  65. data/app/views/lesli_shield/user/roles/new.html.erb +11 -0
  66. data/app/views/lesli_shield/user/roles/show.html.erb +10 -0
  67. data/app/views/lesli_shield/users/{_viewer-activities.html.erb → _activities-viewer.html.erb} +2 -4
  68. data/app/views/lesli_shield/users/_information-card.html.erb +3 -3
  69. data/app/views/lesli_shield/users/_management-privileges.html.erb +74 -0
  70. data/app/views/lesli_shield/users/_management-security.html.erb +5 -0
  71. data/app/views/lesli_shield/users/index.html.erb +3 -7
  72. data/app/views/lesli_shield/users/new.html.erb +5 -11
  73. data/app/views/lesli_shield/users/show.html.erb +7 -5
  74. data/config/initializers/devise.rb +305 -304
  75. data/config/locales/translations.en.yml +4 -1
  76. data/config/locales/translations.es.yml +4 -1
  77. data/config/locales/translations.it.yml +4 -1
  78. data/config/routes.rb +7 -8
  79. data/db/migrate/v1/0801100210_create_lesli_shield_role_actions.rb +48 -0
  80. data/db/migrate/v1/0801100410_create_lesli_shield_role_privileges.rb +45 -0
  81. data/db/migrate/v1/0801110110_create_lesli_shield_user_roles.rb +43 -0
  82. data/db/migrate/v1/0801111210_create_lesli_shield_user_sessions.rb +56 -0
  83. data/db/migrate/v1/0801120110_create_lesli_shield_invites.rb +49 -0
  84. data/lib/lesli_shield/router.rb +21 -0
  85. data/lib/lesli_shield/version.rb +2 -2
  86. data/lib/lesli_shield.rb +1 -1
  87. data/lib/scss/confirmations.scss +24 -24
  88. data/lib/tasks/lesli_shield_tasks.rake +1 -1
  89. data/readme.md +59 -20
  90. metadata +57 -33
  91. data/app/controllers/lesli_shield/dashboard/components_controller.rb +0 -60
  92. data/app/models/lesli_shield/dashboard/component.rb +0 -18
  93. data/app/views/lesli_shield/dashboards/edit.html.erb +0 -1
  94. data/app/views/lesli_shield/dashboards/index.html.erb +0 -9
  95. data/app/views/lesli_shield/dashboards/new.html.erb +0 -1
  96. data/app/views/lesli_shield/dashboards/show.html.erb +0 -1
  97. data/app/views/lesli_shield/roles/_session.html.erb +0 -2
  98. data/app/views/lesli_shield/roles/edit.html.erb +0 -12
  99. data/app/views/lesli_shield/roles/update.turbo_stream.erb +0 -3
  100. data/app/views/lesli_shield/users/update.turbo_stream.erb +0 -3
  101. data/lib/lesli_shield/routing.rb +0 -23
  102. data/lib/vue/application.js +0 -83
  103. data/lib/vue/apps/sessions/index.vue +0 -50
  104. data/lib/vue/passwords.js +0 -137
  105. data/lib/vue/registrations.js +0 -144
  106. data/lib/vue/sessions.js +0 -148
  107. data/lib/vue/stores/sessions.js +0 -43
  108. data/lib/vue/stores/translations.json +0 -162
  109. /data/app/views/lesli_shield/roles/{_form-information.html.erb → _form.html.erb} +0 -0
  110. /data/db/migrate/v1/{0801120310_create_lesli_shield_user_shortcuts.rb → 0801111010_create_lesli_shield_user_shortcuts.rb} +0 -0
  111. /data/db/migrate/v1/{0801120410_create_lesli_shield_user_tokens.rb → 0801111110_create_lesli_shield_user_tokens.rb} +0 -0
@@ -0,0 +1,222 @@
1
+ =begin
2
+
3
+ Lesli
4
+
5
+ Copyright (c) 2025, 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 LesliTech
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
+
34
+ # User extension methods
35
+ # Custom methods that belongs to a instance user
36
+ module LesliShield
37
+ module UserSecurity
38
+ extend ActiveSupport::Concern
39
+
40
+ # get the max level permission from roles assigned to the user
41
+ def max_level_permission
42
+ self.roles.maximum(:permission_level) || 0
43
+ end
44
+
45
+ # check if user has roles with specific names
46
+ def has_roles?(*roles)
47
+ !roles.intersection(self.roles.map{ |r| r[:name] }).empty?
48
+ end
49
+
50
+ # check the privilege cache to check if user is able
51
+ # to perform a specific action in a specific controller
52
+ def has_privileges_for?(controller, action)
53
+ begin
54
+ return self.privileges.where(
55
+ controller: controller,
56
+ action: action,
57
+ active: true
58
+ ).exists?
59
+ rescue => exception
60
+ L2.danger(exception.to_s)
61
+ return false
62
+ end
63
+ end
64
+
65
+ # Check if user has enough privilege to work with the given role
66
+ def can_work_with_role?(role_id)
67
+
68
+ # get the role if only id is given
69
+ role = self.account.roles.find_by(:id => role_id)
70
+
71
+ # false if role not found
72
+ return false if role.blank?
73
+
74
+ # not valid role without object levelpermission defined
75
+ return false if role.level_permission.blank?
76
+
77
+ # get the max level permission from the roles the user has assigned
78
+ user_role_max_level_permission = self.roles.map(&:level_permission).max()
79
+
80
+ # check if user can work with the level permission of the role is trying to modify
81
+ # Note: user only can assigned an level permission below the max of his own roles
82
+ # Current user cannot assign role if role to assign is the same of the greater role
83
+ # assigned to the current user
84
+ user_role_max_level_permission >= role.level_permission
85
+ end
86
+
87
+ # Checks configuration of all the roles assigned to the user
88
+ # if user has a role with "default path" to use as home to redirect after login
89
+ # IMPORTANT: This home path is used only the send the user after login, the user
90
+ # and the role are not limited by this configuration
91
+ def has_role_with_default_path?()
92
+
93
+ # get the roles that contains a path
94
+ role = self.roles.where.not(path_default: [nil, ""])
95
+
96
+ # here we must order the results descendant because we must
97
+ # keep the path of the hightest level permission role.
98
+ # Example: we should use the path of the admin role if user has
99
+ # admin & employee roles, also order by default_path, so we get first
100
+ # the roles with path in case the user has roles with the same level permission
101
+ role = role.order(level_permission: :desc).order(:path_default)
102
+
103
+ # get the first role found, due previously we sort in a descendant order
104
+ # the first role is going to be the one with highest level permission
105
+ # this is going to return nil if no role was found
106
+ default_path = role.first&.path_default || "/"
107
+
108
+ # if first loggin for account owner send him to the onboarding page
109
+ if self.account.onboarding? && self.has_roles?("owner")
110
+ default_path = "/onboarding"
111
+ end
112
+
113
+ default_path
114
+ end
115
+
116
+ # Checks configuration of all the roles assigned to the user
117
+ # if user has a role limited to a defined path
118
+ # if user has a high privilege role that overrides any other role configuration
119
+ def has_role_limited_to_path?()
120
+
121
+ # get the roles ordering in descendant mode because we must
122
+ # keep the path of the hightest level permission role.
123
+ # Example: we should use the path of the admin role if user has
124
+ # admin & employee roles, also order by default_path, so we get first
125
+ # the roles with path in case the user has roles with the same level permission
126
+ role = self.roles.order(level_permission: :desc).order(:path_default)
127
+
128
+ # get the first role found, due previously we sort in a descendant order
129
+ # the first role is going to be the one with highest level permission
130
+ # this is going to return nil if no role was found
131
+ role = role.first
132
+
133
+ # return the path of the role if is limited to a that specific path
134
+ return role.path_default if role.path_limited == true
135
+
136
+ # return nil if role has no limits
137
+ return nil
138
+ end
139
+
140
+ # Sets this user as inactive and removes complete access to the platform
141
+ def revoke_access
142
+ self.update(active: false)
143
+ end
144
+
145
+ # Change user password forcing user to reset the password
146
+ def set_password_as_expired
147
+ self.update(password_expiration_at: Time.current)
148
+ end
149
+
150
+ # @description Change user password forcing user to reset the password
151
+ def set_password_for_reset
152
+ generate_password_reset_token()
153
+ end
154
+
155
+ def has_expired_password?
156
+ return false if self.password_expiration_at.blank?
157
+ return Time.current > self.password_expiration_at
158
+ end
159
+
160
+ # Check if user has a confirmed telephone number
161
+ def has_telephone_confirmed?
162
+ !!self.telephone_confirmed_at
163
+ end
164
+
165
+ # Change user password forcing user to reset the password
166
+ def generate_password_reset_token
167
+ raw, hashed = Devise.token_generator.generate(Lesli::User, :reset_password_token)
168
+
169
+ self.update!(
170
+ password: nil,
171
+ reset_password_token: hashed,
172
+ reset_password_sent_at: Time.current
173
+ )
174
+
175
+ raw
176
+ end
177
+
178
+ # Generate a token to validate telephone number
179
+ def generate_telephone_token(length=4)
180
+ raw, enc = Devise.token_generator.create(
181
+ self.class,
182
+ :telephone_confirmation_token,
183
+ type:'number',
184
+ length:length
185
+ )
186
+
187
+ self.telephone_confirmation_token = enc
188
+ self.telephone_confirmation_sent_at = Time.now.utc
189
+ self.telephone_confirmed_at = nil
190
+ save(validate: false)
191
+ raw
192
+ end
193
+
194
+ # Mark telephone number as valid and confirmed
195
+ def confirm_telephone_number
196
+ self.telephone_confirmation_token = nil
197
+ self.telephone_confirmation_sent_at = nil
198
+ self.telephone_confirmed_at = Time.now.utc
199
+ save(validate: false)
200
+ end
201
+
202
+ # Return a hash that contains all the abilities grouped by
203
+ # controller and define every action privilege. It also
204
+ # evaluate if the user has the ability no matter if is given
205
+ # to the user by role or by itself.
206
+ def abilities_by_controller
207
+
208
+ # Abilities hash where we will save all the privileges the user has to
209
+ abilities = {}
210
+
211
+ # We check all the privileges the user has in the cache table according to his roles
212
+ # and create a key per controller (with the full controller name) that contains an array of all the
213
+ # methods/actions with permission
214
+ # self.privileges.all.each do |privilege|
215
+ # abilities[privilege.controller] = [] if abilities[privilege.controller].nil?
216
+ # abilities[privilege.controller] << privilege.action
217
+ # end
218
+
219
+ abilities
220
+ end
221
+ end
222
+ end
@@ -34,11 +34,11 @@ module LesliShield
34
34
  class Account < ApplicationRecord
35
35
  belongs_to :account, class_name: "Lesli::Account"
36
36
  has_many :dashboards
37
+ has_many :invites
37
38
 
38
39
  after_create :initialize_account
39
40
 
40
41
  def initialize_account
41
- Dashboard.initialize_account(self)
42
42
  end
43
43
  end
44
44
  end
@@ -32,9 +32,6 @@ Building a better future, one line of code at a time.
32
32
 
33
33
  module LesliShield
34
34
  class Dashboard < Lesli::Shared::Dashboard
35
- self.table_name = "lesli_shield_dashboards"
36
- belongs_to :account
37
-
38
- COMPONENTS = %i[]
35
+ COMPONENTS = %i[calendar chart_bar weather]
39
36
  end
40
37
  end
@@ -0,0 +1,24 @@
1
+ module LesliShield
2
+ class Invite < ApplicationRecord
3
+ belongs_to :account
4
+ belongs_to :user, class_name: "Lesli::User"
5
+
6
+ validates :email, presence: true, on: :create
7
+
8
+ before_create :before_create_invite
9
+
10
+ enum :status, {
11
+ created: 0,
12
+ accepted: 1,
13
+ cancelled: 2,
14
+ sent: 5,
15
+ requested: 6
16
+ }
17
+
18
+ private
19
+
20
+ def before_create_invite
21
+ self.status = :created
22
+ end
23
+ end
24
+ end
@@ -1,7 +1,8 @@
1
- /*
1
+ =begin
2
+
2
3
  Lesli
3
4
 
4
- Copyright (c) 2023, Lesli Technologies, S. A.
5
+ Copyright (c) 2026, Lesli Technologies, S. A.
5
6
 
6
7
  This program is free software: you can redistribute it and/or modify
7
8
  it under the terms of the GNU General Public License as published by
@@ -16,18 +17,24 @@ GNU General Public License for more details.
16
17
  You should have received a copy of the GNU General Public License
17
18
  along with this program. If not, see http://www.gnu.org/licenses/.
18
19
 
19
- Lesli · Your Smart Business Assistant.
20
+ Lesli · Ruby on Rails SaaS Development Framework.
20
21
 
21
- Made with ♥ by https://www.lesli.tech
22
+ Made with ♥ by LesliTech
22
23
  Building a better future, one line of code at a time.
23
24
 
24
25
  @contact hello@lesli.tech
25
- @website https://lesli.tech
26
+ @website https://www.lesli.tech
26
27
  @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
27
28
 
28
- // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
29
- // ·
30
- */
31
-
32
-
29
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
33
30
  // ·
31
+ =end
32
+
33
+ module LesliShield
34
+ class Role::Action < Lesli::ApplicationLesliRecord
35
+ self.table_name = 'lesli_shield_role_actions'
36
+
37
+ belongs_to :role, class_name: 'Lesli::Role'
38
+ belongs_to :action, class_name: "Lesli::Resource"
39
+ end
40
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Lesli
4
4
 
5
- Copyright (c) 2025, Lesli Technologies, S. A.
5
+ Copyright (c) 2026, Lesli Technologies, S. A.
6
6
 
7
7
  This program is free software: you can redistribute it and/or modify
8
8
  it under the terms of the GNU General Public License as published by
@@ -30,8 +30,9 @@ Building a better future, one line of code at a time.
30
30
  // ·
31
31
  =end
32
32
 
33
- class CreateLesliShieldDashboards < ActiveRecord::Migration[6.1]
34
- def change
35
- create_table_lesli_shared_dashboards_10(:lesli_shield)
33
+ module LesliShield
34
+ class Role::Privilege < Lesli::ApplicationLesliRecord
35
+ self.table_name = "lesli_shield_role_privileges"
36
+ belongs_to :role, class_name: "Lesli::Role"
36
37
  end
37
38
  end
@@ -0,0 +1,8 @@
1
+ module LesliShield
2
+ class User::Role < ApplicationRecord
3
+ self.table_name = 'lesli_shield_user_roles'
4
+ belongs_to :user
5
+ belongs_to :role, class_name: "Lesli::Role"
6
+ has_many :roles
7
+ end
8
+ end
@@ -0,0 +1,80 @@
1
+ =begin
2
+
3
+ Lesli
4
+
5
+ Copyright (c) 2026, 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 LesliTech
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 LesliShield
34
+ class User::Session < Lesli::ApplicationLesliRecord
35
+ self.table_name = 'lesli_shield_user_sessions'
36
+ belongs_to :user, class_name: 'Lesli::User'
37
+
38
+ after_create :set_session_token
39
+
40
+ enum :session_source, {
41
+ :dispatcher_standard_session => "dispatcher_standard_session",
42
+ :devise_standard_session => "devise_standard_session"
43
+ }
44
+
45
+ def set_session_token
46
+
47
+ return if self.session_source == "devise_standard_session"
48
+
49
+ return unless self.session_token.blank?
50
+
51
+ rebuild_token = true
52
+
53
+ while rebuild_token do
54
+
55
+ session_token = SecureRandom.alphanumeric(20)
56
+
57
+ # assign token to user if token is unique
58
+ unless User::Session.find_by(:session_token => session_token)
59
+ self.session_token = session_token
60
+ self.save!
61
+ rebuild_token = false
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ def active?
69
+ if self.deleted_at.present?
70
+ return false
71
+ end
72
+
73
+ if self.expiration_at != nil && self.expiration_at < Time.now.utc
74
+ return false
75
+ end
76
+
77
+ return true
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,43 @@
1
+ =begin
2
+
3
+ Lesli
4
+
5
+ Copyright (c) 2025, 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 LesliTech
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 LesliShield
34
+ class InviteService < Lesli::ApplicationLesliService
35
+
36
+ def index params
37
+ Invite.all
38
+ .page(query[:pagination][:page])
39
+ .per(query[:pagination][:perPage])
40
+ .order(updated_at: :desc)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,118 @@
1
+ module LesliShield
2
+ class RoleActionService < Lesli::ApplicationLesliService
3
+
4
+ def find id
5
+ super(Role::Action.with_deleted.find(id))
6
+ end
7
+
8
+ def index role_id
9
+
10
+ def clean action
11
+ {
12
+ :id => action.id,
13
+ :role_id => action.role_id,
14
+ :action_id => action.action_id,
15
+ :deleted_at => action.deleted_at,
16
+ :active => action.active
17
+ }
18
+ end
19
+
20
+ role_actions = {}
21
+
22
+ Role::Action.with_deleted.joins(action: :parent)
23
+ .where(:role_id => role_id)
24
+ .select(
25
+ :id,
26
+ :role_id,
27
+ :deleted_at,
28
+ "parents_lesli_resources.id as controller_id",
29
+ "parents_lesli_resources.label as controller_name",
30
+ "lesli_resources.action as action_name",
31
+ "lesli_resources.id as action_id",
32
+ "case when lesli_shield_role_actions.deleted_at is null then TRUE else FALSE end active"
33
+ ).each do |action|
34
+
35
+ unless role_actions.has_key?(action[:controller_name])
36
+ role_actions[action[:controller_name]] = {
37
+ list:nil,
38
+ index: nil,
39
+ show:nil,
40
+ create:nil,
41
+ update:nil,
42
+ destroy:nil
43
+ }
44
+ end
45
+
46
+ if action[:action_name] == "list"
47
+ role_actions[action[:controller_name]][:list] = clean(action)
48
+ end
49
+
50
+ if action[:action_name] == "index"
51
+ role_actions[action[:controller_name]][:index] = clean(action)
52
+ end
53
+
54
+ if action[:action_name] == "show"
55
+ role_actions[action[:controller_name]][:show] = clean(action)
56
+ end
57
+
58
+ if action[:action_name] == "create"
59
+ role_actions[action[:controller_name]][:create] = clean(action)
60
+ end
61
+
62
+ if action[:action_name] == "update"
63
+ role_actions[action[:controller_name]][:update] = clean(action)
64
+ end
65
+
66
+ if action[:action_name] == "destroy"
67
+ role_actions[action[:controller_name]][:destroy] = clean(action)
68
+ end
69
+ end
70
+
71
+ role_actions
72
+ end
73
+
74
+ def add_guest_actions role
75
+
76
+ # Adding default system actions for profile descriptor
77
+ [
78
+ { controller: "lesli/users", actions: ["update"] }, # enable user edition
79
+ { controller: "lesli/abouts", actions: ["show"] }, # system status
80
+ { controller: "lesli/user/sessions", actions: ["index"] }, # session management
81
+ { controller: "lesli_admin/profiles", actions: ["show"] } # enable profile view
82
+ ].each do |controller_action|
83
+
84
+ controller_action[:actions].each do |action_name|
85
+
86
+ system_controller_action = Lesli::Resource.actions.joins(:parent)
87
+ .where("parents_lesli_resources.route = ?", controller_action[:controller])
88
+ .where("lesli_resources.action = ?", action_name)
89
+
90
+ role.actions.find_or_create_by(
91
+ action: system_controller_action.first
92
+ )
93
+ end
94
+ end
95
+ end
96
+
97
+ def add_owner_actions role
98
+
99
+ now = Time.current
100
+
101
+ # Adding default system actions for profile descriptor
102
+ actions = Lesli::Resource.actions
103
+
104
+ records = actions.map do |action|
105
+ {
106
+ role_id: role.id,
107
+ action_id: action.id,
108
+ created_at: now,
109
+ updated_at: now
110
+ }
111
+ end
112
+
113
+ role.actions.upsert_all(records,
114
+ unique_by: :index_role_actions_on_role_and_action
115
+ )
116
+ end
117
+ end
118
+ end