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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +100 -92
  3. data/app/assets/images/admin/default_forgot_password.svg +1 -0
  4. data/app/assets/images/admin/default_reset_password.svg +1 -0
  5. data/app/assets/images/admin/default_safe_login.svg +1 -0
  6. data/app/assets/javascripts/admin.js +0 -1
  7. data/app/assets/javascripts/admin/modernizr.js +3 -409
  8. data/app/assets/stylesheets/admin/partials/_forms.scss +39 -0
  9. data/app/assets/stylesheets/admin/partials/_layout.scss +8 -0
  10. data/app/assets/stylesheets/admin/partials/_validations.scss +6 -13
  11. data/app/controllers/admin/assets_controller.rb +7 -0
  12. data/app/controllers/admin/preferences_controller.rb +1 -1
  13. data/app/controllers/admin/resource_controller.rb +6 -0
  14. data/app/controllers/admin/users_controller.rb +3 -2
  15. data/app/controllers/application_controller.rb +5 -7
  16. data/app/controllers/site_controller.rb +2 -1
  17. data/app/controllers/social_mailer_controller.rb +2 -1
  18. data/app/models/legacy_user.rb +6 -0
  19. data/app/models/user.rb +39 -68
  20. data/app/models/user_action_observer.rb +4 -2
  21. data/app/views/admin/configuration/show.html.haml +2 -7
  22. data/app/views/admin/layouts/_site_chooser.html.haml +1 -1
  23. data/app/views/admin/pages/_node.html.haml +2 -2
  24. data/app/views/admin/preferences/edit.html.haml +9 -14
  25. data/app/views/admin/users/_form.html.haml +8 -15
  26. data/app/views/admin/users/index.html.haml +0 -1
  27. data/app/views/devise/passwords/edit.html.haml +23 -0
  28. data/app/views/devise/passwords/new.html.haml +14 -0
  29. data/app/views/devise/sessions/new.html.haml +25 -0
  30. data/app/views/devise/shared/_links.html.haml +16 -0
  31. data/app/views/layouts/application.html.haml +1 -1
  32. data/config/application.rb +1 -0
  33. data/config/initializers/devise.rb +310 -0
  34. data/config/routes.rb +6 -10
  35. data/db/migrate/20200117141251_create_admin_users.rb +51 -0
  36. data/lib/generators/extension_controller/templates/controller.rb +1 -1
  37. data/lib/login_system.rb +40 -44
  38. data/lib/tasks/upgrade_to_devise.rake +22 -0
  39. data/lib/trusty_cms.rb +1 -1
  40. data/lib/trusty_cms/admin_ui.rb +3 -3
  41. data/lib/trusty_cms/engine.rb +2 -0
  42. data/lib/trusty_cms/setup.rb +0 -1
  43. data/trusty_cms.gemspec +1 -0
  44. data/vendor/extensions/clipped-extension/clipped_extension.rb +0 -2
  45. data/vendor/extensions/multi-site-extension/lib/multi_site/site_chooser_helper.rb +1 -1
  46. data/vendor/extensions/snippets-extension/snippets_extension.rb +0 -2
  47. metadata +27 -8
  48. data/app/assets/javascripts/admin/cookie.js +0 -80
  49. data/app/controllers/admin/password_resets_controller.rb +0 -31
  50. data/app/controllers/admin/welcome_controller.rb +0 -47
  51. data/app/views/admin/password_resets/edit.html.haml +0 -27
  52. data/app/views/admin/password_resets/new.html.haml +0 -12
  53. 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 {
@@ -11,3 +11,11 @@ body.single_form {
11
11
  }
12
12
  }
13
13
  }
14
+
15
+ body.reversed.login_form {
16
+ background-color: #fff;
17
+ }
18
+
19
+ body.reversed.password_form {
20
+ background-color: #fff;
21
+ }
@@ -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
- line-height: 1.4;
9
- background-color: #cc0000;
10
- color: white;
11
- padding: 3px 6px;
12
- margin: 0 0 0 6px;
13
- background-color: #b30000;
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(:name, :email, :login, :password, :password_confirmation, :locale)
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
- annouce_cannot_remove_self_from_admin_role
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 annouce_cannot_remove_self_from_admin_role
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
 
@@ -0,0 +1,6 @@
1
+ class LegacyUser < ActiveRecord::Base
2
+ self.table_name = 'users'
3
+
4
+ # this is a legacy class
5
+ # this table formally held user information for when TrustyCMS had a handwritten authentication system
6
+ end
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
- # Default Order
7
- default_scope {order("name")}
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
- validates_confirmation_of :password, :if => :confirm_password?
9
+ alias_attribute :created_by_id, :id
17
10
 
18
- validates_presence_of :name, :login
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
- validates_length_of :name, :maximum => 100, :allow_nil => true
23
- validates_length_of :login, :within => 3..40, :allow_nil => true
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
- attr_writer :confirm_password
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
- respond_to?("#{role}?") && send("#{role}?")
31
- end
32
-
33
- def sha1(phrase)
34
- Digest::SHA1.hexdigest("--#{salt}--#{phrase}--")
35
- end
36
-
37
- def self.authenticate(login_or_email, password)
38
- user = where(["login = ? OR email = ?", login_or_email, login_or_email]).first
39
- user if user && user.authenticated?(password)
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 confirm_password?
51
- @confirm_password
35
+ def admin?
36
+ self.admin
52
37
  end
53
38
 
54
- def remember_me
55
- update_attribute(:session_token, sha1(Time.now + TrustyCms::Config['session_timeout'].to_i)) unless self.session_token?
39
+ def designer?
40
+ self.designer
56
41
  end
57
42
 
58
- def forget_me
59
- update_attribute(:session_token, nil)
43
+ def content_editor?
44
+ self.content_editor
60
45
  end
61
46
 
62
- def send_password_reset
63
- generate_token(:password_reset_token)
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
- private
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 validate_length_of_password?
75
- new_record? or not password.to_s.empty?
55
+ def password_required?
56
+ return false if skip_password_validation
57
+ super
76
58
  end
77
59
 
78
- before_create :encrypt_password
79
- def encrypt_password
80
- self.salt = Digest::SHA1.hexdigest("--#{Time.now}--#{login}--sweet harmonious biscuits--")
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
- before_update :encrypt_password_unless_empty_or_unchanged
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"), "/admin/preferences", :method => :get
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
@@ -18,5 +18,5 @@
18
18
  - unless simple
19
19
  %td.actions
20
20
  = page.add_child_option
21
- - if current_user.has_role?('admin')
22
- = page.remove_option
21
+ - if current_user.admin?
22
+ = page.remove_option
@@ -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.edit_name do
16
+ - form.edit_first_name do
17
17
  %p
18
- = f.label :name, t("name")
19
- = f.text_field :name, :class => "textbox", :size => 32, :maxlength => 100
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'), admin_url, class: 'alt'
39
+ = link_to t('cancel'), admin_pages_url, class: 'alt'