simple_auth 3.1.4 → 3.2.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: f49f3b991fd189a65c444c7fe0bbf4b6312ad268d15d09718554b17abede88de
4
- data.tar.gz: 4b89cc2082720e7b13c778393cbd353737855e913417a55f520443cbcbbafd25
3
+ metadata.gz: 767e5c4765e914fc1e310fe57f9ad0491ccfc7f3eff8b22c0002877bb4ddb262
4
+ data.tar.gz: f2ffea82bbf55a41c705bddb67b638f7df1cfb1f4abc1918c4d89d7b46bde019
5
5
  SHA512:
6
- metadata.gz: 3bc6961ef9d45a04f41988e5f1abaa47784edec75d74f49655fdc214285c16c63c2d0aca6d80aa669e7d21fad74434c5f0a570ba1a557a9c14e1d0822063154e
7
- data.tar.gz: a23600ef945fb6675390133b84b6219edafa10a11ab524856a6535162ee8726ad007b5d0613af48706b461d8e4318a632170425533ebb8c2b6cd56af46145792
6
+ metadata.gz: b1489bc14e6f5b787902ad3540e7236e1112a71939f192cdf2e100af5ce0ca302794200e307c517334ef8fe42ec87ade787cfb609f96c6cee91093431741a103
7
+ data.tar.gz: fe1ee4d957ac0a892cedd74efbc7a0f671f1d9adeb6a11f268fc9d4cba7e8a45aac9d8b9a1c68798dde41dd17fb7c3f6ba71062c63320a12635816855016fa1d
@@ -19,31 +19,26 @@ jobs:
19
19
  strategy:
20
20
  fail-fast: false
21
21
  matrix:
22
- ruby: ["2.7", "3.0", "3.1"]
22
+ ruby: ["3.3", "3.4", "4.0"]
23
23
  gemfile:
24
24
  - Gemfile
25
- - gemfiles/rails_7_0.gemfile
26
- - gemfiles/rails_6_1.gemfile
27
- - gemfiles/rails_6_0.gemfile
25
+ - gemfiles/rails_8_0.gemfile
26
+ - gemfiles/rails_8_1.gemfile
28
27
 
29
28
  services:
30
29
  postgres:
31
30
  image: postgres:11.5
32
31
  ports: ["5432:5432"]
33
- options:
34
- --health-cmd pg_isready --health-interval 10s --health-timeout 5s
35
- --health-retries 5
32
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
36
33
 
37
34
  steps:
38
- - uses: actions/checkout@v3
35
+ - uses: actions/checkout@v4
39
36
 
40
37
  - uses: actions/cache@v3
41
38
  with:
42
39
  path: vendor/bundle
43
40
  key: >
44
- ${{ runner.os }}-${{ matrix.ruby }}-gems-${{
45
- hashFiles(matrix.gemfile) }}
46
-
41
+ ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles(matrix.gemfile) }} #magic___^_^___line
47
42
  - name: Set up Ruby
48
43
  uses: ruby/setup-ruby@v1
49
44
  with:
data/.rubocop.yml CHANGED
@@ -3,7 +3,11 @@ inherit_gem:
3
3
  rubocop-fnando: .rubocop.yml
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 2.7
6
+ TargetRubyVersion: 3.3
7
+ NewCops: enable
7
8
  Exclude:
8
9
  - gemfiles/**/*
9
10
  - vendor/**/*
11
+
12
+ Minitest/EmptyLineBeforeAssertionMethods:
13
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## v3.2.0
4
+
5
+ - Bump up ruby requirement to 3.3.
6
+ - Add support for ActionController::API
7
+
3
8
  ## v3.1.4
4
9
 
5
10
  - Add `authenticate(scope, condition, &block)`, so you can restrict routes
data/README.md CHANGED
@@ -150,6 +150,54 @@ end
150
150
  In this case, `:admin` is the scope and the lambda will only be called whenever
151
151
  there's a valid record associated with that record.
152
152
 
153
+ ### API Controllers
154
+
155
+ simple_auth supports `ActionController::API`-based controllers. Include the
156
+ `SimpleAuth::ActionController::API` module in your API controller:
157
+
158
+ ```ruby
159
+ class ApiController < ActionController::API
160
+ include SimpleAuth::ActionController::API
161
+
162
+ before_action :authenticate_via_token
163
+ before_action :require_logged_user
164
+
165
+ def index
166
+ render json: {message: "hello there"}
167
+ end
168
+
169
+ private def authenticate_via_token
170
+ user = User.find_by_api_token(id: request.headers["Authorization"])
171
+
172
+ return render(plain: "401 Unauthorized", status: :unauthorized) unless user
173
+
174
+ SimpleAuth::Session.create(scope: "user", session:, record: user)
175
+ end
176
+ end
177
+ ```
178
+
179
+ By default, unauthorized requests receive a `401 Unauthorized` plain text
180
+ response. You can override `render_unauthorized_access(authorization)` to
181
+ customize this behavior. The `authorization` object gives you access to
182
+ `authorization.error_message`, which contains the translated error message for
183
+ the failed authorization:
184
+
185
+ ```ruby
186
+ class ApiController < ActionController::API
187
+ include SimpleAuth::ActionController::API
188
+
189
+ private def render_unauthorized_access(authorization)
190
+ render json: {error: authorization.error_message}, status: :unauthorized
191
+ end
192
+ end
193
+ ```
194
+
195
+ > [!NOTE]
196
+ >
197
+ > `SimpleAuth::ActionController::API` defines a stub session object that's just
198
+ > a hash, so the user record can be resolved across multiple calls within the
199
+ > same request.
200
+
153
201
  ### Translations
154
202
 
155
203
  These are the translations you'll need:
@@ -159,8 +207,8 @@ These are the translations you'll need:
159
207
  en:
160
208
  simple_auth:
161
209
  user:
162
- need_to_be_logged_in: "You need to be logged in"
163
- not_authorized: "You don't have permission to access this page"
210
+ unlogged_in: "You need to be logged in"
211
+ unauthorized: "You don't have permission to access this page"
164
212
  ```
165
213
 
166
214
  If you don't set these translations, a default message will be used.
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ gemspec path: ".."
5
+
6
+ gem "rails", "~> 8.0.0"
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ gemspec path: ".."
5
+
6
+ gem "rails", "~> 8.1.0"
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleAuth
4
+ module ActionController
5
+ module API
6
+ extend ActiveSupport::Concern
7
+ include SimpleAuth::ActionController
8
+
9
+ included do
10
+ undef_method :simple_auth_redirect_logged_scope
11
+ undef_method :return_to
12
+
13
+ SimpleAuth.config.scopes.each do |scope|
14
+ undef_method :"redirect_logged_#{scope}"
15
+ end
16
+ end
17
+
18
+ # A stub session so we can persist the record id between different calls
19
+ # to fetch the record.
20
+ private def session
21
+ @session ||= {}
22
+ end
23
+
24
+ private def render_unauthorized_access(*)
25
+ render plain: "401 Unauthorized", status: :unauthorized
26
+ end
27
+ end
28
+ end
29
+ end
@@ -18,7 +18,7 @@ module SimpleAuth
18
18
  valid_session? && authorized?
19
19
  end
20
20
 
21
- def message
21
+ def error_message
22
22
  return if valid?
23
23
  return unauthorized_message unless authorized?
24
24
 
@@ -26,11 +26,11 @@ module SimpleAuth
26
26
  end
27
27
 
28
28
  private def valid_session?
29
- controller.send("#{scope}_session").valid?
29
+ controller.send(:"#{scope}_session").valid?
30
30
  end
31
31
 
32
32
  private def authorized?
33
- controller.send("authorized_#{scope}?")
33
+ controller.send(:"authorized_#{scope}?")
34
34
  end
35
35
 
36
36
  private def unauthorized_message
@@ -12,7 +12,10 @@ module SimpleAuth
12
12
  def install_simple_auth_scopes
13
13
  SimpleAuth.config.scopes.each do |scope|
14
14
  install_simple_auth_scope(scope)
15
- helper_method "current_#{scope}", "#{scope}_logged_in?"
15
+
16
+ if respond_to?(:helper_method)
17
+ helper_method("current_#{scope}", "#{scope}_logged_in?")
18
+ end
16
19
  end
17
20
  end
18
21
 
@@ -40,15 +43,15 @@ module SimpleAuth
40
43
  end
41
44
  RUBY
42
45
 
43
- define_method "authorized_#{scope}?" do
46
+ define_method :"authorized_#{scope}?" do
44
47
  true
45
48
  end
46
49
 
47
- define_method "require_logged_#{scope}" do
50
+ define_method :"require_logged_#{scope}" do
48
51
  simple_auth_require_logged_scope(scope)
49
52
  end
50
53
 
51
- define_method "redirect_logged_#{scope}" do
54
+ define_method :"redirect_logged_#{scope}" do
52
55
  simple_auth_redirect_logged_scope(scope)
53
56
  end
54
57
  end
@@ -63,21 +66,25 @@ module SimpleAuth
63
66
  end
64
67
 
65
68
  private def simple_auth_require_logged_scope(scope)
66
- action = RequireLoginAction.new(self, scope)
69
+ authorization = RequireLoginAction.new(self, scope)
67
70
 
68
- return if action.valid?
71
+ return if authorization.valid?
69
72
 
70
- reset_session
71
- flash[simple_auth.flash_message_key] = action.message
72
- session[:return_to] = request.fullpath if request.get?
73
- redirect_to instance_eval(&simple_auth.login_url)
73
+ render_unauthorized_access(authorization)
74
74
  end
75
75
 
76
76
  private def simple_auth_redirect_logged_scope(scope)
77
- scope_session = send("#{scope}_session")
77
+ scope_session = send(:"#{scope}_session")
78
78
  return unless scope_session.valid?
79
79
 
80
80
  redirect_to instance_eval(&simple_auth.logged_url)
81
81
  end
82
+
83
+ private def render_unauthorized_access(authorization)
84
+ reset_session
85
+ flash[simple_auth.flash_message_key] = authorization.error_message
86
+ session[:return_to] = request.fullpath if request.get?
87
+ redirect_to instance_eval(&simple_auth.login_url)
88
+ end
82
89
  end
83
90
  end
@@ -22,6 +22,7 @@ module SimpleAuth
22
22
 
23
23
  def install_helpers!
24
24
  ::ActionController::Base.include SimpleAuth::ActionController
25
+ ::ActionController::API.include SimpleAuth::ActionController::API
25
26
  end
26
27
  end
27
28
  end
@@ -6,8 +6,8 @@ module SimpleAuth
6
6
  @record_not_found_exceptions ||= []
7
7
  end
8
8
 
9
- def self.create(**kwargs)
10
- new(**kwargs)
9
+ def self.create(**)
10
+ new(**)
11
11
  end
12
12
 
13
13
  def initialize(scope:, session:, record: nil)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleAuth
4
- VERSION = "3.1.4"
4
+ VERSION = "3.2.0"
5
5
  end
data/lib/simple_auth.rb CHANGED
@@ -10,6 +10,7 @@ module SimpleAuth
10
10
  require "simple_auth/config"
11
11
  require "simple_auth/railtie"
12
12
  require "simple_auth/action_controller"
13
+ require "simple_auth/action_controller/api"
13
14
  require "simple_auth/routing_mapper"
14
15
  require "simple_auth/action_controller/require_login_action"
15
16
  require "simple_auth/session"
data/simple_auth.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.homepage = "http://rubygems.org/gems/simple_auth"
12
12
  s.summary = "A simple authentication system for Rails apps"
13
13
  s.description = s.summary
14
- s.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
14
+ s.required_ruby_version = Gem::Requirement.new(">= 3.3.0")
15
15
 
16
16
  github_url = "https://github.com/fnando/simple_auth"
17
17
  github_tree_url = "#{github_url}/tree/v#{s.version}"
@@ -25,7 +25,6 @@ Gem::Specification.new do |s|
25
25
  s.metadata["rubygems_mfa_required"] = "true"
26
26
 
27
27
  s.files = `git ls-files`.split("\n")
28
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
29
28
  s.executables = `git ls-files -- bin/*`
30
29
  .split("\n")
31
30
  .map {|f| File.basename(f) }
@@ -34,7 +33,7 @@ Gem::Specification.new do |s|
34
33
  s.add_dependency "globalid"
35
34
  s.add_dependency "rails"
36
35
  s.add_development_dependency "activerecord"
37
- s.add_development_dependency "bcrypt", "~> 3.1.7"
36
+ s.add_development_dependency "bcrypt"
38
37
  s.add_development_dependency "minitest"
39
38
  s.add_development_dependency "minitest-utils"
40
39
  s.add_development_dependency "pry-meta"
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class ApiControllerTest < ActionController::TestCase
6
+ setup do
7
+ @routes = Rails.application.routes
8
+ User.delete_all
9
+ end
10
+
11
+ def create_records
12
+ admin = User.create!(
13
+ password: "test",
14
+ email: "admin@example.com",
15
+ admin: true
16
+ )
17
+ user = User.create!(
18
+ password: "test",
19
+ email: "john@example.com",
20
+ admin: false
21
+ )
22
+
23
+ [admin, user]
24
+ end
25
+
26
+ test "renders unauthorized for invalid api keys" do
27
+ get :index
28
+
29
+ assert_equal 401, response.status
30
+ assert_equal "401 Unauthorized", response.body
31
+ end
32
+
33
+ test "renders unauthorized for unauthorized users" do
34
+ _, user = *create_records
35
+ @request.headers["Authorization"] = user.id.to_s
36
+ get :index
37
+
38
+ assert_equal 401, response.status
39
+ assert_equal "401 Unauthorized", response.body
40
+ end
41
+
42
+ test "renders page for authorized users" do
43
+ admin, _ = *create_records
44
+ @request.headers["Authorization"] = admin.id.to_s
45
+ get :index
46
+
47
+ assert_equal 200, response.status
48
+ assert_equal %[{"message":"hello there"}], response.body
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApiController < ActionController::API
4
+ include SimpleAuth::ActionController::API
5
+
6
+ before_action :validate_api_key
7
+ before_action :require_logged_user
8
+
9
+ def index
10
+ render json: {message: "hello there"}
11
+ end
12
+
13
+ private def authorized_user?
14
+ current_user&.admin?
15
+ end
16
+
17
+ private def validate_api_key
18
+ id = request.headers["Authorization"]
19
+ user = User.find_by(id:)
20
+
21
+ return render(plain: "401 Unauthorized", status: :unauthorized) unless user
22
+
23
+ SimpleAuth::Session.create(
24
+ scope: "user",
25
+ session:,
26
+ record: User.find_by(id:)
27
+ )
28
+ end
29
+ end
@@ -8,7 +8,7 @@ Rails.application.routes.draw do
8
8
  post "/start-session", to: "sessions#create_session"
9
9
  post "/terminate-session", to: "sessions#terminate_session"
10
10
 
11
- authenticate :admin, ->(u) { u.admin? } do
11
+ authenticate :admin, lambda(&:admin?) do
12
12
  get "/only/admins", to: ->(_env) { [200, {}, ["OK"]] }
13
13
  end
14
14
 
@@ -35,4 +35,6 @@ Rails.application.routes.draw do
35
35
  get :log_in_with_admin_flag
36
36
  end
37
37
  end
38
+
39
+ get "api", to: "api#index"
38
40
  end
data/test/test_helper.rb CHANGED
@@ -18,4 +18,4 @@ require "active_record"
18
18
  ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
19
19
  require "./test/support/schema"
20
20
 
21
- Dir["./test/support/**/*.rb"].sort.each {|file| require file }
21
+ Dir["./test/support/**/*.rb"].each {|file| require file }
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.4
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-01-09 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: globalid
@@ -56,16 +55,16 @@ dependencies:
56
55
  name: bcrypt
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
- - - "~>"
58
+ - - ">="
60
59
  - !ruby/object:Gem::Version
61
- version: 3.1.7
60
+ version: '0'
62
61
  type: :development
63
62
  prerelease: false
64
63
  version_requirements: !ruby/object:Gem::Requirement
65
64
  requirements:
66
- - - "~>"
65
+ - - ">="
67
66
  - !ruby/object:Gem::Version
68
- version: 3.1.7
67
+ version: '0'
69
68
  - !ruby/object:Gem::Dependency
70
69
  name: minitest
71
70
  requirement: !ruby/object:Gem::Requirement
@@ -194,8 +193,11 @@ files:
194
193
  - gemfiles/rails_6_0.gemfile
195
194
  - gemfiles/rails_6_1.gemfile
196
195
  - gemfiles/rails_7_0.gemfile
196
+ - gemfiles/rails_8_0.gemfile
197
+ - gemfiles/rails_8_1.gemfile
197
198
  - lib/simple_auth.rb
198
199
  - lib/simple_auth/action_controller.rb
200
+ - lib/simple_auth/action_controller/api.rb
199
201
  - lib/simple_auth/action_controller/require_login_action.rb
200
202
  - lib/simple_auth/config.rb
201
203
  - lib/simple_auth/generator.rb
@@ -206,11 +208,13 @@ files:
206
208
  - lib/simple_auth/version.rb
207
209
  - simple_auth.gemspec
208
210
  - test/controllers/admin/dashboard_controller_test.rb
211
+ - test/controllers/api_controller_test.rb
209
212
  - test/controllers/dashboard_controller_test.rb
210
213
  - test/controllers/pages_controller_test.rb
211
214
  - test/generators/install_test.rb
212
215
  - test/requests/admin_test.rb
213
216
  - test/support/dummy/app/controllers/admin/dashboard_controller.rb
217
+ - test/support/dummy/app/controllers/api_controller.rb
214
218
  - test/support/dummy/app/controllers/application_controller.rb
215
219
  - test/support/dummy/app/controllers/dashboard_controller.rb
216
220
  - test/support/dummy/app/controllers/pages_controller.rb
@@ -227,12 +231,11 @@ licenses: []
227
231
  metadata:
228
232
  homepage_uri: http://rubygems.org/gems/simple_auth
229
233
  bug_tracker_uri: https://github.com/fnando/simple_auth/issues
230
- source_code_uri: https://github.com/fnando/simple_auth/tree/v3.1.4
231
- changelog_uri: https://github.com/fnando/simple_auth/tree/v3.1.4/CHANGELOG.md
232
- documentation_uri: https://github.com/fnando/simple_auth/tree/v3.1.4/README.md
233
- license_uri: https://github.com/fnando/simple_auth/tree/v3.1.4/LICENSE.md
234
+ source_code_uri: https://github.com/fnando/simple_auth/tree/v3.2.0
235
+ changelog_uri: https://github.com/fnando/simple_auth/tree/v3.2.0/CHANGELOG.md
236
+ documentation_uri: https://github.com/fnando/simple_auth/tree/v3.2.0/README.md
237
+ license_uri: https://github.com/fnando/simple_auth/tree/v3.2.0/LICENSE.md
234
238
  rubygems_mfa_required: 'true'
235
- post_install_message:
236
239
  rdoc_options: []
237
240
  require_paths:
238
241
  - lib
@@ -240,32 +243,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
240
243
  requirements:
241
244
  - - ">="
242
245
  - !ruby/object:Gem::Version
243
- version: 2.7.0
246
+ version: 3.3.0
244
247
  required_rubygems_version: !ruby/object:Gem::Requirement
245
248
  requirements:
246
249
  - - ">="
247
250
  - !ruby/object:Gem::Version
248
251
  version: '0'
249
252
  requirements: []
250
- rubygems_version: 3.4.1
251
- signing_key:
253
+ rubygems_version: 4.0.3
252
254
  specification_version: 4
253
255
  summary: A simple authentication system for Rails apps
254
- test_files:
255
- - test/controllers/admin/dashboard_controller_test.rb
256
- - test/controllers/dashboard_controller_test.rb
257
- - test/controllers/pages_controller_test.rb
258
- - test/generators/install_test.rb
259
- - test/requests/admin_test.rb
260
- - test/support/dummy/app/controllers/admin/dashboard_controller.rb
261
- - test/support/dummy/app/controllers/application_controller.rb
262
- - test/support/dummy/app/controllers/dashboard_controller.rb
263
- - test/support/dummy/app/controllers/pages_controller.rb
264
- - test/support/dummy/app/controllers/sessions_controller.rb
265
- - test/support/dummy/app/models/user.rb
266
- - test/support/dummy/config/application.rb
267
- - test/support/dummy/config/initializers/simple_auth.rb
268
- - test/support/dummy/config/routes.rb
269
- - test/support/schema.rb
270
- - test/test_helper.rb
271
- - test/unit/session_test.rb
256
+ test_files: []