lesli 5.0.3 → 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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/lesli_manifest.js +2 -1
  3. data/app/assets/javascripts/lesli/users/confirmations.js +32 -0
  4. data/app/assets/javascripts/lesli/users/passwords.js +3 -3
  5. data/app/assets/javascripts/lesli/users/registrations.js +2 -2
  6. data/app/assets/javascripts/lesli/users/sessions.js +2 -2
  7. data/app/assets/stylesheets/lesli/users/confirmations.scss +28 -6
  8. data/app/controllers/lesli/interfaces/application/authorization.rb +2 -2
  9. data/app/controllers/lesli/interfaces/application/logger.rb +14 -38
  10. data/app/controllers/lesli/roles_controller.rb +3 -1
  11. data/app/controllers/users/confirmations_controller.rb +63 -27
  12. data/app/controllers/users/passwords_controller.rb +70 -30
  13. data/app/controllers/users/sessions_controller.rb +2 -4
  14. data/app/lib/lesli/system.rb +13 -5
  15. data/app/mailers/lesli/application_lesli_mailer.rb +8 -19
  16. data/app/mailers/lesli/devise_mailer.rb +29 -3
  17. data/app/models/concerns/account_initializer.rb +91 -0
  18. data/app/models/concerns/{user_guard.rb → user_security.rb} +7 -8
  19. data/app/models/lesli/account.rb +8 -26
  20. data/app/models/lesli/application_lesli_record.rb +1 -0
  21. data/app/models/lesli/descriptor/privilege.rb +38 -0
  22. data/app/models/lesli/descriptor.rb +18 -1
  23. data/app/models/lesli/role/power.rb +70 -0
  24. data/app/models/lesli/role/privilege.rb +38 -0
  25. data/app/models/lesli/role.rb +20 -15
  26. data/app/models/lesli/user/{role.rb → power.rb} +1 -1
  27. data/app/{services/lesli/role_service.rb → models/lesli/user/setting.rb} +10 -9
  28. data/app/models/lesli/user.rb +11 -20
  29. data/app/operators/lesli/descriptor_privilege_operator.rb +75 -0
  30. data/app/operators/lesli/role_power_operator.rb +108 -0
  31. data/app/operators/lesli/user_registration_operator.rb +121 -0
  32. data/app/services/lesli/user_service.rb +2 -4
  33. data/app/services/lesli/{user/session_service.rb → user_session_service.rb} +11 -4
  34. data/app/views/devise/confirmations/new.html.erb +0 -14
  35. data/app/views/devise/confirmations/show.html.erb +63 -0
  36. data/app/views/devise/passwords/edit.html.erb +78 -24
  37. data/app/views/devise/passwords/new.html.erb +1 -2
  38. data/app/views/lesli/emails/devise_mailer/confirmation_instructions.html.erb +1 -1
  39. data/app/views/lesli/emails/devise_mailer/reset_password_instructions.html.erb +23 -0
  40. data/app/views/lesli/partials/_application-lesli-header.html.erb +3 -1
  41. data/config/initializers/devise.rb +2 -0
  42. data/db/migrate/v1.0/0010000110_create_lesli_accounts.rb +2 -0
  43. data/db/{tables/0010001010_create_account_settings.rb → migrate/v1.0/0010001010_create_lesli_account_settings.rb} +5 -5
  44. data/db/{tables/0010003110_create_user_settings.rb → migrate/v1.0/0010003110_create_lesli_user_settings.rb} +4 -4
  45. data/db/migrate/v1.0/0010003210_create_lesli_user_sessions.rb +6 -2
  46. data/db/migrate/v1.0/{0010003410_create_lesli_user_roles.rb → 0010003410_create_lesli_user_powers.rb} +4 -4
  47. data/db/migrate/v1.0/0010005010_create_lesli_descriptors.rb +1 -1
  48. data/db/migrate/v1.0/{0010003910_create_lesli_user_agents.rb → 0010005510_create_lesli_role_powers.rb} +7 -9
  49. data/db/{tables/0010005710_create_role_privileges.rb → migrate/v1.0/0010005710_create_lesli_role_privileges.rb} +6 -6
  50. data/db/seed/development/users.rb +4 -4
  51. data/db/seed/tools.rb +4 -4
  52. data/lib/lesli/engine.rb +33 -10
  53. data/lib/lesli/version.rb +1 -1
  54. data/lib/sass/lesli/bulma/loader.scss +3 -0
  55. data/lib/sass/lesli/pages/devise-simple.scss +2 -1
  56. data/lib/tasks/lesli/controllers.rake +3 -6
  57. data/lib/tasks/lesli/db.rake +11 -1
  58. data/lib/tasks/lesli/role.rake +54 -0
  59. data/lib/vue/application.js +9 -2
  60. data/lib/vue/devise/passwords.js +3 -3
  61. data/lib/vue/layouts/application-header.vue +10 -3
  62. data/lib/webpack/core.js +2 -1
  63. data/readme.md +23 -7
  64. metadata +22 -18
  65. data/app/models/concerns/account_engines.rb +0 -249
  66. data/app/models/concerns/user_polyfill.rb +0 -134
  67. data/config/locales/translations.en.yml +0 -7
  68. data/config/locales/translations.es.yml +0 -7
  69. data/db/migrate/v1.0/0010001510_create_lesli_account_requests.rb +0 -45
  70. data/db/migrate/v1.0/0010003810_create_lesli_user_requests.rb +0 -44
  71. data/db/tables/0010005510_create_role_descriptors.rb +0 -44
@@ -1,30 +1,66 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  class Users::ConfirmationsController < Devise::ConfirmationsController
4
- # GET /resource/confirmation/new
5
- # def new
6
- # super
7
- # end
8
-
9
- # POST /resource/confirmation
10
- # def create
11
- # super
12
- # end
13
-
14
- # GET /resource/confirmation?confirmation_token=abcdef
15
- # def show
16
- # super
17
- # end
18
-
19
- # protected
20
-
21
- # The path used after resending confirmation instructions.
22
- # def after_resending_confirmation_instructions_path_for(resource_name)
23
- # super(resource_name)
24
- # end
25
-
26
- # The path used after confirmation.
27
- # def after_confirmation_path_for(resource_name, resource)
28
- # super(resource_name, resource)
29
- # end
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
- # GET /resource/password/new
5
- # def new
6
- # super
7
- # end
8
-
9
- # POST /resource/password
10
- # def create
11
- # super
12
- # end
13
-
14
- # GET /resource/password/edit?reset_password_token=abcdef
15
- # def edit
16
- # super
17
- # end
18
-
19
- # PUT /resource/password
20
- # def update
21
- # super
22
- # end
23
-
24
- # protected
25
-
26
- # def after_resetting_password_path_for(resource)
27
- # super(resource)
28
- # end
29
-
30
- # The path used after sending reset password instructions
31
- # def after_sending_reset_password_instructions_path_for(resource_name)
32
- # super(resource_name)
33
- # end
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::User::SessionService.new(user).create(get_user_agent, request.remote_ip)
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
@@ -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 · Your Smart Business Assistant.
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 = ["Lesli", "LesliAdmin", "LesliBabel", "LesliAudit", "LesliBell", "LesliDriver"]
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
- @custom = {}
85
+
86
86
  @email = {}
87
- @data = {}
88
- @app = {}
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(data={}, to:, subject:, template_name:)
96
+ def email(params={}, user:nil, to:, subject:, template_name:)
95
97
 
96
- @app[:host] = default_url_options[:host]
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
- def confirmation_instructions(record, token, opts = {})
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 = record.unconfirmed_email || record.email
43
+ email_recipient = user.unconfirmed_email || user.email
18
44
 
19
- # email custom data
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 UserGuard
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 has_privileges?(controller, action)
74
+ def has_privileges_for?(controller, action)
75
75
  begin
76
- !self.privileges
77
- .where("role_privileges.controller = ?", controller)
78
- .where("role_privileges.action = ?", action)
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.path_default_ if role.path_limited == true
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
@@ -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, class_name: "Account::Activity"
52
- has_many :currencies, class_name: "Account::Currency"
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
@@ -33,5 +33,6 @@ Building a better future, one line of code at a time.
33
33
  module Lesli
34
34
  class ApplicationLesliRecord < ApplicationRecord
35
35
  self.abstract_class = true
36
+ acts_as_paranoid
36
37
  end
37
38
  end
@@ -0,0 +1,38 @@
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 Lesli
34
+ class Descriptor::Privilege < ApplicationLesliRecord
35
+ belongs_to :descriptor
36
+ belongs_to :action, class_name: "SystemController::Action"
37
+ end
38
+ end
@@ -33,9 +33,26 @@ Building a better future, one line of code at a time.
33
33
  module Lesli
34
34
  class Descriptor < ApplicationLesliRecord
35
35
  belongs_to :account
36
- #has_many :privileges
36
+ has_many :privileges
37
37
  #has_many :role_descriptors
38
+
39
+ # this scope is needed to allow to join with deleted descriptors
40
+ # join with deleted descriptors is needed to know which privileges we have to remove from the
41
+ # role_privileges table when a descriptor is removed from role_describers
42
+ has_many :role_descriptors_all, -> { with_deleted }, foreign_key: "descriptors_id", class_name: "Role::Descriptor"
38
43
 
39
44
  validates :name, presence: true
45
+
46
+ after_create :initialize_descriptor_privileges
47
+
48
+ def initialize_descriptor_privileges
49
+
50
+ descriptor_operator = DescriptorPrivilegeOperator.new(self)
51
+
52
+ descriptor_operator.add_profile_privileges(self) if self.name == "profile"
53
+
54
+ descriptor_operator.add_owner_privileges(self) if ["owner", "sysadmin"].include?(self.name)
55
+
56
+ end
40
57
  end
41
58
  end