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.
- checksums.yaml +4 -4
- data/app/controllers/cms/attachments_controller.rb +1 -1
- data/app/controllers/cms/cas_sessions_controller.rb +13 -0
- data/app/controllers/cms/sections_controller.rb +1 -1
- data/app/controllers/cms/users_controller.rb +1 -1
- data/app/helpers/cms/sites/authentication_helper.rb +1 -0
- data/app/helpers/cms/sites/devise_shim_helper.rb +1 -1
- data/app/models/cms/default_user.rb +6 -0
- data/app/models/cms/external_user.rb +1 -1
- data/app/models/cms/group.rb +7 -3
- data/app/models/cms/guest_user.rb +2 -41
- data/app/models/cms/permission.rb +4 -0
- data/app/models/cms/persistent_user.rb +17 -110
- data/app/models/cms/section.rb +10 -6
- data/app/models/cms/user.rb +2 -2
- data/app/models/cms/user_group_membership.rb +2 -2
- data/app/portlets/login_portlet.rb +2 -2
- data/config/routes.rb +33 -34
- data/db/browsercms.seeds.rb +7 -4
- data/doc/release_notes.md +3 -3
- data/lib/browsercms.rb +2 -0
- data/lib/cms/authentication/controller.rb +8 -5
- data/lib/cms/authentication/test_password_strategy.rb +1 -1
- data/lib/cms/behaviors.rb +15 -0
- data/lib/cms/behaviors/attaching.rb +1 -1
- data/lib/cms/behaviors/userstamping.rb +1 -1
- data/lib/cms/behaviors/versioning.rb +3 -4
- data/lib/cms/configuration.rb +108 -10
- data/lib/cms/configuration/devise.rb +75 -4
- data/lib/cms/engine.rb +55 -2
- data/lib/cms/users_service.rb +26 -190
- data/lib/cms/users_service/cms_login_user_controller_concern.rb +19 -0
- data/lib/cms/users_service/cms_user_compatibility_module.rb +137 -0
- data/lib/cms/users_service/guest_user_module.rb +42 -0
- data/lib/cms/users_service/user_groups_by_codes_module.rb +13 -0
- data/lib/cms/users_service/users_factory.rb +50 -0
- data/lib/cms/version.rb +1 -1
- data/lib/generators/browser_cms/demo_site/templates/demo.seeds.rb +1 -1
- metadata +27 -6
data/lib/cms/users_service.rb
CHANGED
@@ -1,208 +1,44 @@
|
|
1
|
-
|
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
|
-
|
4
|
-
|
7
|
+
module Cms
|
8
|
+
module UsersService
|
5
9
|
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
#
|
145
|
-
#
|
146
|
-
def
|
147
|
-
|
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
|
-
|
154
|
-
|
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
|
175
|
-
|
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
|
-
|
190
|
-
|
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
|
197
|
-
|
32
|
+
def self.use_guest_user
|
33
|
+
self.current = UsersFactory.extend_user(UsersFactory.guest_user)
|
198
34
|
end
|
199
35
|
|
200
|
-
def
|
201
|
-
|
36
|
+
def self.controller_module
|
37
|
+
CmsLoginUserControllerConcern
|
202
38
|
end
|
203
39
|
|
204
|
-
def
|
205
|
-
|
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
|