anoubis 1.0.0
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +38 -0
- data/app/controllers/anoubis/application_controller.rb +78 -0
- data/app/controllers/anoubis/core/application_controller.rb +343 -0
- data/app/controllers/anoubis/core/data/actions.rb +962 -0
- data/app/controllers/anoubis/core/data/callbacks.rb +68 -0
- data/app/controllers/anoubis/core/data/convert.rb +407 -0
- data/app/controllers/anoubis/core/data/defaults.rb +217 -0
- data/app/controllers/anoubis/core/data/get.rb +531 -0
- data/app/controllers/anoubis/core/data/load.rb +89 -0
- data/app/controllers/anoubis/core/data/set.rb +49 -0
- data/app/controllers/anoubis/core/data/setup.rb +104 -0
- data/app/controllers/anoubis/core/data_controller.rb +28 -0
- data/app/controllers/anoubis/core/index/actions.rb +53 -0
- data/app/controllers/anoubis/core/index/callbacks.rb +23 -0
- data/app/controllers/anoubis/core/index_controller.rb +36 -0
- data/app/controllers/anoubis/etc/base.rb +52 -0
- data/app/controllers/anoubis/etc/data.rb +89 -0
- data/app/controllers/anoubis/etc/field.rb +468 -0
- data/app/controllers/anoubis/etc/field_options.rb +83 -0
- data/app/controllers/anoubis/etc/field_order.rb +51 -0
- data/app/controllers/anoubis/etc/filter.rb +251 -0
- data/app/controllers/anoubis/etc/menu.rb +101 -0
- data/app/controllers/anoubis/etc/model.rb +67 -0
- data/app/controllers/anoubis/etc/tab_item.rb +91 -0
- data/app/controllers/anoubis/etc.rb +8 -0
- data/app/controllers/anoubis/export.rb +47 -0
- data/app/controllers/anoubis/output/autocomplete.rb +30 -0
- data/app/controllers/anoubis/output/basic.rb +86 -0
- data/app/controllers/anoubis/output/data.rb +101 -0
- data/app/controllers/anoubis/output/delete.rb +41 -0
- data/app/controllers/anoubis/output/edit.rb +55 -0
- data/app/controllers/anoubis/output/frame.rb +227 -0
- data/app/controllers/anoubis/output/login.rb +71 -0
- data/app/controllers/anoubis/output/menu.rb +220 -0
- data/app/controllers/anoubis/output/update.rb +43 -0
- data/app/controllers/anoubis/sso/client/application_controller.rb +139 -0
- data/app/controllers/anoubis/sso/client/data/actions.rb +5 -0
- data/app/controllers/anoubis/sso/client/data/callbacks.rb +5 -0
- data/app/controllers/anoubis/sso/client/data/convert.rb +5 -0
- data/app/controllers/anoubis/sso/client/data/defaults.rb +5 -0
- data/app/controllers/anoubis/sso/client/data/get.rb +5 -0
- data/app/controllers/anoubis/sso/client/data/load.rb +26 -0
- data/app/controllers/anoubis/sso/client/data/set.rb +5 -0
- data/app/controllers/anoubis/sso/client/data/setup.rb +5 -0
- data/app/controllers/anoubis/sso/client/data_controller.rb +21 -0
- data/app/controllers/anoubis/sso/client/index/actions.rb +79 -0
- data/app/controllers/anoubis/sso/client/index/callbacks.rb +13 -0
- data/app/controllers/anoubis/sso/client/index_controller.rb +18 -0
- data/app/controllers/anoubis/sso/server/application_controller.rb +49 -0
- data/app/controllers/anoubis/sso/server/login_controller.rb +342 -0
- data/app/controllers/anoubis/sso/server/user_controller.rb +142 -0
- data/app/controllers/anoubis/tenant/application_controller.rb +54 -0
- data/app/controllers/anoubis/tenant/data/actions.rb +11 -0
- data/app/controllers/anoubis/tenant/data/callbacks.rb +11 -0
- data/app/controllers/anoubis/tenant/data/convert.rb +11 -0
- data/app/controllers/anoubis/tenant/data/defaults.rb +11 -0
- data/app/controllers/anoubis/tenant/data/get.rb +11 -0
- data/app/controllers/anoubis/tenant/data/load.rb +52 -0
- data/app/controllers/anoubis/tenant/data/set.rb +11 -0
- data/app/controllers/anoubis/tenant/data/setup.rb +11 -0
- data/app/controllers/anoubis/tenant/data_controller.rb +28 -0
- data/app/controllers/anoubis/tenant/index/actions.rb +191 -0
- data/app/controllers/anoubis/tenant/index/callbacks.rb +11 -0
- data/app/controllers/anoubis/tenant/index_controller.rb +38 -0
- data/app/controllers/anoubis/tenants_controller.rb +7 -0
- data/app/controllers/anoubis/users_controller.rb +7 -0
- data/app/jobs/anoubis/application_job.rb +6 -0
- data/app/mailers/anoubis/application_mailer.rb +8 -0
- data/app/models/anoubis/application_record.rb +45 -0
- data/app/models/anoubis/core/application_record.rb +250 -0
- data/app/models/anoubis/core/locales.rb +27 -0
- data/app/models/anoubis/sso/client/application_record.rb +3 -0
- data/app/models/anoubis/sso/client/group.rb +19 -0
- data/app/models/anoubis/sso/client/group_menu.rb +109 -0
- data/app/models/anoubis/sso/client/menu.rb +145 -0
- data/app/models/anoubis/sso/client/user.rb +81 -0
- data/app/models/anoubis/sso/client/user_group.rb +32 -0
- data/app/models/anoubis/sso/server/system.rb +36 -0
- data/app/models/anoubis/sso/server/user.rb +79 -0
- data/app/models/anoubis/tenant/application_record.rb +41 -0
- data/app/models/anoubis/tenant/group.rb +95 -0
- data/app/models/anoubis/tenant/group_locale.rb +19 -0
- data/app/models/anoubis/tenant/group_menu.rb +84 -0
- data/app/models/anoubis/tenant/menu.rb +156 -0
- data/app/models/anoubis/tenant/menu_locale.rb +27 -0
- data/app/models/anoubis/tenant/system.rb +127 -0
- data/app/models/anoubis/tenant/system_locale.rb +19 -0
- data/app/models/anoubis/tenant/system_menu.rb +51 -0
- data/app/models/anoubis/tenant/tenant.rb +107 -0
- data/app/models/anoubis/tenant/tenant_system.rb +19 -0
- data/app/models/anoubis/tenant/user.rb +225 -0
- data/app/models/anoubis/tenant/user_group.rb +32 -0
- data/app/services/anoubis/core_service.rb +16 -0
- data/app/services/anoubis/session_service.rb +17 -0
- data/app/validators/presence_in_tenant_validator.rb +20 -0
- data/config/initializers/mime_type.rb +1 -0
- data/config/locales/en.yml +120 -0
- data/config/locales/ru.yml +245 -0
- data/config/routes.rb +74 -0
- data/db/migrate/20181018085843_create_tenants.rb +13 -0
- data/db/migrate/20181018111217_create_systems.rb +10 -0
- data/db/migrate/20181018111713_create_tenant_systems.rb +11 -0
- data/db/migrate/20181018111925_create_groups.rb +13 -0
- data/db/migrate/20181018112151_create_users.rb +25 -0
- data/db/migrate/20181018115737_add_title_to_users.rb +10 -0
- data/db/migrate/20181022060211_create_menus.rb +18 -0
- data/db/migrate/20181115055245_create_group_menus.rb +12 -0
- data/db/migrate/20181115060830_create_system_menus.rb +11 -0
- data/db/migrate/20181122062131_create_user_groups.rb +11 -0
- data/db/migrate/20181221060727_create_menu_locales.rb +14 -0
- data/db/migrate/20181225062303_create_system_locales.rb +11 -0
- data/db/migrate/20181225062339_create_group_locales.rb +11 -0
- data/db/seeds.rb +268 -0
- data/lib/anoubis/engine.rb +13 -0
- data/lib/anoubis/version.rb +5 -0
- data/lib/anoubis.rb +213 -0
- data/lib/tasks/anubis_tasks.rake +10 -0
- data/lib/tasks/sessions/clear_sessions.rake +10 -0
- data/spec/anubis_spec.rb +5 -0
- data/spec/controllers/anoubis/index_controller_spec.rb +77 -0
- data/spec/dummy/Rakefile +3 -0
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/bin/update +28 -0
- data/spec/dummy/config/application.rb +14 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +54 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +54 -0
- data/spec/dummy/config/environments/production.rb +85 -0
- data/spec/dummy/config/environments/test.rb +46 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cors.rb +16 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +34 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/db/schema.rb +167 -0
- data/spec/dummy/db/seeds.rb +1 -0
- data/spec/factories/anubis_group_locales.rb +7 -0
- data/spec/factories/anubis_group_menus.rb +7 -0
- data/spec/factories/anubis_groups.rb +6 -0
- data/spec/factories/anubis_menu_locales.rb +9 -0
- data/spec/factories/anubis_menus.rb +6 -0
- data/spec/factories/anubis_system_locales.rb +7 -0
- data/spec/factories/anubis_system_menus.rb +6 -0
- data/spec/factories/anubis_systems.rb +5 -0
- data/spec/factories/anubis_tenants.rb +7 -0
- data/spec/factories/anubis_users.rb +10 -0
- data/spec/integration/navigation_test.rb +7 -0
- data/spec/models/anoubis/group_locale_spec.rb +25 -0
- data/spec/models/anoubis/group_menu_spec.rb +50 -0
- data/spec/models/anoubis/group_spec.rb +52 -0
- data/spec/models/anoubis/menu_locale_spec.rb +31 -0
- data/spec/models/anoubis/menu_spec.rb +48 -0
- data/spec/models/anoubis/system_locale_spec.rb +20 -0
- data/spec/models/anoubis/system_menu_spec.rb +49 -0
- data/spec/models/anoubis/system_spec.rb +53 -0
- data/spec/models/anoubis/tenant_spec.rb +67 -0
- data/spec/models/anoubis/user_spec.rb +57 -0
- data/spec/rails_helper.rb +32 -0
- data/spec/requests/anoubis/users_request_spec.rb +5 -0
- data/spec/spec_helper.rb +13 -0
- metadata +408 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Model links {Menu} and {Group}. Describes group access to menu.
|
|
3
|
+
class Anoubis::Tenant::GroupMenu < Anoubis::Core::ApplicationRecord
|
|
4
|
+
# Redefines default table name
|
|
5
|
+
self.table_name = 'group_menus'
|
|
6
|
+
|
|
7
|
+
before_validation :before_validation_group_menu
|
|
8
|
+
after_create :after_create_group_menu
|
|
9
|
+
before_update :before_update_group_menu
|
|
10
|
+
after_destroy :after_destroy_group_menu
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# @!attribute group
|
|
14
|
+
# @return [Group] reference to the {Group} model
|
|
15
|
+
belongs_to :group, :class_name => 'Anoubis::Tenant::Group'
|
|
16
|
+
validates :group, presence: true, uniqueness: { scope: [:menu_id] }
|
|
17
|
+
|
|
18
|
+
# @!attribute menu
|
|
19
|
+
# @return [Menu] reference to the {Menu} model
|
|
20
|
+
belongs_to :menu, :class_name => 'Anoubis::Tenant::Menu'
|
|
21
|
+
validates :menu, presence: true, uniqueness: { scope: [:group_id] }
|
|
22
|
+
|
|
23
|
+
# @!attribute access
|
|
24
|
+
# @return ['not', 'read', 'write', 'disable'] group access to menu element.
|
|
25
|
+
# - 'not' --- menu element doesn't available for this group
|
|
26
|
+
# - 'read' --- group has access to menu element only for read data
|
|
27
|
+
# - 'write' --- group has access to menu element for read and write data
|
|
28
|
+
# - 'disable' --- group hasn't access to menu element
|
|
29
|
+
enum access: { not: 0, read: 20, write: 40, disable: 60 }
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Is called before validation when the link between menu and group is being created or updated.
|
|
33
|
+
# Procedure checks if group belongs a system that has access to this menu element. If {#access} doesn't
|
|
34
|
+
# defined then {#access} sets to 'read'
|
|
35
|
+
def before_validation_group_menu
|
|
36
|
+
if !Anoubis::Tenant::SystemMenu.where(system_id: self.group.system_id, menu_id: self.menu_id).first
|
|
37
|
+
errors.add(:base, I18n.t('anubis.group_menus.errors.no_access'))
|
|
38
|
+
throw(:abort, __method__)
|
|
39
|
+
end
|
|
40
|
+
self.access = Anubis::Tenant::GroupMenu.accesses[:read] if !self.access
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# Is called after new link between menu and group was created. If new element has parent with link that
|
|
45
|
+
# doesn't present in database then adds this link to database with {#access} defined as 'read'.
|
|
46
|
+
def after_create_group_menu
|
|
47
|
+
if self.menu.menu_id != nil
|
|
48
|
+
Anubis::Tenant::GroupMenu.find_or_create_by(menu_id: self.menu.menu_id, group_id: self.group_id) do |menu|
|
|
49
|
+
menu.access = Anubis::Tenant::GroupMenu.accesses[:read]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
self.after_modify_group_menu
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Is called before link between menu and group will be updated. Procedure prevents changing {#menu}
|
|
57
|
+
# and {#group} value.
|
|
58
|
+
def before_update_group_menu
|
|
59
|
+
self.menu_id = self.menu_id_was if self.menu_id_changed?
|
|
60
|
+
self.group_id = self.group_id_was if self.group_id_changed?
|
|
61
|
+
self.after_modify_group_menu
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
##
|
|
65
|
+
# Is called after link between menu and group had been deleted from database. It also deletes all child links.
|
|
66
|
+
def after_destroy_group_menu
|
|
67
|
+
Anubis::Tenant::Menu.select(:id).where(menu_id: self.menu_id).each do |menu|
|
|
68
|
+
Anubis::Tenant::GroupMenu.where(menu_id: menu.id, group_id: self.group_id).each do |group_menu|
|
|
69
|
+
group_menu.destroy
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
self.after_modify_group_menu
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
##
|
|
76
|
+
# Deletes all user's keys that belong this menu element in Redis database.
|
|
77
|
+
def after_modify_group_menu
|
|
78
|
+
if self.redis
|
|
79
|
+
self.redis.keys(self.redis_prefix + '*_'+self.menu.mode).each do |data|
|
|
80
|
+
self.redis.del data
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Menu model. Stores information about all menu elements of the portal. Menu model defines the dependence
|
|
3
|
+
# between controller and user access.
|
|
4
|
+
class Anubis::Tenant::Menu < ApplicationRecord
|
|
5
|
+
# Redefines default table name
|
|
6
|
+
self.table_name = 'menus'
|
|
7
|
+
|
|
8
|
+
before_create :before_create_menu
|
|
9
|
+
before_update :before_update_menu
|
|
10
|
+
before_save :before_save_menu
|
|
11
|
+
before_destroy :before_destroy_menu
|
|
12
|
+
after_destroy :after_destroy_menu
|
|
13
|
+
|
|
14
|
+
# @!attribute mode
|
|
15
|
+
# @return [String] the controller path for menu element.
|
|
16
|
+
validates :mode, presence: true, uniqueness: true
|
|
17
|
+
|
|
18
|
+
# @!attribute action
|
|
19
|
+
# @return [String] the default action of menu element ('data', 'menu', etc.).
|
|
20
|
+
validates :action, presence: true
|
|
21
|
+
|
|
22
|
+
# @!attribute tab
|
|
23
|
+
# @return [Integer] the nesting level of menu element
|
|
24
|
+
validates :tab, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
25
|
+
|
|
26
|
+
# @!attribute position
|
|
27
|
+
# @return [Integer] the order position of menu element in current level.
|
|
28
|
+
validates :position, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
29
|
+
|
|
30
|
+
# @!attribute page_size
|
|
31
|
+
# @return [Integer] the default page size for table of data frame.
|
|
32
|
+
validates :page_size, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
33
|
+
|
|
34
|
+
# @!attribute menu
|
|
35
|
+
# @return [Menu, nil] the parent menu for element menu (if exists).
|
|
36
|
+
belongs_to :menu, class_name: 'Anubis::Tenant::Menu', optional: true
|
|
37
|
+
has_many :menus, class_name: 'Anubis::Tenant::Menu'
|
|
38
|
+
|
|
39
|
+
has_many :group_menus, class_name: 'Anubis::Tenant::GroupMenu'
|
|
40
|
+
has_many :system_menus, class_name: 'Anubis::Tenant::SystemMenu'
|
|
41
|
+
has_many :menu_locales, class_name: 'Anubis::Tenant::MenuLocale'
|
|
42
|
+
|
|
43
|
+
# @!attribute status
|
|
44
|
+
# @return ['enabled', 'disabled'] the status of menu element.
|
|
45
|
+
# - 'enabled' --- element is enabled and is used by the system.
|
|
46
|
+
# - 'disabled' --- element is disabled and isn't used by the system.
|
|
47
|
+
enum status: { enabled: 0, disabled: 1 }
|
|
48
|
+
|
|
49
|
+
# @!attribute state
|
|
50
|
+
# @return ['visible', 'hidden'] the visibility of menu element. Attribute is used in fronted application.
|
|
51
|
+
# - 'visible' --- element is visible.
|
|
52
|
+
# - 'hidden' --- element is hidden.
|
|
53
|
+
enum state: { visible: 0, hidden: 1 }
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Is called before menu will be created in database. Sets {#position} as last {#position} + 1 on current {#tab}.
|
|
57
|
+
# After this calls {#before_update_menu} for additional modification.
|
|
58
|
+
def before_create_menu
|
|
59
|
+
data = Anubis::Tenant::Menu.where(menu_id: self.menu_id).maximum(:position)
|
|
60
|
+
self.position = if data then data + 1 else 0 end
|
|
61
|
+
|
|
62
|
+
self.before_update_menu
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Is called before menu will be stored in database. Sets {#mode} and {#action} in lowercase. If {#page_size}
|
|
67
|
+
# doesn't defined then sets it to 20. If defined parent menu element then sets {#tab} based on {#tab} of
|
|
68
|
+
# parent menu element + 1.
|
|
69
|
+
def before_update_menu
|
|
70
|
+
self.mode = mode.downcase
|
|
71
|
+
self.action = self.action.downcase
|
|
72
|
+
self.page_size = 20 if !self.page_size
|
|
73
|
+
self.page_size = self.page_size.to_i
|
|
74
|
+
|
|
75
|
+
parent_menu = Anubis::Tenant::Menu.where(id: self.menu_id).first
|
|
76
|
+
if parent_menu
|
|
77
|
+
self.tab = parent_menu.tab + 1
|
|
78
|
+
else
|
|
79
|
+
self.tab = 0
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Is called right before menu will be stored in database (after {#before_create_menu} and {#before_update_menu}).
|
|
85
|
+
# Deletes cache data for this menu in Redis database.
|
|
86
|
+
def before_save_menu
|
|
87
|
+
self.redis.del(self.redis_prefix + 'menu_' + self.mode) if self.redis
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
##
|
|
91
|
+
# Is called before menu will be deleted from database. Checks the ability to destroy a menu. Delete
|
|
92
|
+
# all translations for menu model from {MenuLocale}.
|
|
93
|
+
def before_destroy_menu
|
|
94
|
+
Anubis::Tenant::MenuLocale.where(menu_id: self.id).each do |menu_locale|
|
|
95
|
+
menu_locale.destroy
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
if !can_destroy?
|
|
99
|
+
errors.add(:base, I18n.t('anubis.menus.errors.has_childs'))
|
|
100
|
+
throw(:abort, __method__)
|
|
101
|
+
end
|
|
102
|
+
#childs = !self.menus.empty?
|
|
103
|
+
#childs = !self.group_menus.empty? if !childs
|
|
104
|
+
#childs = !self.system_menus.empty? if !childs
|
|
105
|
+
|
|
106
|
+
#return if !childs
|
|
107
|
+
|
|
108
|
+
#errors.add(:base, I18n.t('menus.errors.has_childs'))
|
|
109
|
+
#throw(:abort, __method__)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
##
|
|
113
|
+
# Is called after menu was deleted from database. Procedure recalculates position of other menu elements.
|
|
114
|
+
def after_destroy_menu
|
|
115
|
+
query = <<-SQL
|
|
116
|
+
UPDATE menus
|
|
117
|
+
SET menus.position = menus.position - 1
|
|
118
|
+
WHERE menus.tab = #{self.tab} AND menus.position > #{self.position}
|
|
119
|
+
SQL
|
|
120
|
+
Anubis::Tenant::Menu.connection.execute query
|
|
121
|
+
#i = self.position
|
|
122
|
+
#Anubis::Tenant::Menu.where(menu_id: self.menu_id, position: (self.position+1..Float::INFINITY)).find_each do |menu|
|
|
123
|
+
# menu.position = i
|
|
124
|
+
# menu.save
|
|
125
|
+
# i += 1
|
|
126
|
+
# end
|
|
127
|
+
Anubis::Tenant::Menu.where(menu_id: self.id).find_each do |menu|
|
|
128
|
+
menu.destroy
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
##
|
|
133
|
+
# Returns model localization data from {MenuLocale}.
|
|
134
|
+
# @return [MenuLocale] localization for current menu
|
|
135
|
+
def model_locale
|
|
136
|
+
@model_locale ||= self.menu_locales.where(locale: Anubis::Tenant::MenuLocale.locales[self.current_locale.to_sym]).first
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# @!attribute title
|
|
140
|
+
# @return [String] the menu's title. Title loads from {MenuLocale#title} based on {#current_locale}
|
|
141
|
+
def title
|
|
142
|
+
self.model_locale.title if self.model_locale
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @!attribute page_title
|
|
146
|
+
# @return [String] the menu's page title. Page title loads from {MenuLocale#page_title} based on {#current_locale}
|
|
147
|
+
def page_title
|
|
148
|
+
self.model_locale.page_title if self.model_locale
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# @!attribute short_title
|
|
152
|
+
# @return [String] the menu's short title. Short title loads from {MenuLocale#short_title} based on {#current_locale}
|
|
153
|
+
def short_title
|
|
154
|
+
self.model_locale.short_title if self.model_locale
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Localization for {Menu} model. Model stores all translations for {Menu} model.
|
|
3
|
+
class Anoubis::Tenant::MenuLocale < Anoubis::Core::ApplicationRecord
|
|
4
|
+
# Redefines default table name
|
|
5
|
+
self.table_name = 'menu_locales'
|
|
6
|
+
|
|
7
|
+
# @!attribute menu
|
|
8
|
+
# @return [Menu] reference to the {Menu} model
|
|
9
|
+
belongs_to :menu, :class_name => 'Anoubis::Tenant::Menu'
|
|
10
|
+
validates :menu, presence: true, uniqueness: { scope: [:locale] }
|
|
11
|
+
|
|
12
|
+
# @!attribute title
|
|
13
|
+
# @return [String] the menu's localized title
|
|
14
|
+
validates :title, presence: true, length: { minimum: 3, maximum: 100 }
|
|
15
|
+
|
|
16
|
+
# @!attribute page_title
|
|
17
|
+
# @return [String] the menu's localized page title. Uses in frontend application.
|
|
18
|
+
validates :page_title, presence: true, length: { minimum: 3, maximum: 200 }
|
|
19
|
+
|
|
20
|
+
# @!attribute short_title
|
|
21
|
+
# @return [String] the menu's localized short title. Uses in frontend application.
|
|
22
|
+
validates :short_title, length: { maximum: 200 }
|
|
23
|
+
|
|
24
|
+
# @!attribute locale
|
|
25
|
+
# @return [Locales] reference to locale
|
|
26
|
+
enum locale: Anoubis::Core::Locales.enums
|
|
27
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
##
|
|
2
|
+
# System model. Stores information about all portal's systems.
|
|
3
|
+
class Anoubis::Tenant::System < Anoubis::Core::ApplicationRecord
|
|
4
|
+
# Redefines default table name
|
|
5
|
+
self.table_name = 'systems'
|
|
6
|
+
|
|
7
|
+
before_validation :before_validation_system_create, on: :create
|
|
8
|
+
before_validation :before_validation_system_update, on: :update
|
|
9
|
+
after_create :after_create_system
|
|
10
|
+
before_save :before_save_system
|
|
11
|
+
after_update :after_update_system
|
|
12
|
+
before_destroy :before_destroy_system
|
|
13
|
+
|
|
14
|
+
# System's identifier consists of lowercase alphabetic symbols.
|
|
15
|
+
VALID_SYSTEM_REGEX = /[a-z]\z/i
|
|
16
|
+
|
|
17
|
+
# @!attribute ident
|
|
18
|
+
# @return [String] the system's identifier. Identifier consists of lowercase alphabetical symbols.
|
|
19
|
+
validates :ident, length: { minimum: 3, maximum: 15 }, uniqueness: true, format: { with: VALID_SYSTEM_REGEX }
|
|
20
|
+
|
|
21
|
+
has_many :tenant_systems, class_name: 'Anoubis::Tenant::TenantSystem'
|
|
22
|
+
has_many :groups, class_name: 'Anoubis::Tenant::Group'
|
|
23
|
+
has_many :system_menus, class_name: 'Anoubis::Tenant::SystemMenu'
|
|
24
|
+
has_many :system_locales, class_name: 'Anoubis::Tenant::SystemLocale'
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
# Is called before validation when new system is being created. If it's a first system then it sets {#ident}
|
|
28
|
+
# value to 'sys'
|
|
29
|
+
def before_validation_system_create
|
|
30
|
+
if self.id
|
|
31
|
+
if self.id == 1
|
|
32
|
+
self.ident = 'sys'
|
|
33
|
+
return true
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# Is called before validation when system is being updated. Prevents the changing {#ident} value for
|
|
40
|
+
# system with id 1.
|
|
41
|
+
def before_validation_system_update
|
|
42
|
+
if self.id == 1 && self.ident_was != self.ident
|
|
43
|
+
errors.add(:ident, I18n.t('anubis.systems.errors.cant_change_ident'))
|
|
44
|
+
throw(:abort, __method__)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# Is called after new system was created. Creates administration group for new system.
|
|
50
|
+
def after_create_system
|
|
51
|
+
if self.id == 1
|
|
52
|
+
data = Anoubis::Tenant::Group.create(id: 1)
|
|
53
|
+
I18n.available_locales.each do |locale|
|
|
54
|
+
I18n.locale = locale
|
|
55
|
+
Anoubis::Tenant::GroupLocale.find_or_create_by(group_id: data.id, locale: Anoubis::Tenant::MenuLocale.locales[locale.to_s.to_sym]) do |system_locale|
|
|
56
|
+
system_locale.title = I18n.t('anubis.install.admins_group')
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
data = Anoubis::Tenant::Group.find_or_create_by(ident: 'admin', system_id: self.id)
|
|
61
|
+
I18n.available_locales.each do |locale|
|
|
62
|
+
I18n.locale = locale
|
|
63
|
+
Anubis::Tenant::GroupLocale.find_or_create_by(group_id: data.id, locale: Anubis::Tenant::MenuLocale.locales[locale.to_s.to_sym]) do |system_locale|
|
|
64
|
+
system_locale.title = I18n.t('anubis.install.admins_group')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# Is called before system will be stored in database. Changes {#ident} value to lower case.
|
|
72
|
+
def before_save_system
|
|
73
|
+
self.ident = self.ident.downcase if self.ident
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
##
|
|
77
|
+
# Is called after system had been updated. If {#ident} value had been changed then procedure updates
|
|
78
|
+
# every {Anubis::Group#full_ident} value.
|
|
79
|
+
def after_update_system
|
|
80
|
+
if self.ident_was != self.ident
|
|
81
|
+
update_groups_full_ident self.id, self.ident
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
##
|
|
86
|
+
# Is called before system will be deleted from database. Checks the ability to destroy a system. Delete
|
|
87
|
+
# all translations for system model from {GroupLocale}.
|
|
88
|
+
def before_destroy_system
|
|
89
|
+
if self.id == 1
|
|
90
|
+
errors.add(:base, I18n.t('anubis.tenants.errors.cant_destroy'))
|
|
91
|
+
throw(:abort, __method__)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
Anubis::Tenant::SystemLocale.where(system_id: self.id).each do |system_locale|
|
|
95
|
+
system_locale.destroy
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
if !can_destroy?
|
|
99
|
+
errors.add(:base, I18n.t('anubis.tenants.errors.has_childs'))
|
|
100
|
+
throw(:abort, __method__)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
##
|
|
105
|
+
# Updates {Group#full_ident} when changed system's identifier.
|
|
106
|
+
# @param id [Integer] group unique identifier
|
|
107
|
+
# @param ident [String] new system identifier
|
|
108
|
+
def update_groups_full_ident (id, ident)
|
|
109
|
+
query = <<-SQL
|
|
110
|
+
UPDATE groups SET groups.full_ident = CONCAT('#{ident}.', groups.ident) WHERE groups.system_id = #{id}
|
|
111
|
+
SQL
|
|
112
|
+
Anubis::Tenant::Group.connection.execute query
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
##
|
|
116
|
+
# Returns model localization data from {SystemLocale}.
|
|
117
|
+
# @return [SystemLocale] localization for current system
|
|
118
|
+
def model_locale
|
|
119
|
+
@model_locale ||= self.system_locales.where(locale: Anubis::Tenant::SystemLocale.locales[self.current_locale.to_sym]).first
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# @!attribute title
|
|
123
|
+
# @return [String] the system's title. Title loads from {SystemLocale#title} based on {#current_locale}
|
|
124
|
+
def title
|
|
125
|
+
self.model_locale.title if self.model_locale
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Localization for {System} model. Model stores all translations for {System} model.
|
|
3
|
+
class Anoubis::Tenant::SystemLocale < Anoubis::Core::ApplicationRecord
|
|
4
|
+
# Redefines default table name
|
|
5
|
+
self.table_name = 'system_locales'
|
|
6
|
+
|
|
7
|
+
# @!attribute title
|
|
8
|
+
# @return [String] the system's localized title
|
|
9
|
+
validates :title, length: { minimum: 3, maximum: 100 }, uniqueness: { scope: [:system_id, :locale] }
|
|
10
|
+
|
|
11
|
+
# @!attribute system
|
|
12
|
+
# @return [System] reference to the {System} model
|
|
13
|
+
belongs_to :system, :class_name => 'Anoubis::Tenant::System'
|
|
14
|
+
validates :system, presence: true, uniqueness: { scope: [:locale] }
|
|
15
|
+
|
|
16
|
+
# @!attribute locale
|
|
17
|
+
# @return [Locales] reference to locale
|
|
18
|
+
enum locale: Anoubis::Core::Locales.enums
|
|
19
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Model links menu and systems. Describes if system has access to menu.
|
|
3
|
+
class Anoubis::Tenant::SystemMenu < Anoubis::Core::ApplicationRecord
|
|
4
|
+
# Redefines default table name
|
|
5
|
+
self.table_name = 'system_menus'
|
|
6
|
+
|
|
7
|
+
after_create :after_create_system_menu
|
|
8
|
+
after_destroy :after_destroy_system_menu
|
|
9
|
+
|
|
10
|
+
# @!attribute system
|
|
11
|
+
# @return [System] reference to the {System} model
|
|
12
|
+
belongs_to :system, class_name: 'Anoubis::Tenant::System'
|
|
13
|
+
validates :system, presence: true, uniqueness: { scope: [:menu_id] }
|
|
14
|
+
|
|
15
|
+
# @!attribute menu
|
|
16
|
+
# @return [Menu] reference to the {Menu} model
|
|
17
|
+
belongs_to :menu, class_name: 'Anoubis::Tenant::Menu'
|
|
18
|
+
validates :menu, presence: true, uniqueness: { scope: [:system_id] }
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Is called after create new link between system and menu. If created element has parent element and
|
|
22
|
+
# link to this parent element doesn't present in database then adds this link too.
|
|
23
|
+
def after_create_system_menu
|
|
24
|
+
if self.menu.menu_id != nil
|
|
25
|
+
Anoubis::Tenant::SystemMenu.find_or_create_by(menu: self.menu.menu, system: self.system)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Is called after link between system and menu was deleted from database. It also deletes all child links.
|
|
31
|
+
def after_destroy_system_menu
|
|
32
|
+
ids = []
|
|
33
|
+
|
|
34
|
+
Anoubis::Tenant::Menu.where(menu_id: self.menu_id).each do |data|
|
|
35
|
+
ids.push data.id
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
Anoubis::Tenant::SystemMenu.where(menu_id: ids, system_id: self.system_id).each do |data|
|
|
39
|
+
data.destroy
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
ids = []
|
|
43
|
+
Anoubis::Tenant::Group.where(system_id: self.system_id).each do |data|
|
|
44
|
+
ids.push data.id
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
Anoubis::Tenant::GroupMenu.where(menu_id: self.menu_id, group_id: ids).each do |data|
|
|
48
|
+
data.destroy
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Tenant model. Stores information about all portal's tenants.
|
|
3
|
+
class Anoubis::Tenant::Tenant < Anoubis::Core::ApplicationRecord
|
|
4
|
+
# Redefines default table name
|
|
5
|
+
self.table_name = 'tenants'
|
|
6
|
+
|
|
7
|
+
before_validation :before_validation_tenant_create, on: :create
|
|
8
|
+
before_validation :before_validation_tenant_update, on: :update
|
|
9
|
+
before_save :before_save_tenant
|
|
10
|
+
after_create :after_create_tenant
|
|
11
|
+
after_update :after_update_tenant
|
|
12
|
+
before_destroy :before_destroy_tenant
|
|
13
|
+
|
|
14
|
+
# Tenant's identifier consists of lowercase alphabetic symbols.
|
|
15
|
+
VALID_TENANT_REGEX = /[a-z]\z/i
|
|
16
|
+
|
|
17
|
+
# @!attribute ident
|
|
18
|
+
# @return [String] the tenant's identifier. Identifier consists of lowercase alphabetical symbols.
|
|
19
|
+
validates :ident, length: { minimum: 3, maximum: 10 }, uniqueness: true, format: { with: VALID_TENANT_REGEX }
|
|
20
|
+
|
|
21
|
+
# @!attribute title
|
|
22
|
+
# @return [String] the tenant's title
|
|
23
|
+
validates :title, length: { minimum: 5, maximum: 100 }, uniqueness: true
|
|
24
|
+
|
|
25
|
+
# @!attribute state
|
|
26
|
+
# @return ['standard', 'default'] the tenant's status.
|
|
27
|
+
# - 'default' --- tenant is marked as default (only one tenant may be default)
|
|
28
|
+
# - 'standard' --- tenant is marked as standard
|
|
29
|
+
enum state: { standard: 0, default: 1 }
|
|
30
|
+
|
|
31
|
+
has_many :tenant_systems, class_name: 'Anoubis::Tenant::TenantSystem'
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# Is called before validation when new tenant is being created. If it's a first tenant then it sets {#ident}
|
|
35
|
+
# value to 'sys'
|
|
36
|
+
def before_validation_tenant_create
|
|
37
|
+
if self.id
|
|
38
|
+
if self.id == 1
|
|
39
|
+
self.ident = 'sys'
|
|
40
|
+
return true
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Is called before validation when tenant is being updated. Prevents the changing {#ident} value.
|
|
47
|
+
def before_validation_tenant_update
|
|
48
|
+
if self.id == 1 && self.ident != self.ident_was
|
|
49
|
+
errors.add(:ident, I18n.t('anubis.tenants.errors.cant_change_ident'))
|
|
50
|
+
throw(:abort, __method__)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
# Is called after new tenant was created. Adds access for this tenant to main system with id 1.
|
|
56
|
+
def after_create_tenant
|
|
57
|
+
Anoubis::Tenant::TenantSystem.find_or_create_by(tenant_id: self.id, system_id: 1) if self.id != 1
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
##
|
|
61
|
+
# Is called after tenant had been updated. If {#ident} value had been changed then procedure updates
|
|
62
|
+
# every {Anoubis::User#login} value.
|
|
63
|
+
# Also if current tenant {#state} value had been set as 'default', then procedure sets {#state}
|
|
64
|
+
# value of all other tenants as 'standard'.
|
|
65
|
+
def after_update_tenant
|
|
66
|
+
if self.ident_was != self.ident
|
|
67
|
+
self.update_users_login self.id, self.ident
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# If current tenant had been set as 'default', then sets all other tenants as 'standard'.
|
|
71
|
+
if self.state != self.state_was && self.state = 'default'
|
|
72
|
+
Anoubis::Tenant::Tenant.where(state: Anoubis::Tenant::Tenant.states[:default]).update_all(state: Anoubis::Tenant::Tenant.states[:standard])
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
##
|
|
77
|
+
# Is called before tenant will be stored in database. Changes {#ident} value to lower case.
|
|
78
|
+
def before_save_tenant
|
|
79
|
+
self.ident = self.ident.downcase if self.ident
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# Is called before tenant will be deleted from database. Checks the ability to destroy a tenant.
|
|
84
|
+
def before_destroy_tenant
|
|
85
|
+
if self.id == 1
|
|
86
|
+
errors.add(:base, I18n.t('anubis.tenants.errors.cant_destroy'))
|
|
87
|
+
throw(:abort, __method__)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
if !can_destroy?
|
|
91
|
+
errors.add(:base, I18n.t('anubis.tenants.errors.has_childs'))
|
|
92
|
+
throw(:abort, __method__)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
##
|
|
97
|
+
# Changes every {User#login} value based on {#ident} value. Procedure makes direct update
|
|
98
|
+
# in database and doesn't call any callbacks of {Anoubis::Tenant::User} model.
|
|
99
|
+
# @param id [Integer] user unique identifier
|
|
100
|
+
# @param ident [String] new tenant identifier
|
|
101
|
+
def update_users_login (id, ident)
|
|
102
|
+
query = <<-SQL
|
|
103
|
+
UPDATE users SET users.login = CONCAT(users.email, '.#{ident}') WHERE users.tenant_id = #{id}
|
|
104
|
+
SQL
|
|
105
|
+
Anoubis::Tenant::User.connection.execute query
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Model for links Tenant and System models
|
|
3
|
+
class Anoubis::Tenant::TenantSystem < ApplicationRecord
|
|
4
|
+
self.table_name = 'tenant_systems'
|
|
5
|
+
|
|
6
|
+
before_update :before_update_tenant_system
|
|
7
|
+
|
|
8
|
+
belongs_to :tenant, class_name: 'Anoubis::Tenant::Tenant'
|
|
9
|
+
validates :tenant, presence: true, uniqueness: { scope: [:system_id] }
|
|
10
|
+
belongs_to :system, class_name: 'Anoubis::Tenant::System'
|
|
11
|
+
validates :system, presence: true, uniqueness: { scope: [:tenant_id] }
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Checks before update data in model. Prevents from changing element data
|
|
15
|
+
def before_update_tenant_system
|
|
16
|
+
self.tenant_id = self.tenant_id_was if self.tenant_id_changed?
|
|
17
|
+
self.system_id = self.system_id_was if self.system_id_changed?
|
|
18
|
+
end
|
|
19
|
+
end
|