trestle-auth 0.2.5 → 0.4.3

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.browserslistrc +1 -0
  3. data/.gitignore +5 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +20 -3
  6. data/Gemfile +14 -0
  7. data/README.md +34 -7
  8. data/app/assets/bundle/trestle/auth/bundle.css +1 -0
  9. data/app/assets/bundle/trestle/auth/userbox.css +1 -0
  10. data/app/assets/stylesheets/trestle/_custom-auth.css +6 -0
  11. data/app/assets/stylesheets/trestle/auth.css +2 -0
  12. data/app/controllers/trestle/auth/sessions_controller.rb +3 -4
  13. data/app/helpers/trestle/auth/title_helper.rb +3 -1
  14. data/app/views/layouts/trestle/auth.html.erb +11 -8
  15. data/app/views/trestle/auth/_userbox.html.erb +16 -5
  16. data/app/views/trestle/auth/sessions/_form.html.erb +32 -0
  17. data/app/views/trestle/auth/sessions/new.html.erb +8 -31
  18. data/bin/rails +20 -0
  19. data/config/{locale → locales}/en.yml +7 -0
  20. data/config/locales/es.yml +15 -0
  21. data/config/{locale → locales}/pl.yml +7 -0
  22. data/config/{locale → locales}/pt-BR.yml +7 -0
  23. data/config/{locale → locales}/zh-CN.yml +0 -0
  24. data/config/routes.rb +8 -3
  25. data/frontend/_form.scss +79 -0
  26. data/frontend/_layout.scss +35 -0
  27. data/{app/assets/stylesheets/trestle/auth/_defaults.scss → frontend/_variables.scss} +2 -6
  28. data/frontend/index.scss +5 -0
  29. data/{app/assets/stylesheets/trestle/auth → frontend}/userbox.scss +14 -12
  30. data/gemfiles/rails-4.2.gemfile +18 -0
  31. data/gemfiles/rails-5.0.gemfile +18 -0
  32. data/gemfiles/rails-5.1.gemfile +18 -0
  33. data/gemfiles/rails-5.2.gemfile +18 -0
  34. data/gemfiles/rails-6.0.gemfile +18 -0
  35. data/lib/generators/trestle/auth/account/account_generator.rb +32 -0
  36. data/lib/generators/trestle/auth/account/templates/admin.rb.erb +47 -0
  37. data/lib/generators/trestle/auth/admin/admin_generator.rb +15 -1
  38. data/lib/generators/trestle/auth/admin/templates/admin.rb.erb +28 -5
  39. data/lib/generators/trestle/auth/install/install_generator.rb +40 -109
  40. data/lib/generators/trestle/auth/install/templates/basic.rb.erb +121 -0
  41. data/lib/generators/trestle/auth/install/templates/devise.rb.erb +92 -0
  42. data/lib/trestle/auth.rb +14 -8
  43. data/lib/trestle/auth/backends.rb +34 -0
  44. data/lib/trestle/auth/backends/base.rb +28 -0
  45. data/lib/trestle/auth/backends/basic.rb +72 -0
  46. data/lib/trestle/auth/backends/devise.rb +14 -0
  47. data/lib/trestle/auth/backends/warden.rb +53 -0
  48. data/lib/trestle/auth/configuration.rb +27 -3
  49. data/lib/trestle/auth/configuration/warden.rb +11 -0
  50. data/lib/trestle/auth/constraint.rb +23 -1
  51. data/lib/trestle/auth/controller/authentication.rb +58 -0
  52. data/lib/trestle/auth/controller/locale.rb +18 -0
  53. data/lib/trestle/auth/controller/time_zone.rb +18 -0
  54. data/lib/trestle/auth/controller_methods.rb +3 -74
  55. data/lib/trestle/auth/engine.rb +1 -1
  56. data/lib/trestle/auth/model_methods.rb +2 -3
  57. data/lib/trestle/auth/version.rb +1 -1
  58. data/package.json +29 -0
  59. data/trestle-auth.gemspec +14 -10
  60. data/webpack.config.js +49 -0
  61. data/yarn.lock +4835 -0
  62. metadata +66 -32
  63. data/app/assets/javascripts/trestle/auth.js +0 -0
  64. data/app/assets/stylesheets/trestle/_custom-auth.scss +0 -4
  65. data/app/assets/stylesheets/trestle/auth.scss +0 -13
  66. data/app/assets/stylesheets/trestle/auth/_form.scss +0 -138
  67. data/app/assets/stylesheets/trestle/auth/_layout.scss +0 -20
@@ -0,0 +1,35 @@
1
+ .auth-body {
2
+ display: flex;
3
+ color: white;
4
+
5
+ .container {
6
+ margin: auto;
7
+ width: 320px;
8
+ }
9
+ }
10
+
11
+ .auth-header {
12
+ text-align: center;
13
+ margin-bottom: 20px;
14
+
15
+ h1 {
16
+ display: flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+
20
+ font-size: 1.75rem;
21
+ font-weight: 500;
22
+ text-shadow: rgba(black, 0.5) 0 1px 1px;
23
+
24
+ padding: 0.75rem 1rem;
25
+ }
26
+
27
+ img {
28
+ max-width: 80%;
29
+ max-height: 100%;
30
+ }
31
+
32
+ span {
33
+ margin-left: 10px;
34
+ }
35
+ }
@@ -1,13 +1,9 @@
1
- $auth-bg: $theme-bg !default;
2
-
3
1
  $auth-form-control-color: white !default;
4
2
  $auth-form-control-placeholder: rgba(white, 0.5) !default;
5
3
  $auth-form-control-bg: rgba(white, 0.1) !default;
6
4
  $auth-form-control-border: 0 !default;
7
5
 
6
+ $auth-form-control-icon-color: rgba(white, 0.5) !default;
7
+
8
8
  $auth-remember-me-color: rgba(white, 0.75) !default;
9
9
  $auth-remember-me-bg: rgba(black, 0.075) !default;
10
-
11
- $auth-login-btn-color: $btn-primary-color !default;
12
- $auth-login-btn-border: $btn-primary-border !default;
13
- $auth-login-btn-bg: $btn-primary-bg !default;
@@ -0,0 +1,5 @@
1
+ @import "~trestle/frontend/css/support";
2
+
3
+ @import "variables";
4
+ @import "layout";
5
+ @import "form";
@@ -1,16 +1,18 @@
1
- @import "trestle/support";
1
+ @import "~trestle/frontend/css/support";
2
2
 
3
3
  .userbox {
4
- margin-top: 2px;
5
- margin-bottom: 2px;
4
+ order: 99;
5
+ padding: 2px 0;
6
+
7
+ display: flex;
8
+ align-items: center;
6
9
 
7
10
  > a {
8
- color: $text-color;
11
+ color: $body-color;
9
12
 
10
13
  display: block;
11
14
  padding: 2px 0;
12
15
 
13
- font-size: 14px;
14
16
  font-weight: normal;
15
17
  line-height: 40px;
16
18
 
@@ -24,26 +26,26 @@
24
26
  margin-left: 6px;
25
27
  }
26
28
 
27
- .name {
28
- color: $text-color;
29
+ .dropdown-toggle {
30
+ &::after {
31
+ vertical-align: middle;
32
+ }
29
33
  }
30
34
  }
31
35
 
32
- @include mobile {
36
+ @include media-breakpoint-down(sm) {
33
37
  .userbox {
38
+ display: block;
34
39
  position: relative;
35
40
  z-index: 5;
36
41
 
37
- > a, .name {
38
- color: white;
39
- }
40
-
41
42
  .name {
42
43
  display: none;
43
44
  }
44
45
 
45
46
  .avatar {
46
47
  border: 1px solid rgba(white, 0.25);
48
+ margin-left: 0;
47
49
  }
48
50
  }
49
51
  }
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem "coveralls", require: false
5
+ gem "capybara"
6
+
7
+ gem "sqlite3", "~> 1.3.13"
8
+ gem "devise"
9
+ end
10
+
11
+ gem "rails", "~> 4.2.0"
12
+ gem "sassc-rails"
13
+
14
+ gem "rake", "~> 12.0"
15
+
16
+ gem "trestle", github: "TrestleAdmin/trestle"
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem "coveralls", require: false
5
+ gem "capybara"
6
+
7
+ gem "sqlite3", "~> 1.3.13"
8
+ gem "devise"
9
+ end
10
+
11
+ gem "rails", "~> 5.0.0"
12
+ gem "sassc-rails"
13
+
14
+ gem "rake", "~> 12.0"
15
+
16
+ gem "trestle", github: "TrestleAdmin/trestle"
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem "coveralls", require: false
5
+ gem "capybara"
6
+
7
+ gem "sqlite3", "~> 1.3.13"
8
+ gem "devise"
9
+ end
10
+
11
+ gem "rails", "~> 5.1.0"
12
+ gem "sassc-rails"
13
+
14
+ gem "rake", "~> 12.0"
15
+
16
+ gem "trestle", github: "TrestleAdmin/trestle"
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem "coveralls", require: false
5
+ gem "capybara"
6
+
7
+ gem "sqlite3", "~> 1.3.13"
8
+ gem "devise"
9
+ end
10
+
11
+ gem "rails", "~> 5.2.0"
12
+ gem "sassc-rails"
13
+
14
+ gem "rake", "~> 12.0"
15
+
16
+ gem "trestle", github: "TrestleAdmin/trestle"
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem "coveralls", require: false
5
+
6
+ gem "capybara"
7
+ gem "sqlite3", "~> 1.4"
8
+ gem "devise"
9
+ end
10
+
11
+ gem "rails", "~> 6.0.0"
12
+ gem "sassc-rails"
13
+
14
+ gem "rake", "~> 12.0"
15
+
16
+ gem "trestle", github: "TrestleAdmin/trestle"
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,32 @@
1
+ module Trestle
2
+ module Auth
3
+ module Generators
4
+ class AccountGenerator < ::Rails::Generators::Base
5
+ desc "Creates a Trestle admin for managing the logged in user"
6
+
7
+ argument :model, type: :string, default: "Administrator"
8
+
9
+ class_option :devise, type: :boolean, default: false, desc: "Create admin for a Devise user model"
10
+
11
+ source_root File.expand_path("../templates", __FILE__)
12
+
13
+ def create_admin
14
+ template "admin.rb.erb", "app/admin/auth/account_admin.rb"
15
+ end
16
+
17
+ def devise?
18
+ options[:devise]
19
+ end
20
+
21
+ protected
22
+ def parameter_name
23
+ singular_name
24
+ end
25
+
26
+ def singular_name
27
+ model.demodulize.underscore
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,47 @@
1
+ Trestle.resource(:account, model: <%= model %>, scope: Auth, singular: true) do
2
+ instance do
3
+ current_user
4
+ end
5
+
6
+ remove_action :new, :edit, :destroy
7
+
8
+ form do |<%= parameter_name %>|
9
+ text_field :email
10
+
11
+ <%- unless devise? -%>
12
+ row do
13
+ col(sm: 6) { text_field :first_name }
14
+ col(sm: 6) { text_field :last_name }
15
+ end
16
+
17
+ <%- end -%>
18
+ row do
19
+ col(sm: 6) { password_field :password }
20
+ col(sm: 6) { password_field :password_confirmation }
21
+ end
22
+ end
23
+ <%- if devise? -%>
24
+
25
+ # Ignore the password parameters if they are blank
26
+ update_instance do |instance, attrs|
27
+ if attrs[:password].blank?
28
+ attrs.delete(:password)
29
+ attrs.delete(:password_confirmation) if attrs[:password_confirmation].blank?
30
+ end
31
+
32
+ instance.assign_attributes(attrs)
33
+ end
34
+
35
+ # Log the current user back in if their password was changed
36
+ after_action on: :update do
37
+ if instance.encrypted_password_previously_changed?
38
+ login!(instance)
39
+ end
40
+ end if Devise.sign_in_after_reset_password
41
+ <%- end -%>
42
+
43
+ # Limit the parameters that are permitted to be updated by the user
44
+ params do |params|
45
+ params.require(:account).permit(:email, <% unless devise? %>:first_name, :last_name, <% end %>:password, :password_confirmation)
46
+ end
47
+ end
@@ -6,15 +6,29 @@ module Trestle
6
6
 
7
7
  argument :model, type: :string, default: "Administrator"
8
8
 
9
+ class_option :devise, type: :boolean, default: false, desc: "Create admin for a Devise user model"
10
+
9
11
  source_root File.expand_path("../templates", __FILE__)
10
12
 
11
13
  def create_admin
12
14
  template "admin.rb.erb", File.join('app/admin/auth', "#{model.underscore.pluralize}_admin.rb")
13
15
  end
14
16
 
17
+ def devise?
18
+ options[:devise]
19
+ end
20
+
15
21
  protected
22
+ def parameter_name
23
+ singular_name
24
+ end
25
+
16
26
  def plural_name
17
- model.demodulize.underscore.pluralize
27
+ singular_name.pluralize
28
+ end
29
+
30
+ def singular_name
31
+ model.demodulize.underscore
18
32
  end
19
33
  end
20
34
  end
@@ -1,33 +1,56 @@
1
- Trestle.resource(:<%= plural_name %>, model: Trestle.config.auth.user_class, scope: Auth) do
1
+ Trestle.resource(:<%= plural_name %>, model: <%= model %>, scope: Auth) do
2
2
  menu do
3
3
  group :configuration, priority: :last do
4
- item :<%= plural_name %>, icon: "fa fa-users"
4
+ item :<%= plural_name %>, icon: "fas fa-users"
5
5
  end
6
6
  end
7
7
 
8
8
  table do
9
- column :avatar, header: false do |administrator|
10
- avatar_for(administrator)
9
+ column :avatar, header: false do |<%= parameter_name %>|
10
+ avatar_for(<%= parameter_name %>)
11
11
  end
12
12
  column :email, link: true
13
+ <%- unless devise? -%>
13
14
  column :first_name
14
15
  column :last_name
16
+ <%- end -%>
15
17
  actions do |a|
16
18
  a.delete unless a.instance == current_user
17
19
  end
18
20
  end
19
21
 
20
- form do |administrator|
22
+ form do |<%= parameter_name %>|
21
23
  text_field :email
22
24
 
25
+ <%- unless devise? -%>
23
26
  row do
24
27
  col(sm: 6) { text_field :first_name }
25
28
  col(sm: 6) { text_field :last_name }
26
29
  end
27
30
 
31
+ <%- end -%>
28
32
  row do
29
33
  col(sm: 6) { password_field :password }
30
34
  col(sm: 6) { password_field :password_confirmation }
31
35
  end
32
36
  end
37
+ <%- if devise? -%>
38
+
39
+ # Ignore the password parameters if they are blank
40
+ update_instance do |instance, attrs|
41
+ if attrs[:password].blank?
42
+ attrs.delete(:password)
43
+ attrs.delete(:password_confirmation) if attrs[:password_confirmation].blank?
44
+ end
45
+
46
+ instance.assign_attributes(attrs)
47
+ end
48
+
49
+ # Log the current user back in if their password was changed
50
+ after_action on: :update do
51
+ if instance == current_user && instance.encrypted_password_previously_changed?
52
+ login!(instance)
53
+ end
54
+ end if Devise.sign_in_after_reset_password
55
+ <%- end -%>
33
56
  end
@@ -6,6 +6,11 @@ module Trestle
6
6
 
7
7
  argument :model, type: :string, default: "Administrator"
8
8
 
9
+ class_option :devise, type: :boolean, default: false, desc: "Setup trestle-auth with Devise integration"
10
+ class_option :skip_account, type: :boolean, default: false, desc: "Skip creation of the current account admin"
11
+
12
+ source_root File.expand_path("../templates", __FILE__)
13
+
9
14
  def check_trestle_installed
10
15
  unless ::File.exist?("config/initializers/trestle.rb")
11
16
  raise Thor::Error, "The file config/initializers/trestle.rb does not appear to exist. Please run `trestle:install` first."
@@ -14,126 +19,52 @@ module Trestle
14
19
 
15
20
  def insert_configuration
16
21
  inject_into_file "config/initializers/trestle.rb", before: /^end/ do
17
- <<-RUBY.strip_heredoc.indent(2)
18
-
19
- # == Authentication Options
20
- #
21
- # Specify the user class to be used by trestle-auth.
22
- #
23
- config.auth.user_class = -> { #{model} }
24
-
25
- # Specify the scope for valid admin users.
26
- # Defaults to config.auth.user_class (unscoped).
27
- #
28
- # config.auth.user_scope = -> { User.where(admin: true) }
29
-
30
- # Specify the Trestle admin for managing administrator users.
31
- #
32
- config.auth.user_admin = -> { :"auth/#{model.underscore.pluralize}" }
33
-
34
- # Specify the parameter (along with a password) to be used to
35
- # authenticate an administrator. Defaults to :email.
36
- #
37
- # config.auth.authenticate_with = :login
38
-
39
- # Customize the method for authenticating a user given login parameters.
40
- # The block should return an instance of the auth user class, or nil.
41
- #
42
- # config.auth.authenticate = ->(params) {
43
- # User.authenticate(params[:login], params[:password])
44
- # }
45
-
46
- # Customize the method for finding a user given an ID from the session.
47
- # The block should return an instance of the auth user class, or nil.
48
- #
49
- # config.auth.find_user = ->(id) {
50
- # User.find_by(id: id)
51
- # }
52
-
53
- # Customize the rendering of user avatars. Can be disabled by setting to false.
54
- # Defaults to the Gravatar based on the user's email address.
55
- #
56
- # config.auth.avatar = ->(user) {
57
- # avatar(fallback: user.initials) do
58
- # image_tag(user.avatar_url, alt: user.name) if user.avatar_url?
59
- # end
60
- # }
61
-
62
- # Customize the rendering of the current user's name in the main header.
63
- # Defaults to the user's #first_name and #last_name (last name in bold),
64
- # with a fallback to `display(user)` if those methods aren't defined.
65
- #
66
- # config.auth.format_user_name = ->(user) {
67
- # content_tag(:strong, user.full_name)
68
- # }
69
-
70
- # Customize the method for determining the user's locale.
71
- # Defaults to user.locale (if the method is defined).
72
- #
73
- # config.auth.locale = ->(user) {
74
- # user.locale if user.respond_to?(:locale)
75
- # }
76
-
77
- # Customize the method for determining the user's time zone.
78
- # Defaults to user.time_zone (if the method is defined).
79
- #
80
- # config.auth.time_zone = ->(user) {
81
- # user.time_zone if user.respond_to?(:time_zone)
82
- # }
22
+ format_configuration(template_content(configuration_template))
23
+ end
24
+ end
83
25
 
84
- # Specify the redirect location after a successful login.
85
- # Defaults to the main Trestle admin path.
86
- #
87
- # config.auth.redirect_on_login = -> {
88
- # if admin = Trestle.lookup(Trestle.config.auth.user_admin)
89
- # admin.instance_path(current_user)
90
- # else
91
- # Trestle.config.path
92
- # end
93
- # }
26
+ def generate_model
27
+ generate "trestle:auth:model", model unless devise?
28
+ end
94
29
 
95
- # Specify the redirect location after logging out.
96
- # Defaults to the trestle-auth new login path.
97
- #
98
- # config.auth.redirect_on_logout = -> { "/" }
30
+ def generate_admin
31
+ generate "trestle:auth:admin", model, ("--devise" if devise?)
32
+ end
99
33
 
100
- # Enable or disable remember me functionality. Defaults to true.
101
- #
102
- # config.auth.remember.enabled = false
34
+ def generate_account
35
+ generate "trestle:auth:account", model, ("--devise" if devise?) unless options[:skip_account]
36
+ end
103
37
 
104
- # Specify remember me expiration time. Defaults to 2 weeks.
105
- #
106
- # config.auth.remember.for = 30.days
38
+ def devise?
39
+ options[:devise]
40
+ end
107
41
 
108
- # Customize the method for authenticating a user given a remember token.
109
- #
110
- # config.auth.remember.authenticate = ->(token) {
111
- # User.authenticate_with_remember_token(token)
112
- # }
42
+ def configuration_template
43
+ devise? ? "devise.rb.erb" : "basic.rb.erb"
44
+ end
113
45
 
114
- # Customize the method for remembering a user.
115
- #
116
- # config.auth.remember.remember_me, ->(user) { user.remember_me! }
46
+ private
47
+ def format_configuration(source)
48
+ "\n#{source.indent(2)}\n"
49
+ end
117
50
 
118
- # Customize the method for forgetting a user.
119
- #
120
- # config.auth.remember.forget_me, ->(user) { user.forget_me! }
51
+ def template_content(path, options={})
52
+ path = File.expand_path(find_in_source_paths(path.to_s))
53
+ context = options.delete(:context) || instance_eval("binding")
121
54
 
122
- # Customize the method for generating the remember cookie.
123
- #
124
- # config.auth.remember.cookie, ->(user) {
125
- # { value: user.remember_token, expires: user.remember_token_expires_at }
126
- # }
127
- RUBY
128
- end
55
+ content = capturable_erb(path).tap do |erb|
56
+ erb.filename = path
57
+ end.result(context)
129
58
  end
130
59
 
131
- def generate_model
132
- generate "trestle:auth:model", model
133
- end
60
+ def capturable_erb(path)
61
+ match = ERB.version.match(/(\d+\.\d+\.\d+)/)
134
62
 
135
- def generate_admin
136
- generate "trestle:auth:admin", model
63
+ if match && match[1] >= "2.2.0" # Ruby 2.6+
64
+ CapturableERB.new(::File.binread(path), trim_mode: "-", eoutvar: "@output_buffer")
65
+ else
66
+ CapturableERB.new(::File.binread(path), nil, "-", "@output_buffer")
67
+ end
137
68
  end
138
69
  end
139
70
  end