auth_strategist 0.6.0 → 0.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 +5 -5
- data/.rubocop.yml +7 -4
- data/Gemfile +2 -0
- data/README.md +6 -35
- data/Rakefile +2 -0
- data/auth_strategist.gemspec +9 -5
- data/bin/console +1 -0
- data/lib/auth_strategist.rb +10 -4
- data/lib/auth_strategist/authorization.rb +9 -11
- data/lib/auth_strategist/build_strategy.rb +45 -0
- data/lib/auth_strategist/configuration.rb +5 -21
- data/lib/auth_strategist/errors/authorized_not_implemented.rb +11 -0
- data/lib/auth_strategist/errors/unauthorized.rb +2 -0
- data/lib/auth_strategist/registry.rb +7 -0
- data/lib/auth_strategist/strategy_interface.rb +23 -37
- data/lib/auth_strategist/version.rb +3 -1
- data/lib/generators/auth_strategist/install_generator.rb +3 -1
- data/lib/generators/auth_strategist/templates/initializer.rb +10 -9
- data/spec/auth_strategist_spec.rb +6 -46
- data/spec/authorization_spec.rb +33 -4
- data/spec/build_strategy_spec.rb +28 -0
- data/spec/configuration_spec.rb +3 -13
- data/spec/dummy/controllers/dummy_controller.rb +2 -0
- data/spec/dummy/strategies/dummy_strategy.rb +4 -2
- data/spec/dummy/strategies/missing_authorized.rb +5 -0
- data/spec/dummy/strategies/not_registered.rb +2 -0
- data/spec/spec_helper.rb +11 -15
- data/spec/strategy_interface_spec.rb +9 -113
- metadata +61 -20
- data/lib/auth_strategist/authorize.rb +0 -41
- data/lib/auth_strategist/configuration/strategies_registry.rb +0 -11
- data/spec/authorize_spec.rb +0 -74
- data/spec/dummy/strategies/missing_authorize.rb +0 -3
- data/spec/factories/authorize.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5618d9f7fb8c6c8992f89206742c72649013a408ea63fc0b7a8dad63f1726f9c
|
4
|
+
data.tar.gz: 994ab4e70f2f184b163e6082553bfa88da26de82ffb7bce4800733fab5b8e35c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db8966f7cc51e57fc573528f3b99a260b0b61cbddfe79a07f64316c865e5a11a2c393b3bdc74b05d85f7bfbf09361f5e5914722ce8a5d020bd89f936a93094c4
|
7
|
+
data.tar.gz: a5220e01c51d35a7c89efa402f8923a6936e3befe2fd3e3d07be9a7beaddf82d5f9fbd8fa4179be5715cc738a33432f0865364262cbacc79b4a99f3e7459d45d
|
data/.rubocop.yml
CHANGED
@@ -1,17 +1,20 @@
|
|
1
|
-
Metrics/
|
1
|
+
Metrics/BlockLength:
|
2
2
|
Exclude:
|
3
|
-
-
|
3
|
+
- spec/**/*
|
4
4
|
|
5
5
|
Metrics/MethodLength:
|
6
6
|
Max: 15
|
7
|
-
Exclude:
|
8
|
-
- './lib/auth_strategist/strategy_interface.rb'
|
9
7
|
|
10
8
|
Metrics/LineLength:
|
11
9
|
Max: 100
|
10
|
+
Exclude:
|
11
|
+
- spec/**/*
|
12
12
|
|
13
13
|
Style/Documentation:
|
14
14
|
Enabled: false
|
15
15
|
|
16
16
|
Style/SignalException:
|
17
17
|
EnforcedStyle: only_raise
|
18
|
+
|
19
|
+
Style/DoubleNegation:
|
20
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
[gem]: https://github.com/buszu/auth_strategist
|
2
|
-
[codeclimate]: https://codeclimate.com/github/buszu/auth_strategist/
|
3
2
|
|
4
3
|
AuthStrategist
|
5
4
|
======
|
6
|
-
[](https://codeclimate.com/github/buszu/auth_strategist)
|
7
5
|
[](http://badge.fury.io/rb/auth_strategist)
|
8
6
|
|
9
7
|
AuthStrategist is a simple gem to define and use authorization strategies.
|
@@ -22,28 +20,14 @@ Generate initializer if using Rails:
|
|
22
20
|
|
23
21
|
$ rails g auth_strategist:install
|
24
22
|
|
25
|
-
Or install it yourself as:
|
26
|
-
|
27
|
-
$ gem install auth_strategist
|
28
|
-
|
29
23
|
## Configuration
|
30
24
|
|
31
25
|
```ruby
|
32
26
|
AuthStrategist.configure do |c|
|
33
|
-
# Set
|
34
|
-
# Optional and empty by default.
|
35
|
-
c.default_strategy_components = [:application, :ref]
|
36
|
-
|
37
|
-
# Set strategies directory
|
27
|
+
# Set strategies directory and load them
|
38
28
|
# Required if strategies files are not already loaded
|
39
29
|
c.strategies_path = 'lib/auth_strategist/strategies'
|
40
|
-
|
41
|
-
# Register your strategies
|
42
|
-
# Required for each strategy you have defined
|
43
|
-
c.strategies do |s|
|
44
|
-
# E.g. OwnershipAuthStrategy will be available under :ownership key
|
45
|
-
s.ownership = OwnershipAuthStrategy
|
46
|
-
end
|
30
|
+
c.load_strategies!
|
47
31
|
end
|
48
32
|
```
|
49
33
|
|
@@ -57,32 +41,19 @@ class OwnershipAuthStrategy
|
|
57
41
|
|
58
42
|
define_components :user, :item
|
59
43
|
|
60
|
-
def
|
61
|
-
|
44
|
+
def authorized?
|
45
|
+
item.user_id != user.id
|
62
46
|
end
|
63
47
|
end
|
64
48
|
```
|
65
49
|
* Register it
|
66
50
|
```ruby
|
67
51
|
AuthStrategist.strategies do |s|
|
68
|
-
s.ownership
|
52
|
+
s.register :ownership, OwnershipAuthStrategy
|
69
53
|
end
|
70
54
|
```
|
71
|
-
|
72
|
-
```ruby
|
73
|
-
AuthStrategist.configure do |c|
|
74
|
-
c.strategies do |s|
|
75
|
-
s.ownership = OwnershipAuthStrategy
|
76
|
-
end
|
77
|
-
end
|
78
|
-
```
|
55
|
+
|
79
56
|
### Using strategies
|
80
|
-
* Using strategy by calling authorization Service Object
|
81
|
-
```ruby
|
82
|
-
AuthStrategist::Authorize.call strategy: :ownership,
|
83
|
-
user: current_user,
|
84
|
-
item: book
|
85
|
-
```
|
86
57
|
* Using strategy with authorize! method
|
87
58
|
```ruby
|
88
59
|
class SomethingsController < ApplicationController
|
data/Rakefile
CHANGED
data/auth_strategist.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
$LOAD_PATH.push File.expand_path('
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
4
|
|
5
5
|
require 'auth_strategist/version'
|
6
6
|
|
@@ -18,8 +18,12 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
19
19
|
s.require_paths = ['lib']
|
20
20
|
|
21
|
-
s.
|
22
|
-
s.
|
23
|
-
|
21
|
+
s.add_dependency 'dry-container', '~> 0.7'
|
22
|
+
s.add_dependency 'dry-initializer', '~> 3.0'
|
23
|
+
|
24
|
+
s.add_development_dependency 'bundler'
|
25
|
+
s.add_development_dependency 'rake'
|
26
|
+
s.add_development_dependency 'rspec'
|
24
27
|
s.add_development_dependency 'rspec-its'
|
28
|
+
s.add_development_dependency 'rubocop'
|
25
29
|
end
|
data/bin/console
CHANGED
data/lib/auth_strategist.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry-initializer'
|
4
|
+
require 'dry-container'
|
5
|
+
|
1
6
|
require 'auth_strategist/version'
|
2
7
|
require 'auth_strategist/configuration'
|
3
|
-
require 'auth_strategist/
|
8
|
+
require 'auth_strategist/registry'
|
4
9
|
require 'auth_strategist/errors/unauthorized'
|
10
|
+
require 'auth_strategist/errors/authorized_not_implemented'
|
5
11
|
require 'auth_strategist/strategy_interface'
|
6
|
-
require 'auth_strategist/
|
12
|
+
require 'auth_strategist/build_strategy'
|
7
13
|
require 'auth_strategist/authorization'
|
8
14
|
|
9
15
|
module AuthStrategist
|
@@ -18,8 +24,8 @@ module AuthStrategist
|
|
18
24
|
end
|
19
25
|
|
20
26
|
def strategies
|
21
|
-
|
22
|
-
|
27
|
+
yield(Registry) if block_given?
|
28
|
+
Registry
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -1,17 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AuthStrategist
|
2
4
|
module Authorization
|
3
|
-
def
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
private
|
5
|
+
def authorize!(options = {})
|
6
|
+
strategy = AuthStrategist::BuildStrategy.call(options)
|
7
|
+
strategy.authorize!
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
10
|
+
def can?(options = {})
|
11
|
+
strategy = AuthStrategist::BuildStrategy.call(options)
|
12
|
+
strategy.authorized?
|
15
13
|
end
|
16
14
|
end
|
17
15
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuthStrategist
|
4
|
+
class BuildStrategy
|
5
|
+
def self.call(params = {})
|
6
|
+
new.call(params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(params = {})
|
10
|
+
choose_strategy(params)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
attr_reader :strategy
|
16
|
+
|
17
|
+
def choose_strategy(params = {})
|
18
|
+
strategy_key = params[:strategy]
|
19
|
+
raise(strategy_key_nil) if strategy_key.nil?
|
20
|
+
|
21
|
+
strategy_class = begin
|
22
|
+
strategies.resolve(strategy_key)
|
23
|
+
rescue StandardError
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
raise(strategy_not_found(strategy_key)) if strategy_class.nil?
|
28
|
+
|
29
|
+
strategy_params = params.dup.tap { |h| h.delete(:strategy) }
|
30
|
+
strategy_class.new(strategy_params)
|
31
|
+
end
|
32
|
+
|
33
|
+
def strategies
|
34
|
+
AuthStrategist.strategies
|
35
|
+
end
|
36
|
+
|
37
|
+
def strategy_not_found(strategy_key)
|
38
|
+
StandardError.new("Strategy '#{strategy_key}' was not found.")
|
39
|
+
end
|
40
|
+
|
41
|
+
def strategy_key_nil
|
42
|
+
StandardError.new(':strategy option must not be nil.')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,27 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AuthStrategist
|
2
4
|
class Configuration
|
3
|
-
attr_accessor :
|
4
|
-
|
5
|
-
def initialize
|
6
|
-
@default_strategy_components = []
|
7
|
-
@strategies = strategies_registry_class.new
|
8
|
-
end
|
9
|
-
|
10
|
-
def strategies
|
11
|
-
return @strategies unless block_given?
|
12
|
-
|
13
|
-
load_strategies
|
14
|
-
yield(@strategies)
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def load_strategies
|
20
|
-
Dir["./#{strategies_path}/*.rb"].each { |file| require file } if strategies_path
|
21
|
-
end
|
5
|
+
attr_accessor :strategies_path
|
22
6
|
|
23
|
-
def
|
24
|
-
|
7
|
+
def load_strategies!
|
8
|
+
Dir["./#{strategies_path}/**/*.rb"].each { |file| require(file) } if strategies_path
|
25
9
|
end
|
26
10
|
end
|
27
11
|
end
|
@@ -1,50 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AuthStrategist
|
2
4
|
module StrategyInterface
|
3
5
|
def self.included(base)
|
4
6
|
base.class_eval do
|
5
|
-
|
6
|
-
|
7
|
-
defined_components.delete_if { |c| default_components.include?(c) }
|
8
|
-
defined_components.uniq!
|
9
|
-
attr_accessor(*defined_components)
|
10
|
-
@components = defined_components
|
11
|
-
end
|
12
|
-
|
13
|
-
def components
|
14
|
-
[*default_components, *@components]
|
15
|
-
end
|
16
|
-
|
17
|
-
def default_components
|
18
|
-
AuthStrategist.configuration.default_strategy_components.uniq
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
attr_accessor(*components)
|
23
|
-
|
24
|
-
def initialize(attributes = {})
|
25
|
-
assign_component_values(attributes)
|
26
|
-
end
|
7
|
+
extend Dry::Initializer
|
8
|
+
end
|
27
9
|
|
28
|
-
|
29
|
-
|
10
|
+
def base.define_components(*components)
|
11
|
+
components.each do |component|
|
12
|
+
option component, optional: true
|
30
13
|
end
|
14
|
+
end
|
31
15
|
|
32
|
-
|
33
|
-
|
34
|
-
|
16
|
+
def base.components
|
17
|
+
dry_initializer.definitions.keys
|
18
|
+
end
|
19
|
+
end
|
35
20
|
|
36
|
-
|
37
|
-
|
38
|
-
|
21
|
+
def authorized?
|
22
|
+
raise(
|
23
|
+
AuthStrategist::Errors::AuthorizedNotImplemented,
|
24
|
+
"#{self.class}#authorized? was not implemented."
|
25
|
+
)
|
26
|
+
end
|
39
27
|
|
40
|
-
|
28
|
+
def authorize!
|
29
|
+
raise unauthorized unless authorized?
|
30
|
+
end
|
41
31
|
|
42
|
-
|
43
|
-
|
44
|
-
instance_variable_set("@#{c}", attributes[c])
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
32
|
+
def unauthorized
|
33
|
+
AuthStrategist::Errors::Unauthorized
|
48
34
|
end
|
49
35
|
end
|
50
36
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails/generators'
|
2
4
|
|
3
5
|
module AuthStrategist
|
4
6
|
class InstallGenerator < ::Rails::Generators::Base
|
5
|
-
source_root File.expand_path('
|
7
|
+
source_root File.expand_path('templates', __dir__)
|
6
8
|
desc 'Installs AuthStrategist.'
|
7
9
|
|
8
10
|
def install
|
@@ -1,13 +1,14 @@
|
|
1
|
-
|
2
|
-
# Set default strategy components
|
3
|
-
c.default_strategy_components = []
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
3
|
+
AuthStrategist.configure do |c|
|
4
|
+
# Set strategies directory path and load if they are not autoloaded
|
6
5
|
# c.strategies_path = 'lib/auth_strategist/strategies'
|
6
|
+
# c.load_strategies!
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
9
|
+
# Register your strategies
|
10
|
+
AuthStrategist.strategies do |s|
|
11
|
+
# E.g.
|
12
|
+
# s.register :ownership, OwnershipAuthStrategy
|
13
|
+
# s.register 'ownership.book', BookOwnershipAuthStrategy
|
13
14
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe AuthStrategist do
|
@@ -9,8 +11,8 @@ describe AuthStrategist do
|
|
9
11
|
expect(described_class::Configuration).to be_kind_of(Class)
|
10
12
|
end
|
11
13
|
|
12
|
-
it 'includes
|
13
|
-
expect(described_class::
|
14
|
+
it 'includes BuildStrategy service object' do
|
15
|
+
expect(described_class::BuildStrategy).to be_kind_of(Class)
|
14
16
|
end
|
15
17
|
|
16
18
|
it 'includes StrategyInterface module' do
|
@@ -31,37 +33,11 @@ describe AuthStrategist do
|
|
31
33
|
|
32
34
|
describe '.configure' do
|
33
35
|
context 'called with block' do
|
34
|
-
let(:default_strategy_components) { [:custom_component] }
|
35
36
|
let(:strategies_path) { 'spec/dummy/strategies' }
|
36
|
-
let(:test_strategy_class) { NotRegistered }
|
37
|
-
|
38
|
-
before(:each) do
|
39
|
-
described_class.configure do |c|
|
40
|
-
c.default_strategy_components = default_strategy_components
|
41
|
-
c.strategies_path = strategies_path
|
42
|
-
c.strategies do |s|
|
43
|
-
s.test = test_strategy_class
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
after(:each) do
|
49
|
-
described_class.configuration.strategies.delete(:test)
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'sets up configuration (default_strategy_components)' do
|
53
|
-
expect(described_class.configuration.default_strategy_components).to(
|
54
|
-
eq(default_strategy_components)
|
55
|
-
)
|
56
|
-
end
|
57
37
|
|
58
38
|
it 'sets up configuration (strategies_path)' do
|
59
39
|
expect(described_class.configuration.strategies_path).to eq(strategies_path)
|
60
40
|
end
|
61
|
-
|
62
|
-
it 'sets up configuration (strategies)' do
|
63
|
-
expect(described_class.configuration.strategies.test).to eq(test_strategy_class)
|
64
|
-
end
|
65
41
|
end
|
66
42
|
|
67
43
|
context 'called without block' do
|
@@ -72,25 +48,9 @@ describe AuthStrategist do
|
|
72
48
|
end
|
73
49
|
|
74
50
|
describe '.strategies' do
|
75
|
-
context 'called with block' do
|
76
|
-
let(:test_strategy_class) { NotRegistered }
|
77
|
-
|
78
|
-
before(:each) do
|
79
|
-
described_class.strategies { |s| s.test = test_strategy_class }
|
80
|
-
end
|
81
|
-
|
82
|
-
after(:each) do
|
83
|
-
described_class.strategies.delete(:test)
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'sets up configuration (strategies)' do
|
87
|
-
expect(described_class.configuration.strategies.test).to eq(test_strategy_class)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
51
|
context 'called without block' do
|
92
|
-
it 'returns
|
93
|
-
expect(described_class.strategies).to eq(described_class
|
52
|
+
it 'returns strategies registry' do
|
53
|
+
expect(described_class.strategies).to eq(described_class::Registry)
|
94
54
|
end
|
95
55
|
end
|
96
56
|
end
|
data/spec/authorization_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe AuthStrategist::Authorization do
|
@@ -8,12 +10,39 @@ describe AuthStrategist::Authorization do
|
|
8
10
|
expect(dummy_controller).to respond_to(:authorize!)
|
9
11
|
end
|
10
12
|
|
13
|
+
it 'adds #can? method to base' do
|
14
|
+
expect(dummy_controller).to respond_to(:can?)
|
15
|
+
end
|
16
|
+
|
11
17
|
describe '#authorize!' do
|
12
|
-
|
18
|
+
context 'when authorization fails' do
|
19
|
+
it 'raises an error (AuthStrategist::Errors::Unauthorized)' do
|
20
|
+
expect { dummy_controller.authorize!(strategy: :dummy_strategy) }
|
21
|
+
.to raise_error(AuthStrategist::Errors::Unauthorized)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when authorization succeeds' do
|
26
|
+
it 'returns nil' do
|
27
|
+
expect(dummy_controller.authorize!(strategy: :dummy_strategy, dummy_component: :ok))
|
28
|
+
.to be_nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#can?' do
|
34
|
+
context 'when authorization fails' do
|
35
|
+
it 'returns false' do
|
36
|
+
expect(dummy_controller.can?(strategy: :dummy_strategy))
|
37
|
+
.to eq(false)
|
38
|
+
end
|
39
|
+
end
|
13
40
|
|
14
|
-
|
15
|
-
|
16
|
-
|
41
|
+
context 'when authorization succeeds' do
|
42
|
+
it 'returns nil' do
|
43
|
+
expect(dummy_controller.can?(strategy: :dummy_strategy, dummy_component: :ok))
|
44
|
+
.to eq(true)
|
45
|
+
end
|
17
46
|
end
|
18
47
|
end
|
19
48
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe AuthStrategist::BuildStrategy do
|
6
|
+
describe '#call' do
|
7
|
+
let(:builder) { described_class.new }
|
8
|
+
|
9
|
+
context 'when :strategy key was absent in given options' do
|
10
|
+
it 'raises an error' do
|
11
|
+
expect { builder.call }.to raise_error(StandardError, ':strategy option must not be nil.')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when strategy registered under :strategy key was not found' do
|
16
|
+
it 'raises an error' do
|
17
|
+
expect { builder.call(strategy: :missing_strategy) }
|
18
|
+
.to raise_error(StandardError, 'Strategy \'missing_strategy\' was not found.')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when strategy was found' do
|
23
|
+
it 'builds new service object and sends #call to it' do
|
24
|
+
expect(builder.call(strategy: :dummy_strategy)).to be_a(DummyStrategy)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -1,21 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe AuthStrategist::Configuration do
|
4
6
|
context 'by default for specs environment' do
|
5
|
-
let(:default_strategy_components) { [:default_component] }
|
6
|
-
let(:strategies_path) { 'spec/dummy/strategies' }
|
7
|
-
let(:strategies_registry) do
|
8
|
-
described_class::StrategiesRegistry.new(dummy_strategy: DummyStrategy,
|
9
|
-
missing_authorize: MissingAuthorize)
|
10
|
-
end
|
11
|
-
|
12
7
|
let(:subject) { AuthStrategist.configuration }
|
13
8
|
|
14
|
-
its(:
|
15
|
-
is_expected.to eq(default_strategy_components)
|
16
|
-
end
|
17
|
-
|
18
|
-
its(:strategies_path) { is_expected.to eq(strategies_path) }
|
19
|
-
its(:strategies) { is_expected.to eq(strategies_registry) }
|
9
|
+
its(:strategies_path) { is_expected.to eq('spec/dummy/strategies') }
|
20
10
|
end
|
21
11
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,23 +1,19 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
4
4
|
|
5
|
-
require '
|
6
|
-
require 'factories/authorize'
|
5
|
+
require 'auth_strategist'
|
7
6
|
|
8
7
|
require 'rspec/its'
|
9
8
|
|
10
9
|
require 'dummy/controllers/dummy_controller'
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
11
|
+
AuthStrategist.configure do |g|
|
12
|
+
g.strategies_path = 'spec/dummy/strategies'
|
13
|
+
g.load_strategies!
|
14
|
+
end
|
15
|
+
|
16
|
+
AuthStrategist.strategies do |s|
|
17
|
+
s.register :dummy_strategy, DummyStrategy
|
18
|
+
s.register :missing_authorized, MissingAuthorized
|
23
19
|
end
|
@@ -1,18 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe AuthStrategist::StrategyInterface do
|
4
|
-
let(:
|
5
|
-
let(:strategy_class) { MissingAuthorize }
|
6
|
+
let(:strategy_class) { MissingAuthorized }
|
6
7
|
|
7
8
|
context 'included' do
|
8
9
|
it 'adds .define_components method to base' do
|
9
10
|
expect(strategy_class).to respond_to(:define_components)
|
10
11
|
end
|
11
12
|
|
12
|
-
it 'adds .default_components method to base' do
|
13
|
-
expect(strategy_class).to respond_to(:default_components)
|
14
|
-
end
|
15
|
-
|
16
13
|
it 'adds .components method to base' do
|
17
14
|
expect(strategy_class).to respond_to(:components)
|
18
15
|
end
|
@@ -21,10 +18,6 @@ describe AuthStrategist::StrategyInterface do
|
|
21
18
|
expect(strategy_class).to respond_to(:new)
|
22
19
|
end
|
23
20
|
|
24
|
-
it 'adds #components method to base' do
|
25
|
-
expect(strategy_class.new).to respond_to(:components)
|
26
|
-
end
|
27
|
-
|
28
21
|
it 'adds #authorize! method to base' do
|
29
22
|
expect(strategy_class.new).to respond_to(:authorize!)
|
30
23
|
end
|
@@ -33,96 +26,10 @@ describe AuthStrategist::StrategyInterface do
|
|
33
26
|
expect(strategy_class.new).to respond_to(:unauthorized)
|
34
27
|
end
|
35
28
|
|
36
|
-
it 'adds getters for default components to base' do
|
37
|
-
default_components.each do |c|
|
38
|
-
expect(strategy_class.new).to respond_to(c)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'adds setters for default components to base' do
|
43
|
-
default_components.each do |c|
|
44
|
-
expect(strategy_class.new).to respond_to("#{c}=")
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe '.define_components' do
|
49
|
-
before(:each) do
|
50
|
-
strategy_class.define_components(*components)
|
51
|
-
end
|
52
|
-
|
53
|
-
context 'when component names are not the same as default' do
|
54
|
-
let(:components) { [:user, :password] }
|
55
|
-
|
56
|
-
it 'adds components getters' do
|
57
|
-
components.each { |c| expect(strategy_class.new).to respond_to(c) }
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'adds components setters' do
|
61
|
-
components.each { |c| expect(strategy_class.new).to respond_to("#{c}=") }
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'adds components to components list' do
|
65
|
-
expect(strategy_class.components & components).to eq(components)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
context 'when component names are the same as default' do
|
70
|
-
let(:components) { default_components }
|
71
|
-
|
72
|
-
it 'is not being added to components list' do
|
73
|
-
expect(strategy_class.components).to eq(strategy_class.components.uniq)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
context 'when no components provided' do
|
78
|
-
let(:components) {}
|
79
|
-
|
80
|
-
it 'is equal to .default_components' do
|
81
|
-
expect(strategy_class.components).to eq(strategy_class.default_components)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe '.default_components' do
|
87
|
-
context 'for default specs environment configuration' do
|
88
|
-
subject { strategy_class }
|
89
|
-
|
90
|
-
its(:default_components) do
|
91
|
-
is_expected.to eq(default_components)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
context 'for any configuration' do
|
96
|
-
let(:components) { [:application, :requestor] }
|
97
|
-
|
98
|
-
before(:each) do
|
99
|
-
AuthStrategist.configure do |c|
|
100
|
-
c.default_strategy_components = components
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'returns components configured as default' do
|
105
|
-
expect(strategy_class.default_components).to eq(components)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe '.components' do
|
111
|
-
let(:components) { [*default_components, :dup, :dup] }
|
112
|
-
|
113
|
-
before(:each) do
|
114
|
-
strategy_class.define_components(*components)
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'returns default and stratagy specific components without duplicates' do
|
118
|
-
expect(strategy_class.components).to eq(components.uniq)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
29
|
describe '.new' do
|
123
|
-
let(:options) {
|
30
|
+
let(:options) { { user: 'john', password: 'rambo' } }
|
124
31
|
|
125
|
-
before
|
32
|
+
before do
|
126
33
|
strategy_class.define_components(*options.keys)
|
127
34
|
options[:missing_component] = :missing_component
|
128
35
|
end
|
@@ -136,24 +43,13 @@ describe AuthStrategist::StrategyInterface do
|
|
136
43
|
end
|
137
44
|
end
|
138
45
|
|
139
|
-
describe '#components' do
|
140
|
-
subject { strategy_class.new }
|
141
|
-
|
142
|
-
before(:each) do
|
143
|
-
allow(strategy_class).to receive(:components).and_return([:ok])
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'calls .components on strategy class' do
|
147
|
-
expect(subject.components).to eq([:ok])
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
46
|
describe '#authorize!' do
|
152
47
|
subject { strategy_class.new }
|
153
48
|
|
154
49
|
context 'when not implemented within base' do
|
155
|
-
it '
|
156
|
-
expect
|
50
|
+
it 'raises error (AuthStrategist::Errors::AuthorizedNotImplemented)' do
|
51
|
+
expect { subject.authorize! }
|
52
|
+
.to raise_error(AuthStrategist::Errors::AuthorizedNotImplemented, 'MissingAuthorized#authorized? was not implemented.')
|
157
53
|
end
|
158
54
|
end
|
159
55
|
|
@@ -162,7 +58,7 @@ describe AuthStrategist::StrategyInterface do
|
|
162
58
|
subject { strategy_class.new(dummy_component: :ok) }
|
163
59
|
|
164
60
|
it 'executes like defined' do
|
165
|
-
expect(subject.authorize!).to
|
61
|
+
expect(subject.authorize!).to be_nil
|
166
62
|
end
|
167
63
|
end
|
168
64
|
end
|
metadata
CHANGED
@@ -1,31 +1,45 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: auth_strategist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Krzysztof Buszewicz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: dry-container
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
19
|
+
version: '0.7'
|
20
|
+
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: dry-initializer
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - ">="
|
@@ -42,16 +56,30 @@ dependencies:
|
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- - "
|
59
|
+
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
61
|
+
version: '0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- - "
|
66
|
+
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rspec-its
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +94,20 @@ dependencies:
|
|
66
94
|
- - ">="
|
67
95
|
- !ruby/object:Gem::Version
|
68
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
69
111
|
description:
|
70
112
|
email:
|
71
113
|
- krzysztof.buszewicz@gmail.com
|
@@ -86,23 +128,23 @@ files:
|
|
86
128
|
- bin/setup
|
87
129
|
- lib/auth_strategist.rb
|
88
130
|
- lib/auth_strategist/authorization.rb
|
89
|
-
- lib/auth_strategist/
|
131
|
+
- lib/auth_strategist/build_strategy.rb
|
90
132
|
- lib/auth_strategist/configuration.rb
|
91
|
-
- lib/auth_strategist/
|
133
|
+
- lib/auth_strategist/errors/authorized_not_implemented.rb
|
92
134
|
- lib/auth_strategist/errors/unauthorized.rb
|
135
|
+
- lib/auth_strategist/registry.rb
|
93
136
|
- lib/auth_strategist/strategy_interface.rb
|
94
137
|
- lib/auth_strategist/version.rb
|
95
138
|
- lib/generators/auth_strategist/install_generator.rb
|
96
139
|
- lib/generators/auth_strategist/templates/initializer.rb
|
97
140
|
- spec/auth_strategist_spec.rb
|
98
141
|
- spec/authorization_spec.rb
|
99
|
-
- spec/
|
142
|
+
- spec/build_strategy_spec.rb
|
100
143
|
- spec/configuration_spec.rb
|
101
144
|
- spec/dummy/controllers/dummy_controller.rb
|
102
145
|
- spec/dummy/strategies/dummy_strategy.rb
|
103
|
-
- spec/dummy/strategies/
|
146
|
+
- spec/dummy/strategies/missing_authorized.rb
|
104
147
|
- spec/dummy/strategies/not_registered.rb
|
105
|
-
- spec/factories/authorize.rb
|
106
148
|
- spec/spec_helper.rb
|
107
149
|
- spec/strategy_interface_spec.rb
|
108
150
|
homepage: https://github.com/buszu/auth_strategist
|
@@ -125,19 +167,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
167
|
version: '0'
|
126
168
|
requirements: []
|
127
169
|
rubyforge_project:
|
128
|
-
rubygems_version: 2.6
|
170
|
+
rubygems_version: 2.7.6
|
129
171
|
signing_key:
|
130
172
|
specification_version: 4
|
131
173
|
summary: Simple gem to realize API actions authorization with different strategies.
|
132
174
|
test_files:
|
133
175
|
- spec/auth_strategist_spec.rb
|
134
176
|
- spec/authorization_spec.rb
|
135
|
-
- spec/
|
177
|
+
- spec/build_strategy_spec.rb
|
136
178
|
- spec/configuration_spec.rb
|
137
179
|
- spec/dummy/controllers/dummy_controller.rb
|
138
180
|
- spec/dummy/strategies/dummy_strategy.rb
|
139
|
-
- spec/dummy/strategies/
|
181
|
+
- spec/dummy/strategies/missing_authorized.rb
|
140
182
|
- spec/dummy/strategies/not_registered.rb
|
141
|
-
- spec/factories/authorize.rb
|
142
183
|
- spec/spec_helper.rb
|
143
184
|
- spec/strategy_interface_spec.rb
|
@@ -1,41 +0,0 @@
|
|
1
|
-
module AuthStrategist
|
2
|
-
class Authorize
|
3
|
-
attr_reader :strategy
|
4
|
-
|
5
|
-
def self.call(options = {})
|
6
|
-
new(options).call
|
7
|
-
end
|
8
|
-
|
9
|
-
def initialize(options = {})
|
10
|
-
@strategy = choose_strategy(options)
|
11
|
-
end
|
12
|
-
|
13
|
-
def call
|
14
|
-
strategy.authorize!
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def choose_strategy(options = {})
|
20
|
-
strategy_name = options.delete(:strategy)
|
21
|
-
raise(strategy_name_blank) if strategy_name.nil?
|
22
|
-
|
23
|
-
strategy_class = strategies[strategy_name]
|
24
|
-
raise(strategy_not_found(strategy_name)) if strategy_class.nil?
|
25
|
-
|
26
|
-
strategy_class.new(options)
|
27
|
-
end
|
28
|
-
|
29
|
-
def strategies
|
30
|
-
AuthStrategist.strategies.to_h
|
31
|
-
end
|
32
|
-
|
33
|
-
def strategy_not_found(strategy_name)
|
34
|
-
StandardError.new("Strategy :#{strategy_name} was not found.")
|
35
|
-
end
|
36
|
-
|
37
|
-
def strategy_name_blank
|
38
|
-
StandardError.new(':strategy option must not be blank.')
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/spec/authorize_spec.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe AuthStrategist::Authorize do
|
4
|
-
let(:authorize) { FactoryGirl.build(:authorize, dummy_component: :ok) }
|
5
|
-
let(:authorize_blank_strategy) { FactoryGirl.build(:authorize_blank_strategy) }
|
6
|
-
let(:authorize_missing_strategy) { FactoryGirl.build(:authorize_missing_strategy) }
|
7
|
-
|
8
|
-
describe '.call' do
|
9
|
-
context 'when :strategy key was absent in given options' do
|
10
|
-
it 'raises an error' do
|
11
|
-
expect { described_class.call }.to raise_error(StandardError)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'when strategy registered under :strategy key was not found' do
|
16
|
-
let(:missing_strategy) { :missing_strategy }
|
17
|
-
|
18
|
-
it 'raises an error' do
|
19
|
-
expect { described_class.call(strategy: missing_strategy) }.to raise_error(StandardError)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'when strategy was found' do
|
24
|
-
let(:options) { Hash[:strategy, :dummy_strategy] }
|
25
|
-
|
26
|
-
before(:each) do
|
27
|
-
allow_any_instance_of(described_class).to receive(:call).and_return(:ok)
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'builds new service object and sends #call to it' do
|
31
|
-
expect(described_class.call(options)).to eq(:ok)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe '.new' do
|
37
|
-
context 'when :strategy key was absent in given options' do
|
38
|
-
it 'raises an error' do
|
39
|
-
expect { authorize_blank_strategy }.to raise_error(StandardError)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'when strategy registered under :strategy key was not found' do
|
44
|
-
it 'raises an error' do
|
45
|
-
expect { authorize_missing_strategy }.to raise_error(StandardError)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'when strategy was found' do
|
50
|
-
let(:strategy_class) { DummyStrategy }
|
51
|
-
|
52
|
-
it 'sets strategy up' do
|
53
|
-
expect(authorize.strategy).to be_kind_of(strategy_class)
|
54
|
-
expect(authorize.strategy.dummy_component).to eq(:ok)
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'returns service object instance' do
|
58
|
-
expect(authorize).to be_kind_of(AuthStrategist::Authorize)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '#call' do
|
64
|
-
let(:strategy_class) { DummyStrategy }
|
65
|
-
|
66
|
-
before(:each) do
|
67
|
-
allow_any_instance_of(strategy_class).to receive(:authorize!).and_return(:ok)
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'sends #authorize! to strategy' do
|
71
|
-
expect(authorize.call).to eq(:ok)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
data/spec/factories/authorize.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
FactoryGirl.define do
|
2
|
-
factory :authorize_blank_strategy, class: AuthStrategist::Authorize do
|
3
|
-
initialize_with do
|
4
|
-
new(attributes)
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
factory :authorize_missing_strategy, parent: :authorize_blank_strategy do
|
9
|
-
strategy :missing_strategy
|
10
|
-
end
|
11
|
-
|
12
|
-
factory :authorize, parent: :authorize_blank_strategy do
|
13
|
-
strategy :dummy_strategy
|
14
|
-
end
|
15
|
-
end
|