trestle-auth 0.2.5 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
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