authentication-zero 2.5.0 → 2.7.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33059916bc171e1b5b356d42cec0cda9187fccae24dcf672f64d92a5c1c361ae
4
- data.tar.gz: 7a03af810846d29d4256569d7551640a169d4da5fdd47a3c3495c4e8c99af1b7
3
+ metadata.gz: 60cf049a1db63ab5db00eae68715cb06a09e9a7901453050c44193ea0fa2c3ef
4
+ data.tar.gz: 0e4373e8deb0556129a6aa8dc07222dcff48f5e79c156120c9e1fc90ac9444a5
5
5
  SHA512:
6
- metadata.gz: ee18e7ebff72bfe5f640aa0ceb9ecf34d1ceb05b17b98d537a119ff3ec152c12106455fb43704a97ea2723dd1bac39c8c109c9c5522118f9976dc37aa0b17b63
7
- data.tar.gz: 0c63115b52b3a748f379922ca5eda6a0bfca9ecbf3960385a8441feb2e02d9cb43483250cfe0a739b7d14d29371a1ccc29065c51543ea56f6b115c4aab4afaf4
6
+ metadata.gz: 9168e4d6d3aa6873a56dab1cdb2b53f1640f71de184b73041430c4ee64e804eacc4e853ddc768d7be8189db41f4bdc69f66c3be61bc903adff40fbb491a38dad
7
+ data.tar.gz: 5f96ab18052f21ac747ed35edd5c9f2afec612c423bac8626a8eaf05970e78d782af567b3d9c831787ecb2d77c9eb823e604cb7b639a560df630aeac6193ac5e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## Authentication Zero 2.7.0 (March 2, 2022) ##
2
+
3
+ * Implemented omniauth
4
+
5
+ ## Authentication Zero 2.6.0 (March 1, 2022) ##
6
+
7
+ * Implemented ratelimit
8
+
1
9
  ## Authentication Zero 2.5.0 (February 28, 2022) ##
2
10
 
3
11
  * Implemented pwned
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- authentication-zero (2.5.0)
4
+ authentication-zero (2.7.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -11,11 +11,13 @@ The purpose of authentication zero is to generate a pre-built authentication sys
11
11
  - Checks if a password has been found in any data breach (--pwned)
12
12
  - Authentication by cookie
13
13
  - Authentication by token (--api)
14
+ - Social Login with OmniAuth (--omniauth)
14
15
  - Ask password before sensitive data changes, aka: sudo
15
16
  - Reset the user password and send reset instructions
16
17
  - Reset the user password only from verified emails
17
18
  - Lock sending reset password email after many attempts (--lockable)
18
- - Send e-mail notification when your email has been changed
19
+ - Rate limiting for your app, 1000 reqs/hour (--ratelimit)
20
+ - Send e-mail confirmation when your email has been changed
19
21
  - Send e-mail notification when someone has logged into your account
20
22
  - Manage multiple sessions & devices
21
23
  - Cancel my account
@@ -95,10 +97,6 @@ $ rails generate authentication user
95
97
 
96
98
  Then run `bundle install` again!
97
99
 
98
- #### --lockable (optional)
99
-
100
- Run `rails kredis:install`, to add a default configuration at `config/redis/shared.yml`.
101
-
102
100
  ## Development
103
101
 
104
102
  To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
@@ -1,3 +1,3 @@
1
1
  module AuthenticationZero
2
- VERSION = "2.5.0"
2
+ VERSION = "2.7.0"
3
3
  end
@@ -3,49 +3,62 @@ require "rails/generators/active_record"
3
3
  class AuthenticationGenerator < Rails::Generators::NamedBase
4
4
  include ActiveRecord::Generators::Migration
5
5
 
6
- class_option :api, type: :boolean, desc: "Generates API authentication"
6
+ class_option :api, type: :boolean, desc: "Generates API authentication"
7
+ class_option :pwned, type: :boolean, desc: "Add pwned password validation"
8
+ class_option :lockable, type: :boolean, desc: "Add password reset locking"
9
+ class_option :ratelimit, type: :boolean, desc: "Add request rate limiting"
10
+ class_option :omniauth, type: :boolean, desc: "Add social login support"
7
11
 
8
- class_option :lockable, type: :boolean, desc: "Add password reset locking"
12
+ source_root File.expand_path("templates", __dir__)
9
13
 
10
- class_option :pwned, type: :boolean, desc: "Add pwned password validation"
14
+ def add_gems
15
+ uncomment_lines "Gemfile", /"bcrypt"/
16
+ uncomment_lines "Gemfile", /"redis"/ if options.lockable?
17
+ uncomment_lines "Gemfile", /"kredis"/ if options.lockable?
11
18
 
12
- class_option :migration, type: :boolean, default: true
13
- class_option :test_framework, type: :string, desc: "Test framework to be invoked"
19
+ if options.pwned?
20
+ gem "pwned", comment: "Use Pwned to check if a password has been found in any of the huge data breaches [https://github.com/philnash/pwned]"
21
+ end
14
22
 
15
- class_option :fixture, type: :boolean, default: true
16
- class_option :system_tests, type: :string, desc: "Skip system test files"
23
+ if options.ratelimit?
24
+ gem "rack-ratelimit", group: :production, comment: "Use Rack::Ratelimit to rate limit requests [https://github.com/jeremy/rack-ratelimit]"
25
+ end
17
26
 
18
- class_option :skip_routes, type: :boolean
27
+ if omniauth?
28
+ gem "omniauth", comment: "Use OmniAuth to support multi-provider authentication [https://github.com/omniauth/omniauth]"
29
+ gem "omniauth-rails_csrf_protection", comment: "Provides a mitigation against CVE-2015-9284 [https://github.com/cookpad/omniauth-rails_csrf_protection]"
30
+ end
31
+ end
19
32
 
20
- source_root File.expand_path("templates", __dir__)
33
+ def create_configuration_files
34
+ copy_file "config/redis/shared.yml", "config/redis/shared.yml" if options.lockable?
35
+ copy_file "config/initializers/omniauth.rb", "config/initializers/omniauth.rb" if omniauth?
36
+ end
21
37
 
22
- def add_gems
23
- uncomment_lines "Gemfile", /"bcrypt"/
24
- uncomment_lines "Gemfile", /"redis"/ if options.lockable
25
- uncomment_lines "Gemfile", /"kredis"/ if options.lockable
26
- gem "pwned", comment: "Use pwned to check if a password has been found in any of the huge data breaches [https://github.com/philnash/pwned]" if options.pwned
38
+ def add_environment_configurations
39
+ ratelimit_code = <<~CODE
40
+ # Rate limit general requests by IP address in a rate of 1000 requests per hour
41
+ config.middleware.use(Rack::Ratelimit, name: "General", rate: [1000, 1.hour], redis: Redis.new, logger: Rails.logger) { |env| ActionDispatch::Request.new(env).ip }
42
+ CODE
43
+
44
+ environment ratelimit_code, env: "production" if options.ratelimit?
27
45
  end
28
46
 
29
47
  def create_migrations
30
- if options.migration
31
- migration_template "migrations/create_table_migration.rb", "#{db_migrate_path}/create_#{table_name}.rb"
32
- migration_template "migrations/create_sessions_migration.rb", "#{db_migrate_path}/create_sessions.rb"
33
- end
48
+ migration_template "migrations/create_table_migration.rb", "#{db_migrate_path}/create_#{table_name}.rb"
49
+ migration_template "migrations/create_sessions_migration.rb", "#{db_migrate_path}/create_sessions.rb"
50
+ migration_template "migrations/add_omniauth_migration.rb", "#{db_migrate_path}/add_omniauth_to_#{table_name}.rb" if omniauth?
34
51
  end
35
52
 
36
53
  def create_models
37
54
  template "models/model.rb", "app/models/#{file_name}.rb"
38
55
  template "models/session.rb", "app/models/session.rb"
39
56
  template "models/current.rb", "app/models/current.rb"
40
- template "models/locking.rb", "app/models/locking.rb" if options.lockable
57
+ template "models/locking.rb", "app/models/locking.rb" if options.lockable?
41
58
  end
42
59
 
43
- hook_for :fixture_replacement
44
-
45
60
  def create_fixture_file
46
- if options.fixture && options.fixture_replacement.nil?
47
- template "#{test_framework}/fixtures.yml", "test/fixtures/#{fixture_file_name}.yml"
48
- end
61
+ template "test_unit/fixtures.yml", "test/fixtures/#{fixture_file_name}.yml"
49
62
  end
50
63
 
51
64
  def add_application_controller_methods
@@ -93,10 +106,11 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
93
106
 
94
107
  def create_controllers
95
108
  directory "controllers/#{format_folder}", "app/controllers"
109
+ directory "controllers/omniauth", "app/controllers" if omniauth?
96
110
  end
97
111
 
98
112
  def create_views
99
- if options.api
113
+ if options.api?
100
114
  directory "erb/identity_mailer", "app/views/identity_mailer"
101
115
  directory "erb/session_mailer", "app/views/session_mailer"
102
116
  else
@@ -109,40 +123,36 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
109
123
  end
110
124
 
111
125
  def add_routes
112
- unless options.skip_routes
113
- route "resource :sudo, only: [:new, :create]"
114
- route "resource :registration, only: :destroy"
115
- route "resource :password_reset, only: [:new, :edit, :create, :update]"
116
- route "resource :password, only: [:edit, :update]"
117
- route "resource :email_verification, only: [:edit, :create]"
118
- route "resource :email, only: [:edit, :update]"
119
- route "resources :sessions, only: [:index, :show, :destroy]"
120
- route "post 'sign_up', to: 'registrations#create'"
121
- route "get 'sign_up', to: 'registrations#new'" unless options.api?
122
- route "post 'sign_in', to: 'sessions#create'"
123
- route "get 'sign_in', to: 'sessions#new'" unless options.api?
126
+ if omniauth?
127
+ route "post '/auth/:provider/callback', to: 'omniauth_sessions#create'"
128
+ route "get '/auth/:provider/callback', to: 'omniauth_sessions#create'"
129
+ route "get '/auth/failure', to: 'omniauth_sessions#failure'"
124
130
  end
131
+
132
+ route "resource :sudo, only: [:new, :create]"
133
+ route "resource :registration, only: :destroy"
134
+ route "resource :password_reset, only: [:new, :edit, :create, :update]"
135
+ route "resource :password, only: [:edit, :update]"
136
+ route "resource :email_verification, only: [:edit, :create]"
137
+ route "resource :email, only: [:edit, :update]"
138
+ route "resources :sessions, only: [:index, :show, :destroy]"
139
+ route "post 'sign_up', to: 'registrations#create'"
140
+ route "get 'sign_up', to: 'registrations#new'" unless options.api?
141
+ route "post 'sign_in', to: 'sessions#create'"
142
+ route "get 'sign_in', to: 'sessions#new'" unless options.api?
125
143
  end
126
144
 
127
145
  def create_test_files
128
- directory "#{test_framework}/controllers/#{format_folder}", "test/controllers"
129
- directory "#{system_tests}/system", "test/system" if system_tests?
146
+ directory "test_unit/controllers/#{format_folder}", "test/controllers"
147
+ directory "test_unit/system", "test/system" unless options.api?
130
148
  end
131
149
 
132
150
  private
133
151
  def format_folder
134
- options.api ? "api" : "html"
135
- end
136
-
137
- def test_framework
138
- options.test_framework
139
- end
140
-
141
- def system_tests
142
- options.system_tests
152
+ options.api? ? "api" : "html"
143
153
  end
144
154
 
145
- def system_tests?
146
- !options.api? && options.system_tests
155
+ def omniauth?
156
+ options.omniauth? && !options.api?
147
157
  end
148
158
  end
@@ -0,0 +1,3 @@
1
+ Rails.application.config.middleware.use OmniAuth::Builder do
2
+ provider :developer unless Rails.env.production? # You should replace it with your provider
3
+ end
@@ -0,0 +1,15 @@
1
+ production: &production
2
+ url: <%= ENV.fetch("REDIS_URL", "redis://127.0.0.1:6379/0") %>
3
+ timeout: 1
4
+
5
+ development: &development
6
+ url: <%= ENV.fetch("REDIS_URL", "redis://127.0.0.1:6379/0") %>
7
+ timeout: 1
8
+
9
+ # You can also specify host, port, and db instead of url
10
+ # host: <%= ENV.fetch("REDIS_SHARED_HOST", "127.0.0.1") %>
11
+ # port: <%= ENV.fetch("REDIS_SHARED_PORT", "6379") %>
12
+ # db: <%= ENV.fetch("REDIS_SHARED_DB", "11") %>
13
+
14
+ test:
15
+ <<: *development
@@ -25,8 +25,7 @@ class SessionsController < ApplicationController
25
25
  end
26
26
 
27
27
  def destroy
28
- @session.destroy
29
- redirect_to sessions_path, notice: "That session has been logged out"
28
+ @session.destroy; redirect_to(sessions_path, notice: "That session has been logged out")
30
29
  end
31
30
 
32
31
  private
@@ -5,7 +5,11 @@ class SudosController < ApplicationController
5
5
  def create
6
6
  session = Current.session
7
7
 
8
+ <% if options.omniauth? -%>
9
+ if session.<%= singular_table_name %>.authenticate(params[:password]) || session.<%= singular_table_name %>.provider
10
+ <% else -%>
8
11
  if session.<%= singular_table_name %>.authenticate(params[:password])
12
+ <% end -%>
9
13
  session.update!(sudo_at: Time.current); redirect_to(params[:proceed_to_url])
10
14
  else
11
15
  redirect_to new_sudo_path(proceed_to_url: params[:proceed_to_url]), alert: "The password you entered is incorrect"
@@ -0,0 +1,38 @@
1
+ class OmniauthSessionsController < ApplicationController
2
+ skip_before_action :verify_authenticity_token
3
+ skip_before_action :authenticate
4
+
5
+ def create
6
+ @<%= singular_table_name %> = <%= class_name %>.where(omniauth_params).first_or_initialize(<%= "#{singular_table_name}_params" %>)
7
+
8
+ if @<%= singular_table_name %>.save
9
+ session = @<%= singular_table_name %>.sessions.create!(session_params)
10
+ cookies.signed.permanent[:session_token] = { value: session.id, httponly: true }
11
+
12
+ redirect_to root_path, notice: "Signed in successfully"
13
+ else
14
+ redirect_to sign_in_path, alert: "Authentication failed"
15
+ end
16
+ end
17
+
18
+ def failure
19
+ redirect_to sign_in_path, alert: params[:message]
20
+ end
21
+
22
+ private
23
+ def omniauth_params
24
+ { provider: omniauth.provider, uid: omniauth.uid }
25
+ end
26
+
27
+ def <%= "#{singular_table_name}_params" %>
28
+ { email: omniauth.info.email, password: SecureRandom::base58, verified: true }
29
+ end
30
+
31
+ def session_params
32
+ { user_agent: request.user_agent, ip_address: request.remote_ip, sudo_at: Time.current }
33
+ end
34
+
35
+ def omniauth
36
+ request.env["omniauth.auth"]
37
+ end
38
+ end
@@ -18,6 +18,11 @@
18
18
  <%%= form.submit "Sign in" %>
19
19
  </div>
20
20
  <%% end %>
21
+ <% if options.omniauth? %>
22
+ <div>
23
+ <%%= button_to "Sign in with OmniAuth", "/auth/developer", "data-turbo" => false %>
24
+ </div>
25
+ <% end -%>
21
26
 
22
27
  <br>
23
28
 
@@ -8,7 +8,7 @@ class IdentityMailer < ApplicationMailer
8
8
 
9
9
  def email_verify_confirmation
10
10
  @<%= singular_table_name %> = params[:<%= singular_table_name %>]
11
- @signed_id = @<%= singular_table_name %>.signed_id(purpose: @<%= singular_table_name %>.email, expires_in: 3.days)
11
+ @signed_id = @<%= singular_table_name %>.signed_id(purpose: @<%= singular_table_name %>.email, expires_in: 2.days)
12
12
 
13
13
  mail to: @<%= singular_table_name %>.email, subject: "Verify your email"
14
14
  end
@@ -0,0 +1,8 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
2
+ def change
3
+ add_column :<%= table_name %>, :provider, :string
4
+ add_column :<%= table_name %>, :uid, :string
5
+ end
6
+
7
+ add_index :<%= table_name %>, [:provider, :uid], unique: true
8
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authentication-zero
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nixon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-28 00:00:00.000000000 Z
11
+ date: 2022-03-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -32,6 +32,8 @@ files:
32
32
  - lib/authentication_zero/version.rb
33
33
  - lib/generators/authentication/USAGE
34
34
  - lib/generators/authentication/authentication_generator.rb
35
+ - lib/generators/authentication/templates/config/initializers/omniauth.rb
36
+ - lib/generators/authentication/templates/config/redis/shared.yml
35
37
  - lib/generators/authentication/templates/controllers/api/email_verifications_controller.rb.tt
36
38
  - lib/generators/authentication/templates/controllers/api/emails_controller.rb.tt
37
39
  - lib/generators/authentication/templates/controllers/api/password_resets_controller.rb.tt
@@ -46,6 +48,7 @@ files:
46
48
  - lib/generators/authentication/templates/controllers/html/registrations_controller.rb.tt
47
49
  - lib/generators/authentication/templates/controllers/html/sessions_controller.rb.tt
48
50
  - lib/generators/authentication/templates/controllers/html/sudos_controller.rb.tt
51
+ - lib/generators/authentication/templates/controllers/omniauth/omniauth_sessions_controller.rb.tt
49
52
  - lib/generators/authentication/templates/erb/emails/edit.html.erb.tt
50
53
  - lib/generators/authentication/templates/erb/identity_mailer/email_verify_confirmation.html.erb.tt
51
54
  - lib/generators/authentication/templates/erb/identity_mailer/email_verify_confirmation.text.erb.tt
@@ -62,6 +65,7 @@ files:
62
65
  - lib/generators/authentication/templates/erb/sudos/new.html.erb.tt
63
66
  - lib/generators/authentication/templates/mailers/identity_mailer.rb.tt
64
67
  - lib/generators/authentication/templates/mailers/session_mailer.rb.tt
68
+ - lib/generators/authentication/templates/migrations/add_omniauth_migration.rb.tt
65
69
  - lib/generators/authentication/templates/migrations/create_sessions_migration.rb.tt
66
70
  - lib/generators/authentication/templates/migrations/create_table_migration.rb.tt
67
71
  - lib/generators/authentication/templates/models/current.rb.tt