browsercms-artirix 4.0.0.rc1.art4 → 4.0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|