trusty-cms 3.8.0 → 3.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +100 -92
- data/app/assets/images/admin/default_forgot_password.svg +1 -0
- data/app/assets/images/admin/default_reset_password.svg +1 -0
- data/app/assets/images/admin/default_safe_login.svg +1 -0
- data/app/assets/javascripts/admin.js +0 -1
- data/app/assets/javascripts/admin/modernizr.js +3 -409
- data/app/assets/stylesheets/admin/partials/_forms.scss +39 -0
- data/app/assets/stylesheets/admin/partials/_layout.scss +8 -0
- data/app/assets/stylesheets/admin/partials/_validations.scss +6 -13
- data/app/controllers/admin/assets_controller.rb +7 -0
- data/app/controllers/admin/preferences_controller.rb +1 -1
- data/app/controllers/admin/resource_controller.rb +6 -0
- data/app/controllers/admin/users_controller.rb +3 -2
- data/app/controllers/application_controller.rb +5 -7
- data/app/controllers/site_controller.rb +2 -1
- data/app/controllers/social_mailer_controller.rb +2 -1
- data/app/models/legacy_user.rb +6 -0
- data/app/models/user.rb +39 -68
- data/app/models/user_action_observer.rb +4 -2
- data/app/views/admin/configuration/show.html.haml +2 -7
- data/app/views/admin/layouts/_site_chooser.html.haml +1 -1
- data/app/views/admin/pages/_node.html.haml +2 -2
- data/app/views/admin/preferences/edit.html.haml +9 -14
- data/app/views/admin/users/_form.html.haml +8 -15
- data/app/views/admin/users/index.html.haml +0 -1
- data/app/views/devise/passwords/edit.html.haml +23 -0
- data/app/views/devise/passwords/new.html.haml +14 -0
- data/app/views/devise/sessions/new.html.haml +25 -0
- data/app/views/devise/shared/_links.html.haml +16 -0
- data/app/views/layouts/application.html.haml +1 -1
- data/config/application.rb +1 -0
- data/config/initializers/devise.rb +310 -0
- data/config/routes.rb +6 -10
- data/db/migrate/20200117141251_create_admin_users.rb +51 -0
- data/lib/generators/extension_controller/templates/controller.rb +1 -1
- data/lib/login_system.rb +40 -44
- data/lib/tasks/upgrade_to_devise.rake +22 -0
- data/lib/trusty_cms.rb +1 -1
- data/lib/trusty_cms/admin_ui.rb +3 -3
- data/lib/trusty_cms/engine.rb +2 -0
- data/lib/trusty_cms/setup.rb +0 -1
- data/trusty_cms.gemspec +1 -0
- data/vendor/extensions/clipped-extension/clipped_extension.rb +0 -2
- data/vendor/extensions/multi-site-extension/lib/multi_site/site_chooser_helper.rb +1 -1
- data/vendor/extensions/snippets-extension/snippets_extension.rb +0 -2
- metadata +27 -8
- data/app/assets/javascripts/admin/cookie.js +0 -80
- data/app/controllers/admin/password_resets_controller.rb +0 -31
- data/app/controllers/admin/welcome_controller.rb +0 -47
- data/app/views/admin/password_resets/edit.html.haml +0 -27
- data/app/views/admin/password_resets/new.html.haml +0 -12
- data/app/views/password_mailer/password_reset.html.haml +0 -8
@@ -11,6 +11,45 @@
|
|
11
11
|
}
|
12
12
|
}
|
13
13
|
|
14
|
+
.login-form-content {
|
15
|
+
display: flex;
|
16
|
+
flex-flow: wrap;
|
17
|
+
justify-content: center;
|
18
|
+
margin-top: 5em;
|
19
|
+
.visual {
|
20
|
+
img {
|
21
|
+
height: 300px;
|
22
|
+
float: right;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
.login {
|
27
|
+
form {
|
28
|
+
padding: 1em;
|
29
|
+
.field #user_email, .field #user_password, .field #user_password_confirmation {
|
30
|
+
padding: 1em;
|
31
|
+
margin-bottom: 1em;
|
32
|
+
width: 200px;
|
33
|
+
}
|
34
|
+
|
35
|
+
input[type='submit'] {
|
36
|
+
border-radius: 0;
|
37
|
+
background-color: #3c3a4b;
|
38
|
+
|
39
|
+
&:hover {
|
40
|
+
color: #fff;
|
41
|
+
cursor: pointer;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
.error {
|
48
|
+
background-color: #f8d7da;
|
49
|
+
color: #721c24;
|
50
|
+
padding: 1em;
|
51
|
+
}
|
52
|
+
|
14
53
|
#content {
|
15
54
|
form {
|
16
55
|
p {
|
@@ -1,18 +1,11 @@
|
|
1
1
|
#content {
|
2
|
-
span.error-with-field {
|
3
|
-
input, select {
|
4
|
-
background: #f3c2c2;
|
5
|
-
}
|
6
|
-
}
|
7
2
|
span.error {
|
8
|
-
|
9
|
-
|
10
|
-
color:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
border-radius: 5px;
|
15
|
-
box-shadow: 0 5px #333;
|
3
|
+
display: block;
|
4
|
+
margin: 1em 0;
|
5
|
+
background-color: #f8d7da;
|
6
|
+
color: #721c24;
|
7
|
+
padding: 1em;
|
8
|
+
font-size: 1em;
|
16
9
|
a.closer {
|
17
10
|
margin-left: 10px;
|
18
11
|
color: #ffcccc;
|
@@ -38,6 +38,7 @@ class Admin::AssetsController < Admin::ResourceController
|
|
38
38
|
else
|
39
39
|
uploaded_asset = compress(uploaded_asset) if $kraken.api_key.present? && COMPRESS_FILE_TYPE.include?(uploaded_asset.content_type) && compress
|
40
40
|
@asset = Asset.create(:asset => uploaded_asset, :caption => asset_params[:asset][:caption])
|
41
|
+
set_owner_or_editor
|
41
42
|
if params[:for_attachment]
|
42
43
|
@page = Page.find_by_id(params[:page_id]) || Page.new
|
43
44
|
@page_attachments << @page_attachment = @asset.page_attachments.build(:page => @page)
|
@@ -81,6 +82,12 @@ private
|
|
81
82
|
uploaded_asset
|
82
83
|
end
|
83
84
|
|
85
|
+
def set_owner_or_editor
|
86
|
+
@asset.created_by_id = current_user.id
|
87
|
+
@asset.updated_by_id = current_user.id
|
88
|
+
@asset.save! if @asset.id.present?
|
89
|
+
end
|
90
|
+
|
84
91
|
def asset_params
|
85
92
|
params.permit(:id, :for_attachment, :asset => [:caption, :for_attachment, :asset => []])
|
86
93
|
end
|
@@ -28,6 +28,6 @@ class Admin::PreferencesController < ApplicationController
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def preferences_params
|
31
|
-
params.require(:user).permit(:
|
31
|
+
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :locale)
|
32
32
|
end
|
33
33
|
end
|
@@ -7,6 +7,7 @@ class Admin::ResourceController < ApplicationController
|
|
7
7
|
before_action :never_cache
|
8
8
|
before_action :load_models, :only => :index
|
9
9
|
before_action :load_model, :only => [:new, :create, :edit, :update, :remove, :destroy]
|
10
|
+
before_action :set_owner_or_editor, :only => [:new, :create, :update]
|
10
11
|
after_action :clear_model_cache, :only => [:create, :update, :destroy]
|
11
12
|
|
12
13
|
cattr_reader :paginated
|
@@ -134,6 +135,11 @@ class Admin::ResourceController < ApplicationController
|
|
134
135
|
self.class.model_class
|
135
136
|
end
|
136
137
|
|
138
|
+
def set_owner_or_editor
|
139
|
+
self.model.created_by_id = current_user.id if self.model.id == nil
|
140
|
+
self.model.updated_by_id = current_user.id
|
141
|
+
end
|
142
|
+
|
137
143
|
def model
|
138
144
|
instance_variable_get("@#{model_symbol}") || load_model
|
139
145
|
end
|
@@ -15,8 +15,9 @@ class Admin::UsersController < Admin::ResourceController
|
|
15
15
|
user_params = params[model_symbol].permit!
|
16
16
|
if user_params && user_params['admin'] == false && model == current_user
|
17
17
|
user_params.delete('admin')
|
18
|
-
|
18
|
+
announce_cannot_remove_self_from_admin_role
|
19
19
|
end
|
20
|
+
model.skip_password_validation = true unless user_params[:password_confirmation].present?
|
20
21
|
model.update_attributes!(user_params)
|
21
22
|
response_for :update
|
22
23
|
end
|
@@ -34,7 +35,7 @@ class Admin::UsersController < Admin::ResourceController
|
|
34
35
|
flash[:error] = t('users_controller.cannot_delete_self')
|
35
36
|
end
|
36
37
|
|
37
|
-
def
|
38
|
+
def announce_cannot_remove_self_from_admin_role
|
38
39
|
flash[:error] = 'You cannot remove yourself from the admin role.'
|
39
40
|
end
|
40
41
|
end
|
@@ -3,12 +3,10 @@ require 'login_system'
|
|
3
3
|
|
4
4
|
class ApplicationController < ActionController::Base
|
5
5
|
include LoginSystem
|
6
|
-
# TODO: Add an ActionView::PathSet.new([paths]) for all extension view paths
|
7
6
|
prepend_view_path("#{TRUSTY_CMS_ROOT}/app/views")
|
8
7
|
|
9
8
|
protect_from_forgery with: :exception
|
10
|
-
|
11
|
-
before_action :set_current_user
|
9
|
+
before_action :authenticate_user!
|
12
10
|
before_action :set_timezone
|
13
11
|
before_action :set_user_locale
|
14
12
|
before_action :set_javascripts_and_stylesheets
|
@@ -25,6 +23,10 @@ class ApplicationController < ActionController::Base
|
|
25
23
|
@trusty_config = TrustyCms::Config
|
26
24
|
end
|
27
25
|
|
26
|
+
def after_sign_in_path_for(resource)
|
27
|
+
admin_pages_path
|
28
|
+
end
|
29
|
+
|
28
30
|
def template_name
|
29
31
|
case self.action_name
|
30
32
|
when 'index'
|
@@ -48,10 +50,6 @@ class ApplicationController < ActionController::Base
|
|
48
50
|
ActionMailer::Base.default_url_options[:host] = request.host_with_port
|
49
51
|
end
|
50
52
|
|
51
|
-
def set_current_user
|
52
|
-
UserActionObserver.instance.current_user = current_user
|
53
|
-
end
|
54
|
-
|
55
53
|
def set_user_locale
|
56
54
|
I18n.locale = current_user && !current_user.locale.blank? ? current_user.locale : TrustyCms::Config['default_locale']
|
57
55
|
end
|
@@ -2,7 +2,8 @@ require 'trusty_cms/pagination/controller'
|
|
2
2
|
class SiteController < ApplicationController
|
3
3
|
include TrustyCms::Pagination::Controller
|
4
4
|
|
5
|
-
no_login_required
|
5
|
+
# no_login_required
|
6
|
+
skip_before_action :authenticate_user!
|
6
7
|
|
7
8
|
def self.cache_timeout=(val)
|
8
9
|
TrustyCms::PageResponseCacheDirector.cache_timeout=(val)
|
@@ -1,7 +1,8 @@
|
|
1
1
|
class SocialMailerController < ApplicationController
|
2
2
|
include ShareLayouts::Controllers::ActionController
|
3
3
|
trusty_layout "default", {:only => :create_social_mail}
|
4
|
-
no_login_required
|
4
|
+
# no_login_required
|
5
|
+
skip_before_action :authenticate_user!
|
5
6
|
|
6
7
|
def create_social_mail
|
7
8
|
|
data/app/models/user.rb
CHANGED
@@ -1,96 +1,67 @@
|
|
1
|
-
require 'digest/sha1'
|
2
|
-
|
3
1
|
class User < ActiveRecord::Base
|
4
2
|
has_many :pages, :foreign_key => :created_by_id
|
3
|
+
self.table_name = 'admins'
|
5
4
|
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
# Associations
|
10
|
-
belongs_to :created_by, :class_name => 'User'
|
11
|
-
belongs_to :updated_by, :class_name => 'User'
|
12
|
-
|
13
|
-
# Validations
|
14
|
-
validates_uniqueness_of :login
|
5
|
+
# :confirmable, :lockable, :timeoutable and :omniauthable
|
6
|
+
devise :database_authenticatable, :registerable,
|
7
|
+
:recoverable, :rememberable, :trackable, :validatable
|
15
8
|
|
16
|
-
|
9
|
+
alias_attribute :created_by_id, :id
|
17
10
|
|
18
|
-
|
19
|
-
validates_presence_of :password, :password_confirmation, :if => :new_record?
|
11
|
+
attr_accessor :skip_password_validation
|
20
12
|
|
13
|
+
validate :password_complexity
|
21
14
|
|
22
|
-
|
23
|
-
|
24
|
-
validates_length_of :password, :within => 5..40, :allow_nil => true, :if => :validate_length_of_password?
|
25
|
-
validates_length_of :email, :maximum => 255, :allow_nil => true
|
15
|
+
# Default Order
|
16
|
+
default_scope {order('last_name')}
|
26
17
|
|
27
|
-
|
18
|
+
# Associations
|
19
|
+
belongs_to :created_by, :class_name => 'User'
|
20
|
+
belongs_to :updated_by, :class_name => 'User'
|
28
21
|
|
29
22
|
def has_role?(role)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
def authenticated?(password)
|
43
|
-
self.password == sha1(password)
|
44
|
-
end
|
45
|
-
|
46
|
-
def after_initialize
|
47
|
-
@confirm_password = true
|
23
|
+
case role
|
24
|
+
when :admin
|
25
|
+
self.admin?
|
26
|
+
when :designer
|
27
|
+
self.designer?
|
28
|
+
when :content_editor
|
29
|
+
self.content_editor?
|
30
|
+
else
|
31
|
+
false
|
32
|
+
end
|
48
33
|
end
|
49
34
|
|
50
|
-
def
|
51
|
-
|
35
|
+
def admin?
|
36
|
+
self.admin
|
52
37
|
end
|
53
38
|
|
54
|
-
def
|
55
|
-
|
39
|
+
def designer?
|
40
|
+
self.designer
|
56
41
|
end
|
57
42
|
|
58
|
-
def
|
59
|
-
|
43
|
+
def content_editor?
|
44
|
+
self.content_editor
|
60
45
|
end
|
61
46
|
|
62
|
-
def
|
63
|
-
|
64
|
-
update_attribute(:password_reset_sent_at, Time.zone.now)
|
65
|
-
PasswordMailer.password_reset(self).deliver_now
|
47
|
+
def locale
|
48
|
+
'en'
|
66
49
|
end
|
67
50
|
|
68
|
-
|
69
|
-
|
70
|
-
def generate_token(column)
|
71
|
-
self[column] = SecureRandom.urlsafe_base64 if User.exists?(column => self[column])
|
51
|
+
def name
|
52
|
+
"#{self.first_name} #{self.last_name}"
|
72
53
|
end
|
73
54
|
|
74
|
-
def
|
75
|
-
|
55
|
+
def password_required?
|
56
|
+
return false if skip_password_validation
|
57
|
+
super
|
76
58
|
end
|
77
59
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
self.password = sha1(password)
|
82
|
-
end
|
60
|
+
def password_complexity
|
61
|
+
# Regexp extracted from https://stackoverflow.com/questions/19605150/regex-for-password-must-contain-at-least-eight-characters-at-least-one-number-a
|
62
|
+
return if password.blank? || password =~ /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,70}$/
|
83
63
|
|
84
|
-
|
85
|
-
def encrypt_password_unless_empty_or_unchanged
|
86
|
-
user = self.class.find(self.id)
|
87
|
-
case password
|
88
|
-
when ''
|
89
|
-
self.password = user.password
|
90
|
-
when user.password
|
91
|
-
else
|
92
|
-
encrypt_password
|
93
|
-
end
|
64
|
+
errors.add :password, 'Complexity requirement not met. Length should be 12 characters and include: 1 uppercase, 1 lowercase, 1 digit and 1 special character.'
|
94
65
|
end
|
95
66
|
|
96
67
|
end
|
@@ -4,6 +4,7 @@ class UserActionObserver < ActiveRecord::Observer
|
|
4
4
|
def current_user=(user)
|
5
5
|
self.class.current_user = user
|
6
6
|
end
|
7
|
+
|
7
8
|
def self.current_user=(user)
|
8
9
|
Thread.current[:current_user] = user
|
9
10
|
end
|
@@ -11,15 +12,16 @@ class UserActionObserver < ActiveRecord::Observer
|
|
11
12
|
def current_user
|
12
13
|
self.class.current_user
|
13
14
|
end
|
15
|
+
|
14
16
|
def self.current_user
|
15
17
|
Thread.current[:current_user]
|
16
18
|
end
|
17
19
|
|
18
20
|
def before_create(model)
|
19
|
-
model.created_by = self.current_user
|
21
|
+
#model.created_by = self.current_user
|
20
22
|
end
|
21
23
|
|
22
24
|
def before_update(model)
|
23
|
-
model.updated_by = self.current_user
|
25
|
+
#model.updated_by = self.current_user
|
24
26
|
end
|
25
27
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
- user.preferences do
|
6
6
|
%h3
|
7
7
|
.actions
|
8
|
-
= button_to t("edit_preferences"),
|
8
|
+
= button_to t("edit_preferences"), edit_user_registration_path, :method => :get
|
9
9
|
= t('personal_preferences')
|
10
10
|
= image_tag(gravatar_url(@user.email, :size=>"64px"), :class=>"avatar", :width=>64, :height=>64, :alt=>"")
|
11
11
|
%p.ruled
|
@@ -18,11 +18,6 @@
|
|
18
18
|
= t('email_address')
|
19
19
|
%span.uri
|
20
20
|
= current_user.email
|
21
|
-
%p.ruled
|
22
|
-
%label
|
23
|
-
= t('login')
|
24
|
-
%span
|
25
|
-
= current_user.login
|
26
21
|
%p.ruled
|
27
22
|
%label
|
28
23
|
= t('password')
|
@@ -37,7 +32,7 @@
|
|
37
32
|
- render_region :trusty_config do |config|
|
38
33
|
- config.site do
|
39
34
|
%h3
|
40
|
-
- if admin?
|
35
|
+
- if current_user.admin?
|
41
36
|
.actions
|
42
37
|
= button_to t("edit_configuration"), edit_admin_configuration_path, :method => :get
|
43
38
|
Configuration
|
@@ -1,4 +1,4 @@
|
|
1
|
-
- if admin? && defined?(Site) && defined?(controller) && controller.sited_model? && controller.template_name == 'index' && Site.several?
|
1
|
+
- if current_user.admin? && defined?(Site) && defined?(controller) && controller.sited_model? && controller.template_name == 'index' && Site.several?
|
2
2
|
%nav#site_chooser
|
3
3
|
%ul#nav
|
4
4
|
%li
|
@@ -13,32 +13,27 @@
|
|
13
13
|
= render_region :form_top, :locals => {:f => f}
|
14
14
|
|
15
15
|
- render_region :form, :locals => {:f => f} do |form|
|
16
|
-
- form.
|
16
|
+
- form.edit_first_name do
|
17
17
|
%p
|
18
|
-
= f.label :name, t("
|
19
|
-
= f.text_field :
|
18
|
+
= f.label :name, t("first_name")
|
19
|
+
= f.text_field :first_name, :class => "textbox", :size => 32, :maxlength => 100
|
20
|
+
|
21
|
+
- form.edit_last_name do
|
22
|
+
%p
|
23
|
+
= f.label :name, t("last_name")
|
24
|
+
= f.text_field :last_name, :class => "textbox", :size => 32, :maxlength => 100
|
20
25
|
|
21
26
|
- form.edit_email do
|
22
27
|
%p
|
23
28
|
= f.label :email, t("email_address"), :class => "optional"
|
24
29
|
= f.text_field "email", :class => 'textbox', :size => 32, :maxlength => 255
|
25
30
|
|
26
|
-
- form.edit_username do
|
27
|
-
%p
|
28
|
-
= f.label :login, t("username")
|
29
|
-
= f.text_field "login", :class => "textbox", :size => 32, :maxlength => 40, :required => true
|
30
|
-
|
31
31
|
- form.edit_password do
|
32
32
|
= render "admin/users/password_fields", :f => f
|
33
33
|
|
34
|
-
- form.edit_locale do
|
35
|
-
%p
|
36
|
-
= f.label :locale, t('language')
|
37
|
-
= f.select "locale", available_locales_select
|
38
|
-
|
39
34
|
- render_region :form_bottom, :locals => {:f => f} do |form_bottom|
|
40
35
|
- form_bottom.edit_buttons do
|
41
36
|
.buttons
|
42
37
|
= save_model_button @user
|
43
38
|
= t('or')
|
44
|
-
= link_to t('cancel'),
|
39
|
+
= link_to t('cancel'), admin_pages_url, class: 'alt'
|