tb_core 1.4.5 → 1.5.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 (46) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +2 -2
  3. data/Rakefile +1 -1
  4. data/app/controllers/admin/password_resets_controller.rb +1 -0
  5. data/app/controllers/admin/roles_controller.rb +1 -3
  6. data/app/controllers/admin/settings_controller.rb +2 -2
  7. data/app/controllers/admin/setup_controller.rb +1 -1
  8. data/app/controllers/admin/users_controller.rb +4 -4
  9. data/app/controllers/concerns/tb_core/error_handling.rb +5 -4
  10. data/app/controllers/concerns/tb_core/redirection.rb +1 -0
  11. data/app/controllers/concerns/tb_core/user_authentication.rb +5 -0
  12. data/app/controllers/user_sessions_controller.rb +2 -2
  13. data/app/helpers/forgot_password_mailer_helper.rb +9 -0
  14. data/app/helpers/tb_core/application_helper.rb +17 -0
  15. data/app/mailers/tb_core_mailer.rb +2 -0
  16. data/app/models/concerns/tb_core/user_model.rb +55 -8
  17. data/app/models/spud_role.rb +2 -7
  18. data/app/views/layouts/admin/application.html.erb +1 -1
  19. data/app/views/tb_core_mailer/forgot_password_notification.html.erb +5 -1
  20. data/lib/generators/spud/controller_spec_generator.rb +1 -1
  21. data/lib/generators/spud/module_generator.rb +4 -4
  22. data/lib/generators/spud/setup_generator.rb +3 -5
  23. data/lib/tb_core/belongs_to_app.rb +2 -1
  24. data/lib/tb_core/engine.rb +1 -3
  25. data/lib/tb_core/form_builder.rb +1 -1
  26. data/lib/tb_core/test_files.rb +3 -3
  27. data/lib/tb_core/test_helper.rb +25 -25
  28. data/lib/tb_core/version.rb +1 -1
  29. data/spec/controllers/admin/application_controller_spec.rb +3 -3
  30. data/spec/controllers/admin/dashboard_controller_spec.rb +1 -1
  31. data/spec/controllers/admin/password_reset_controller_spec.rb +2 -2
  32. data/spec/controllers/admin/settings_controller_spec.rb +1 -1
  33. data/spec/controllers/admin/setup_controller_spec.rb +1 -1
  34. data/spec/controllers/admin/user_sessions_controller_spec.rb +1 -1
  35. data/spec/controllers/admin/users_controller_spec.rb +3 -3
  36. data/spec/dummy/app/assets/config/manifest.js +3 -0
  37. data/spec/dummy/config/application.rb +1 -46
  38. data/spec/dummy/config/initializers/secret_token.rb +0 -1
  39. data/spec/factories/spud_admin_permission_factories.rb +1 -1
  40. data/spec/factories/spud_user_factories.rb +2 -2
  41. data/spec/models/spud_user_spec.rb +2 -2
  42. data/spec/rails_helper.rb +1 -1
  43. data/vendor/assets/rails-validator/rails-validator.js +534 -0
  44. data/vendor/assets/rails-validator/rails-validator.js.map +1 -0
  45. data/vendor/assets/rails-validator/rails-validator.min.js +3 -0
  46. metadata +44 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 119d2b18447e11794e3242645aacd697afa47258
4
- data.tar.gz: 90fa0a23e723b28b1a597bed200157783252ed43
2
+ SHA256:
3
+ metadata.gz: 6d872d85445d4c25392456def398ec02e4103b2d200272849c105063c75699e7
4
+ data.tar.gz: a4fa137374414a058fce80a9169518b3978587e968c7a9b21d0a8982db1b86f0
5
5
  SHA512:
6
- metadata.gz: 66144e84faacb6b62cb9ee33ea90342b6cb426238a7d41ab75aa09c2b644be8a5e3fe48a0a767d2add4c82fb0b4222127bcce70ed60d7b9cb4e5b671f90def8f
7
- data.tar.gz: 3fb79b93110d12782939307eee24776d1bc0f1cd7c424e7a90f2252aeb5bc9bdb345d6760a552afc1d5e086ff19f29af7ec4859d31a5349e6b4e5e4dfe16c5ae
6
+ metadata.gz: f7b229ce4e43d1012672432e6641005cc944926eef3a77fe5044cfc26ed591d0d572729ddbd7fb6a7c0ca27e9c559fe8aa05941815abcb2d29281af35637a9d0
7
+ data.tar.gz: 1939d6ab1f5e361a89b0dc79f3dea4c023413cad9bb870a4f711241cdcb7dd6b8c0474b2a49321e686de3bf64ee86571c6ffb706bf0d736991dd1713de76d4d9
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://semaphoreci.com/api/v1/moser-it/tb_core/branches/dev/shields_badge.svg)](https://semaphoreci.com/moser-it/tb_core)
1
+ [![CircleCI](https://circleci.com/bb/moser-inc/tb_core.svg?style=svg)](https://circleci.com/bb/moser-inc/tb_core)
2
2
 
3
3
  Twice Baked Core
4
4
  ================
@@ -105,7 +105,7 @@ Create a file in your app at `app/views/admin/users/_form_additions.html.erb`.
105
105
  <%= f.label :avatar, :class=>"control-label"%>
106
106
  <div class="controls">
107
107
  <%= f.file_field :avatar %>
108
- </div>
108
+ </div>
109
109
  </div>
110
110
 
111
111
  ### Adding fields to the user show action
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
17
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
18
18
  load 'rails/tasks/engine.rake'
19
19
 
20
20
  load 'rails/tasks/statistics.rake'
@@ -43,6 +43,7 @@ private
43
43
  def load_user_using_perishable_token
44
44
  @user = SpudUser.find_using_perishable_token(params[:id])
45
45
  return if @user
46
+
46
47
  flash[:notice] = "We're sorry, but we could not locate your account. " +
47
48
  'If you are having issues try copying and pasting the URL ' +
48
49
  'from your email into your browser or restarting the ' +
@@ -34,9 +34,7 @@ class Admin::RolesController < Admin::ApplicationController
34
34
 
35
35
  def update
36
36
  #role_params[:permission_tags] ||= []
37
- if @role.update_attributes(role_params)
38
- flash[:notice] = 'SpudRole updated successfully'
39
- end
37
+ flash[:notice] = 'SpudRole updated successfully' if @role.update(role_params)
40
38
  respond_with @role, location: admin_roles_path
41
39
  end
42
40
 
@@ -13,14 +13,14 @@ class Admin::SettingsController < Admin::ApplicationController
13
13
  end
14
14
 
15
15
  def update
16
- if check_password && @current_user.update_attributes(user_params)
16
+ if check_password && @current_user.update(user_params)
17
17
  if user_params.include?(:password)
18
18
  SpudUserSession.create(@current_user)
19
19
  end
20
20
  flash[:notice] = 'User settings saved successfully.'
21
21
  respond_with @current_user, location: admin_settings_path
22
22
  else
23
- render 'edit', status: 401
23
+ render 'edit', status: :unauthorized
24
24
  end
25
25
  end
26
26
 
@@ -18,7 +18,7 @@ class Admin::SetupController < Admin::ApplicationController
18
18
  SpudUserSession.create(@spud_user)
19
19
  redirect_to admin_root_path
20
20
  else
21
- render 'new', status: 422
21
+ render 'new', status: :unprocessable_entity
22
22
  end
23
23
  end
24
24
 
@@ -8,8 +8,8 @@ class Admin::UsersController < Admin::ApplicationController
8
8
  respond_to :html, :csv
9
9
 
10
10
  sortable_by :email, :current_login_at,
11
- name: [:last_name, :first_name],
12
- default: :email
11
+ name: [:last_name, :first_name],
12
+ default: :email
13
13
 
14
14
  def index
15
15
  @spud_users = SpudUser.order(sortable_query).paginate(page: params[:page], per_page: 15)
@@ -63,7 +63,7 @@ class Admin::UsersController < Admin::ApplicationController
63
63
  end
64
64
 
65
65
  def update
66
- if @user.update_attributes(user_params)
66
+ if @user.update(user_params)
67
67
  if @user == current_user && user_params[:password].present?
68
68
  SpudUserSession.create(@user)
69
69
  end
@@ -75,7 +75,7 @@ class Admin::UsersController < Admin::ApplicationController
75
75
  @user.destroy
76
76
  respond_with @user, location: admin_users_path do |format|
77
77
  format.js{
78
- render nothing: true, status: 200
78
+ render nothing: true, status: :ok
79
79
  }
80
80
  end
81
81
  end
@@ -29,14 +29,15 @@ module TbCore
29
29
  render template: error.template,
30
30
  layout: nil,
31
31
  formats: [:html],
32
+ locals: { },
32
33
  status: error.code,
33
34
  content_type: 'text/html'
34
35
  end
35
36
  end
36
37
  end
37
38
 
38
- def handle_record_not_found(e)
39
- error = NotFoundError.new(class_string(e.model))
39
+ def handle_record_not_found(exception)
40
+ error = NotFoundError.new(class_string(exception.model))
40
41
  handle_request_error(error)
41
42
  end
42
43
 
@@ -50,8 +51,8 @@ module TbCore
50
51
  string
51
52
  end
52
53
 
53
- def handle_unknown_format_error(_e)
54
- error = NotFoundError.new()
54
+ def handle_unknown_format_error(_exception)
55
+ error = NotFoundError.new
55
56
  handle_request_error(error)
56
57
  end
57
58
  end
@@ -14,6 +14,7 @@ module TbCore
14
14
  if params[:return_to]
15
15
  uri = URI.parse(params[:return_to].to_s)
16
16
  return "#{uri.path}?#{uri.query}" if uri.query
17
+
17
18
  return uri.path
18
19
  end
19
20
  default
@@ -10,27 +10,32 @@ module TbCore
10
10
 
11
11
  def current_user_session
12
12
  return @current_user_session if defined?(@current_user_session)
13
+
13
14
  @current_user_session = SpudUserSession.find
14
15
  end
15
16
 
16
17
  def current_user
17
18
  return @current_user if defined?(@current_user)
19
+
18
20
  @current_user = current_user_session&.spud_user
19
21
  end
20
22
 
21
23
  def current_user_id
22
24
  return 0 unless @current_user
25
+
23
26
  @current_user.id
24
27
  end
25
28
 
26
29
  def require_user
27
30
  raise UnauthorizedError.new unless current_user
31
+
28
32
  true
29
33
  end
30
34
 
31
35
  def require_admin_user
32
36
  raise UnauthorizedError.new unless current_user
33
37
  raise AccessDeniedError.new unless current_user.admin_rights?
38
+
34
39
  true
35
40
  end
36
41
 
@@ -14,7 +14,7 @@ class UserSessionsController < ApplicationController
14
14
  end
15
15
 
16
16
  def create
17
- @user_session = SpudUserSession.new(user_session_params)
17
+ @user_session = SpudUserSession.new(user_session_params.to_h)
18
18
  if @user_session.save()
19
19
  respond_with @user_session do |format|
20
20
  format.html{
@@ -50,7 +50,7 @@ class UserSessionsController < ApplicationController
50
50
  end
51
51
 
52
52
  def set_change_password
53
- current_user.update_attributes(change_password_params)
53
+ current_user.update(change_password_params)
54
54
  respond_with current_user do |format|
55
55
  format.html{
56
56
  if current_user.errors.any?
@@ -0,0 +1,9 @@
1
+ module ForgotPasswordMailerHelper
2
+ def perishable_token_link_expiration_time_text(user)
3
+ return if user.class.perishable_token_valid_for.blank?
4
+
5
+ expiration_time = user.updated_at + user.class.perishable_token_valid_for
6
+
7
+ "This link will expire in #{distance_of_time_in_words(Time.current, expiration_time)}."
8
+ end
9
+ end
@@ -13,6 +13,21 @@ module TbCore::ApplicationHelper
13
13
  return form_for(record, options, &block)
14
14
  end
15
15
 
16
+ def tb_form_with(record, **options, &block)
17
+ options[:builder] = TbCore::FormBuilder
18
+
19
+ options[:html] ||= {}
20
+ if options[:html][:class]
21
+ options[:html][:class] += ' form-horizontal'
22
+ else
23
+ options[:html][:class] = 'form-horizontal'
24
+ end
25
+
26
+ options[:model] = record
27
+
28
+ return form_with(options, &block)
29
+ end
30
+
16
31
  def tb_form_errors(record, *fields_to_display)
17
32
  if record.errors.any?
18
33
  content_tag :div, class: 'form-errors test' do
@@ -56,6 +71,7 @@ module TbCore::ApplicationHelper
56
71
  end
57
72
  end
58
73
 
74
+ # rubocop:disable Rails/HelperInstanceVariable
59
75
  def tb_page_title
60
76
  if content_for?(:title)
61
77
  title = content_for(:title) + ' | ' + TbCore.site_name
@@ -66,6 +82,7 @@ module TbCore::ApplicationHelper
66
82
  end
67
83
  return content_tag :title, title
68
84
  end
85
+ # rubocop:enable Rails/HelperInstanceVariable
69
86
 
70
87
  def current_site_name
71
88
  return TbCore.config.site_name
@@ -1,4 +1,6 @@
1
1
  class TbCoreMailer < ActionMailer::Base
2
+ helper ForgotPasswordMailerHelper
3
+
2
4
  default from: TbCore.from_address
3
5
  layout 'mailer'
4
6
 
@@ -1,27 +1,40 @@
1
1
  module TbCore
2
+
3
+ module Regex
4
+ EMAIL = /
5
+ \A
6
+ [A-Z0-9_.&%+\-']+ # mailbox
7
+ @
8
+ (?:[A-Z0-9\-]+\.)+ # subdomains
9
+ (?:[A-Z]{2,25}) # TLD
10
+ \z
11
+ /ix.freeze
12
+ end
13
+
2
14
  module UserModel
3
15
  extend ActiveSupport::Concern
4
16
 
17
+ # rubocop:disable Metrics/BlockLength
5
18
  included do
6
19
  self.table_name = 'spud_users'
7
20
 
8
21
  acts_as_authentic do |c|
9
- c.transition_from_crypto_providers = Authlogic::CryptoProviders::Sha512
10
22
  c.crypto_provider = Authlogic::CryptoProviders::SCrypt
11
23
  c.logged_in_timeout = 24.hours
12
24
  c.login_field = :email if TbCore.config.use_email_as_login
13
- if TbCore.config.user_password_length
14
- c.merge_validates_length_of_password_field_options(minimum: TbCore.config.user_password_length)
15
- end
25
+ c.require_password_confirmation = true
16
26
  end
17
27
 
28
+ attr_accessor :password_confirmation
29
+
18
30
  belongs_to :role,
19
- class_name: SpudRole.to_s, foreign_key: :spud_role_id, required: false
31
+ class_name: 'SpudRole', foreign_key: :spud_role_id, optional: true
20
32
  has_many :spud_user_settings,
21
33
  dependent: :destroy, foreign_key: :spud_user_id
22
34
 
23
35
  validates :first_name, :last_name, presence: true
24
36
  before_validation :set_login_to_email, if: -> { TbCore.config.use_email_as_login }
37
+
25
38
  before_update :unset_requires_password_change
26
39
 
27
40
  scope :admins, lambda {
@@ -29,7 +42,37 @@ module TbCore
29
42
  }
30
43
 
31
44
  scope :ordered, -> { order('last_name asc, first_name asc, email asc') }
45
+
46
+ # These used to be built in to Authlogic
47
+ # See: https://github.com/binarylogic/authlogic/blob/5986e1bd056ccecc519d9f49cc83a0ba757668b4/doc/use_normal_rails_validation.md
48
+ validates :email,
49
+ format: {
50
+ with: ::TbCore::Regex::EMAIL,
51
+ message: proc {
52
+ ::Authlogic::I18n.t(
53
+ 'error_messages.email_invalid',
54
+ default: 'should look like an email address.'
55
+ )
56
+ }
57
+ },
58
+ length: { maximum: 100 },
59
+ uniqueness: {
60
+ case_sensitive: false,
61
+ if: :will_save_change_to_email?
62
+ }
63
+ validates :password,
64
+ confirmation: { if: :require_password? },
65
+ length: {
66
+ minimum: 8,
67
+ if: :require_password?
68
+ }
69
+ validates :password_confirmation,
70
+ length: {
71
+ minimum: 8,
72
+ if: :require_password?
73
+ }
32
74
  end
75
+ # rubocop:enable Metrics/BlockLength
33
76
 
34
77
  module ClassMethods
35
78
 
@@ -69,6 +112,7 @@ module TbCore
69
112
 
70
113
  def full_name
71
114
  return login if first_name.blank? && last_name.blank?
115
+
72
116
  [first_name, last_name].reject(&:blank?).join(' ')
73
117
  end
74
118
 
@@ -79,12 +123,14 @@ module TbCore
79
123
  # Returns true if user can view at least one dashboard app
80
124
  def admin_rights?
81
125
  return true if super_admin
126
+
82
127
  TbCore.admin_applications.find { |app| can_view_app?(app) }.present?
83
128
  end
84
129
 
85
130
  # Returns true if the user can view a spud app based on it's key
86
131
  def can_view_app?(admin_application)
87
132
  return true if super_admin?
133
+
88
134
  key = admin_application[:key]
89
135
  permissions.find { |p| p.apps.include?(key) }.present?
90
136
  end
@@ -95,6 +141,7 @@ module TbCore
95
141
  # * if multiple tags are supplied, return true if ALL tags match
96
142
  def permission?(*tags)
97
143
  return true if super_admin?
144
+
98
145
  my_tags = permissions.collect(&:tag)
99
146
  tags.find { |tag| !my_tags.include?(tag) }.blank?
100
147
  end
@@ -105,12 +152,14 @@ module TbCore
105
152
  # * if multiple tags are supplied, return true if ANY tag matches
106
153
  def any_permission?(*tags)
107
154
  return true if super_admin?
155
+
108
156
  permissions.find { |p| tags.include?(p.tag) }.present?
109
157
  end
110
158
 
111
159
  # Return a list of SpudPermission objects for the user's SpudRole
112
160
  def permissions
113
161
  return [] if role.blank?
162
+
114
163
  role.permissions
115
164
  end
116
165
 
@@ -122,9 +171,7 @@ module TbCore
122
171
  end
123
172
 
124
173
  def unset_requires_password_change
125
- if password_changed? && !requires_password_change_changed?(to: true)
126
- self.requires_password_change = false
127
- end
174
+ self.requires_password_change = false if password_changed? && !requires_password_change_changed?(to: true)
128
175
  true
129
176
  end
130
177
  end
@@ -14,14 +14,9 @@ class SpudRole < ActiveRecord::Base
14
14
  end
15
15
 
16
16
  def permission_tags=(tags)
17
- self.spud_role_permissions.each do |role_permission|
18
- if role_permission.permission.nil? || !tags.include?(role_permission.permission.tag)
19
- role_permission.destroy()
20
- else
21
- tags.delete(role_permission.permission.tag)
22
- end
17
+ self.spud_role_permissions = tags.map do |tag|
18
+ SpudRolePermission.new(spud_permission_tag: tag)
23
19
  end
24
- self.spud_role_permissions += tags.collect{ |tag| SpudRolePermission.new(spud_permission_tag: tag) }
25
20
  end
26
21
 
27
22
  def permission_tags
@@ -49,7 +49,7 @@
49
49
  <h3 class="modal-title"></h3>
50
50
  </div>
51
51
  <div class="modal-body">
52
- <p>One fine body&hellip;</p>
52
+ <p>...</p>
53
53
  </div>
54
54
  <div class="modal-footer modal-footer-default">
55
55
  <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
@@ -1,6 +1,10 @@
1
1
  <h1>Hello <%= @user.full_name %>,</h1>
2
2
 
3
- <p>A password reset has recently been requested for your user account on <strong><%= TbCore.config.site_name %></strong>. Click the link below to set your new password.</p>
3
+ <p>
4
+ A password reset has recently been requested for your user account on <strong><%= TbCore.config.site_name %></strong>.
5
+ Click the link below to set your new password.
6
+ <%= perishable_token_link_expiration_time_text(@user) %>
7
+ </p>
4
8
 
5
9
  <p><%= link_to @url, @url %></p>
6
10
 
@@ -1,5 +1,5 @@
1
1
  class Spud::ControllerSpecGenerator < ::Rails::Generators::Base
2
- source_root File.expand_path('../templates', __FILE__)
2
+ source_root File.expand_path('templates', __dir__)
3
3
 
4
4
  argument :name, type: :string
5
5
  argument :string_attribute, type: :string