browsercms-artirix 4.0.0.rc1.art4 → 4.0.1.1

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/cms/attachments_controller.rb +1 -1
  3. data/app/controllers/cms/cas_sessions_controller.rb +13 -0
  4. data/app/controllers/cms/sections_controller.rb +1 -1
  5. data/app/controllers/cms/users_controller.rb +1 -1
  6. data/app/helpers/cms/sites/authentication_helper.rb +1 -0
  7. data/app/helpers/cms/sites/devise_shim_helper.rb +1 -1
  8. data/app/models/cms/default_user.rb +6 -0
  9. data/app/models/cms/external_user.rb +1 -1
  10. data/app/models/cms/group.rb +7 -3
  11. data/app/models/cms/guest_user.rb +2 -41
  12. data/app/models/cms/permission.rb +4 -0
  13. data/app/models/cms/persistent_user.rb +17 -110
  14. data/app/models/cms/section.rb +10 -6
  15. data/app/models/cms/user.rb +2 -2
  16. data/app/models/cms/user_group_membership.rb +2 -2
  17. data/app/portlets/login_portlet.rb +2 -2
  18. data/config/routes.rb +33 -34
  19. data/db/browsercms.seeds.rb +7 -4
  20. data/doc/release_notes.md +3 -3
  21. data/lib/browsercms.rb +2 -0
  22. data/lib/cms/authentication/controller.rb +8 -5
  23. data/lib/cms/authentication/test_password_strategy.rb +1 -1
  24. data/lib/cms/behaviors.rb +15 -0
  25. data/lib/cms/behaviors/attaching.rb +1 -1
  26. data/lib/cms/behaviors/userstamping.rb +1 -1
  27. data/lib/cms/behaviors/versioning.rb +3 -4
  28. data/lib/cms/configuration.rb +108 -10
  29. data/lib/cms/configuration/devise.rb +75 -4
  30. data/lib/cms/engine.rb +55 -2
  31. data/lib/cms/users_service.rb +26 -190
  32. data/lib/cms/users_service/cms_login_user_controller_concern.rb +19 -0
  33. data/lib/cms/users_service/cms_user_compatibility_module.rb +137 -0
  34. data/lib/cms/users_service/guest_user_module.rb +42 -0
  35. data/lib/cms/users_service/user_groups_by_codes_module.rb +13 -0
  36. data/lib/cms/users_service/users_factory.rb +50 -0
  37. data/lib/cms/version.rb +1 -1
  38. data/lib/generators/browser_cms/demo_site/templates/demo.seeds.rb +1 -1
  39. metadata +27 -6
@@ -1,208 +1,44 @@
1
- class Cms::UsersService
1
+ require 'cms/users_service/cms_login_user_controller_concern'
2
+ require 'cms/users_service/users_factory'
3
+ require 'cms/users_service/guest_user_module'
4
+ require 'cms/users_service/cms_user_compatibility_module'
5
+ require 'cms/users_service/user_groups_by_codes_module'
2
6
 
3
- GUEST_LOGIN = 'guest'
4
- GUEST_NAME = 'Anonymous'
7
+ module Cms
8
+ module UsersService
5
9
 
6
- # dirty trick needed for compatibility issues
7
- # https://amitrmohanty.wordpress.com/2014/01/20/how-to-get-current_user-in-model-and-observer-rails/
8
- def self.current
9
- Thread.current[:cms_user]
10
- end
11
-
12
- def self.current=(user)
13
- Thread.current[:cms_user] = user
14
- end
15
-
16
- class << self
17
- delegate :use_user, :use_guest_user, :guest_user, to: :service
18
- end
19
-
20
- def self.service
21
- @service || reload_service
22
- end
23
-
24
- def self.reload_service
25
- @service = new
26
- end
27
-
28
- def use_user(login)
29
- self.class.current = user(login)
30
- end
31
-
32
- def use_guest_user
33
- self.class.current = guest_user
34
- end
35
-
36
- def guest_user
37
- guest_user.tap { |u| extend_user u }
38
- end
39
-
40
- private
41
- def user(login)
42
- load_user(login).tap do |user|
43
- extend_user(user)
44
- end
45
- end
46
-
47
- def extend_user(user)
48
- user.send :extend, CmsUserCompatibilityModule unless user.try :cms_user_compatible?
49
- end
50
-
51
- def load_user(login)
52
- Cms.user_class.where(Cms.user_key_field => login).first!
53
- end
54
-
55
- def load_guest_user
56
- params = {
57
- Cms.user_key_field => GUEST_LOGIN,
58
- Cms.user_name_field => GUEST_NAME
59
- }
60
-
61
- Cms.user_class.new(params).tap do |guest_user|
62
- guest_user.send :extend, GuestUserModule
63
- end
64
- end
65
-
66
- class GuestUserModule
67
- def guest?
68
- true
69
- end
70
-
71
- def readonly?
72
- true
73
- end
74
-
75
- def cms_access?
76
- false
77
- end
78
- end
79
-
80
- module CmsUserCompatibilityModule
81
-
82
- def cms_user_compatible?
83
- true
84
- end
85
-
86
- def enable_able?
87
- false
88
- end
89
-
90
- def disable_able?
91
- false
92
- end
93
-
94
- def password_changeable?
95
- false
96
- end
97
-
98
- def expired?
99
- false
100
- end
101
-
102
- # add expected columns
103
- def self.extended(base)
104
- unless base.respond_to? :login
105
- base.send :alias_method, :login, Cms.user_key_field.to_sym
106
- end
107
-
108
- unless base.respond_to? :full_name
109
- base.send :alias_method, :full_name, Cms.user_name_field.to_sym
110
- end
111
- end
112
-
113
- def guest?
114
- false
115
- end
116
-
117
- # COLUMN based
118
-
119
- def full_name_with_login
120
- "#{full_name} (#{login})"
121
- end
122
-
123
- def full_name_or_login
124
- if full_name.strip.present?
125
- full_name
126
- else
127
- login
128
- end
129
- end
130
-
131
-
132
- def permissions
133
- @permissions ||= Cms::Permission.where(["#{self.class.table_name}.id = ?", id]).includes({ :groups => :users }).references(:users)
134
- end
135
-
136
- def viewable_sections
137
- @viewable_sections ||= Cms::Section.where(["#{self.class.table_name}.id = ?", id]).includes(:groups => :users).references(:users)
138
- end
139
-
140
- def modifiable_sections
141
- @modifiable_sections ||= Cms::Section.where(["#{self.class.table_name}.id = ? and #{GroupType.table_name}.cms_access = ?", id, true]).includes(:groups => [:group_type, :users]).references(:users, :groups)
142
- end
10
+ GUEST_NAME = 'Anonymous User'
11
+ GROUP_CMS_ADMIN = 'cms-admin'
12
+ GROUP_CONTENT_EDITOR = 'content-editor'
143
13
 
144
- # Expects a list of names of Permissions
145
- # true if the user has any of the permissions
146
- def able_to?(*required_permissions)
147
- perms = required_permissions.map(&:to_sym)
148
- permissions.any? do |p|
149
- perms.include?(p.name.to_sym)
150
- end
14
+ # dirty trick needed for compatibility issues
15
+ # https://amitrmohanty.wordpress.com/2014/01/20/how-to-get-current_user-in-model-and-observer-rails/
16
+ def self.current
17
+ Thread.current[:cms_user]
151
18
  end
152
19
 
153
- # Determine if this user has permission to view the specific object. Permissions
154
- # are always tied to a specific section. This method can take different input parameters
155
- # and will attempt to determine the relevant section to check.
156
- # Expects object to be of type:
157
- # 1. Section - Will check the user's groups to see if any of those groups can view this section.
158
- # 2. Path - Will look up the section based on the path, then check it. (Note that section paths are not currently unique, so this will check the first one it finds).
159
- # 3. Other - Assumes it has a section attribute and will call that and check the return value.
160
- #
161
- # Returns: true if the user can view this object, false otherwise.
162
- # Raises: ActiveRecord::RecordNotFound if a path to a not existent section is passed in.
163
- def able_to_view?(object)
164
- section = object
165
- if object.is_a?(String)
166
- section = Cms::Section.find_by_path(object)
167
- raise ActiveRecord::RecordNotFound.new("Could not find section with path = '#{object}'") unless section
168
- elsif !object.is_a?(Cms::Section)
169
- section = object.parent
170
- end
171
- viewable_sections.include?(section) || cms_access?
20
+ def self.current=(user)
21
+ Thread.current[:cms_user] = user
172
22
  end
173
23
 
174
- def able_to_modify?(object)
175
- case object
176
- when Cms::Section
177
- modifiable_sections.include?(object)
178
- when Cms::Page, Cms::Link
179
- modifiable_sections.include?(object.section)
180
- else
181
- if object.class.respond_to?(:connectable?) && object.class.connectable?
182
- object.connected_pages.all? { |page| able_to_modify?(page) }
183
- else
184
- true
185
- end
186
- end
24
+ def self.use_user_by_login(login, group_codes: nil)
25
+ use_user UsersFactory.user(login, group_codes: group_codes)
187
26
  end
188
27
 
189
- # Expects node to be a Section, Page or Link
190
- # Returns true if the specified node, or any of its ancestor sections, is editable by any of
191
- # the user's 'CMS User' groups.
192
- def able_to_edit?(object)
193
- able_to?(:edit_content) && able_to_modify?(object)
28
+ def self.use_user(user, group_codes: nil)
29
+ self.current = UsersFactory.extend_user(user, group_codes: group_codes)
194
30
  end
195
31
 
196
- def able_to_publish?(object)
197
- able_to?(:publish_content) && able_to_modify?(object)
32
+ def self.use_guest_user
33
+ self.current = UsersFactory.extend_user(UsersFactory.guest_user)
198
34
  end
199
35
 
200
- def able_to_edit_or_publish_content?
201
- able_to?(:edit_content, :publish_content)
36
+ def self.controller_module
37
+ CmsLoginUserControllerConcern
202
38
  end
203
39
 
204
- def cms_access?
205
- groups.cms_access.count > 0
40
+ def self.user_compatibility_module
41
+ CmsUserCompatibilityModule
206
42
  end
207
43
  end
208
44
  end
@@ -0,0 +1,19 @@
1
+ module Cms
2
+ module UsersService
3
+ module CmsLoginUserControllerConcern
4
+ extend ActiveSupport::Concern
5
+
6
+ def cms_login_user_by_login(login, group_codes: nil)
7
+ Cms::UsersService.use_user_by_login login, group_codes: group_codes
8
+
9
+ sign_in :cms_user, Cms::UsersService.current
10
+ end
11
+
12
+ def cms_login_user_by_user(user, group_codes: nil)
13
+ Cms::UsersService.use_user user, group_codes: group_codes
14
+
15
+ sign_in :cms_user, Cms::UsersService.current
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,137 @@
1
+ module Cms
2
+ module UsersService
3
+ module CmsUserCompatibilityModule
4
+
5
+ def cms_user_compatible?
6
+ true
7
+ end
8
+
9
+ def enable_able?
10
+ false
11
+ end
12
+
13
+ def disable_able?
14
+ false
15
+ end
16
+
17
+ def password_changeable?
18
+ false
19
+ end
20
+
21
+ def expired?
22
+ false
23
+ end
24
+
25
+ # add expected columns to objects
26
+ def self.extended(base)
27
+ unless base.respond_to? :login
28
+ base.send :alias_method, :login, Cms.user_key_field.to_sym
29
+ end
30
+
31
+ unless base.respond_to? :full_name
32
+ base.send :alias_method, :full_name, Cms.user_name_field.to_sym
33
+ end
34
+ end
35
+
36
+ def guest?
37
+ false
38
+ end
39
+
40
+ # COLUMN based
41
+
42
+ def full_name_with_login
43
+ "#{full_name} (#{login})"
44
+ end
45
+
46
+ def full_name_or_login
47
+ if full_name.strip.present?
48
+ full_name
49
+ else
50
+ login
51
+ end
52
+ end
53
+
54
+ # Permissions
55
+
56
+ def groups_with_cms_access
57
+ groups.cms_access
58
+ end
59
+
60
+ def permissions
61
+ @permissions ||= Cms::Permission.by_group_ids groups.map(&:id)
62
+ end
63
+
64
+ def viewable_sections
65
+ @viewable_sections ||= Cms::Section.by_group_ids groups.map(&:id)
66
+ end
67
+
68
+ def modifiable_sections
69
+ @modifiable_sections ||= Cms::Section.by_group_ids groups_with_cms_access.map(&:id)
70
+ end
71
+
72
+ # Expects a list of codes of Permissions
73
+ # true if the user has any of the permissions
74
+ def able_to?(*required_permissions)
75
+ perms = required_permissions.map(&:to_sym)
76
+ permissions.any? do |p|
77
+ perms.include?(p.name.to_sym)
78
+ end
79
+ end
80
+
81
+ # Determine if this user has permission to view the specific object. Permissions
82
+ # are always tied to a specific section. This method can take different input parameters
83
+ # and will attempt to determine the relevant section to check.
84
+ # Expects object to be of type:
85
+ # 1. Section - Will check the user's groups to see if any of those groups can view this section.
86
+ # 2. Path - Will look up the section based on the path, then check it. (Note that section paths are not currently unique, so this will check the first one it finds).
87
+ # 3. Other - Assumes it has a section attribute and will call that and check the return value.
88
+ #
89
+ # Returns: true if the user can view this object, false otherwise.
90
+ # Raises: ActiveRecord::RecordNotFound if a path to a not existent section is passed in.
91
+ def able_to_view?(object)
92
+ section = object
93
+ if object.is_a?(String)
94
+ section = Cms::Section.find_by_path(object)
95
+ raise ActiveRecord::RecordNotFound.new("Could not find section with path = '#{object}'") unless section
96
+ elsif !object.is_a?(Cms::Section)
97
+ section = object.parent
98
+ end
99
+ viewable_sections.include?(section) || cms_access?
100
+ end
101
+
102
+ def able_to_modify?(object)
103
+ case object
104
+ when Cms::Section
105
+ modifiable_sections.include?(object)
106
+ when Cms::Page, Cms::Link
107
+ modifiable_sections.include?(object.section)
108
+ else
109
+ if object.class.respond_to?(:connectable?) && object.class.connectable?
110
+ object.connected_pages.all? { |page| able_to_modify?(page) }
111
+ else
112
+ true
113
+ end
114
+ end
115
+ end
116
+
117
+ # Expects node to be a Section, Page or Link
118
+ # Returns true if the specified node, or any of its ancestor sections, is editable by any of
119
+ # the user's 'CMS User' groups.
120
+ def able_to_edit?(object)
121
+ able_to?(:edit_content) && able_to_modify?(object)
122
+ end
123
+
124
+ def able_to_publish?(object)
125
+ able_to?(:publish_content) && able_to_modify?(object)
126
+ end
127
+
128
+ def able_to_edit_or_publish_content?
129
+ able_to?(:edit_content, :publish_content)
130
+ end
131
+
132
+ def cms_access?
133
+ groups.cms_access.present?
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,42 @@
1
+ module Cms
2
+ module UsersService
3
+ module GuestUserModule
4
+ def guest?
5
+ true
6
+ end
7
+
8
+ def readonly?
9
+ true
10
+ end
11
+
12
+ def cms_access?
13
+ false
14
+ end
15
+
16
+ def groups
17
+ @groups ||= Cms::Group.guest_groups.includes(:permissions)
18
+ end
19
+
20
+ def group
21
+ groups.first
22
+ end
23
+
24
+ def able_to_edit?(_section)
25
+ false
26
+ end
27
+
28
+ #You shouldn't be able to save a guest user (but do not fail, as in original BrowserCMS)
29
+ def update_attribute(_name, _value)
30
+ false
31
+ end
32
+
33
+ def update_attributes(_attrs = {})
34
+ false
35
+ end
36
+
37
+ def save(_perform_validation = true)
38
+ false
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ module Cms
2
+ module UsersService
3
+
4
+ module UserGroupsByCodesModule
5
+ attr_accessor :group_codes
6
+
7
+ def groups
8
+ @groups ||= Cms::Group.with_code(group_codes).includes(:permissions)
9
+ end
10
+ end
11
+
12
+ end
13
+ end