identity_toolbox 0.1.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 +7 -0
- data/.env.pipelines +2 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.simplecov +8 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +159 -0
- data/README.md +220 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bitbucket-pipelines.yml +22 -0
- data/identity_toolbox.gemspec +36 -0
- data/lib/identity_toolbox.rb +33 -0
- data/lib/identity_toolbox/authorizable.rb +33 -0
- data/lib/identity_toolbox/configuration.rb +7 -0
- data/lib/identity_toolbox/default_policy.rb +97 -0
- data/lib/identity_toolbox/identity_service.rb +13 -0
- data/lib/identity_toolbox/policy_methods.rb +27 -0
- data/lib/identity_toolbox/spec_support/authorization_steps.rb +15 -0
- data/lib/identity_toolbox/spec_support/shared_examples_for_controllers.rb +20 -0
- data/lib/identity_toolbox/spec_support/shared_examples_for_policies.rb +82 -0
- data/lib/identity_toolbox/spec_support/shared_examples_for_policy_scopes.rb +92 -0
- data/lib/identity_toolbox/spec_support/tags.rb +17 -0
- data/lib/identity_toolbox/version.rb +5 -0
- metadata +266 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: aa431f92f09944ba1dbcd6447b88bffefabf667e8de9a8edd8c66033e31efebb
|
|
4
|
+
data.tar.gz: 3d63c5240c824ddade56157d6fc1537a9defe5ed97a7a1a7f1f638d7560083af
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7d8ebea90398d0c57e49f2f94bfae2cbce2e3bead8298468d91c02739294af051936517f8d03c5bc9227475e52f8c4c6e0caa68649df668a3cd8aee2dc5d1a7b
|
|
7
|
+
data.tar.gz: 11240ffdc42e984d36a7e3a12ab897ec490578c9a366a46ff396c547cc15016fcda17a84d456f2638ee5f13da905081b1f0088b4f6da59d6035b6a728c28c6e9
|
data/.env.pipelines
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
identity_toolbox
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby-2.5.1
|
data/.simplecov
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
|
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
## [0.1.0] - 2018-08-14
|
|
9
|
+
### Fixed
|
|
10
|
+
- First release
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
identity_toolbox (0.1.0)
|
|
5
|
+
json_api_toolbox (~> 0.16)
|
|
6
|
+
pundit (~> 2.0)
|
|
7
|
+
request_store (~> 1.3)
|
|
8
|
+
rspec
|
|
9
|
+
|
|
10
|
+
GEM
|
|
11
|
+
remote: https://rubygems.org/
|
|
12
|
+
specs:
|
|
13
|
+
actionpack (5.2.1)
|
|
14
|
+
actionview (= 5.2.1)
|
|
15
|
+
activesupport (= 5.2.1)
|
|
16
|
+
rack (~> 2.0)
|
|
17
|
+
rack-test (>= 0.6.3)
|
|
18
|
+
rails-dom-testing (~> 2.0)
|
|
19
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
20
|
+
actionview (5.2.1)
|
|
21
|
+
activesupport (= 5.2.1)
|
|
22
|
+
builder (~> 3.1)
|
|
23
|
+
erubi (~> 1.4)
|
|
24
|
+
rails-dom-testing (~> 2.0)
|
|
25
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
26
|
+
activemodel (5.2.1)
|
|
27
|
+
activesupport (= 5.2.1)
|
|
28
|
+
activerecord (5.2.1)
|
|
29
|
+
activemodel (= 5.2.1)
|
|
30
|
+
activesupport (= 5.2.1)
|
|
31
|
+
arel (>= 9.0)
|
|
32
|
+
activesupport (5.2.1)
|
|
33
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
34
|
+
i18n (>= 0.7, < 2)
|
|
35
|
+
minitest (~> 5.1)
|
|
36
|
+
tzinfo (~> 1.1)
|
|
37
|
+
addressable (2.5.2)
|
|
38
|
+
public_suffix (>= 2.0.2, < 4.0)
|
|
39
|
+
arel (9.0.0)
|
|
40
|
+
builder (3.2.3)
|
|
41
|
+
byebug (10.0.2)
|
|
42
|
+
coderay (1.1.2)
|
|
43
|
+
concurrent-ruby (1.0.5)
|
|
44
|
+
crack (0.4.3)
|
|
45
|
+
safe_yaml (~> 1.0.0)
|
|
46
|
+
crass (1.0.4)
|
|
47
|
+
diff-lcs (1.3)
|
|
48
|
+
docile (1.3.1)
|
|
49
|
+
domain_name (0.5.20180417)
|
|
50
|
+
unf (>= 0.0.5, < 1.0.0)
|
|
51
|
+
dotenv (2.5.0)
|
|
52
|
+
erubi (1.7.1)
|
|
53
|
+
hashdiff (0.3.7)
|
|
54
|
+
http-cookie (1.0.3)
|
|
55
|
+
domain_name (~> 0.5)
|
|
56
|
+
i18n (1.1.0)
|
|
57
|
+
concurrent-ruby (~> 1.0)
|
|
58
|
+
json (2.1.0)
|
|
59
|
+
json-api-vanilla (1.0.1)
|
|
60
|
+
json_api_toolbox (0.16.2)
|
|
61
|
+
actionpack (>= 4.0.0)
|
|
62
|
+
activerecord (>= 4.0.0)
|
|
63
|
+
activesupport (>= 4.0.0)
|
|
64
|
+
json-api-vanilla (~> 1.0.1)
|
|
65
|
+
jsonapi-serializable (>= 0.3.0)
|
|
66
|
+
request_store (~> 1.3.2)
|
|
67
|
+
rest-client (>= 2.0.1)
|
|
68
|
+
rspec (>= 3.0.0)
|
|
69
|
+
will_paginate (>= 3.1.0)
|
|
70
|
+
jsonapi-renderer (0.2.0)
|
|
71
|
+
jsonapi-serializable (0.3.0)
|
|
72
|
+
jsonapi-renderer (~> 0.2.0)
|
|
73
|
+
loofah (2.2.2)
|
|
74
|
+
crass (~> 1.0.2)
|
|
75
|
+
nokogiri (>= 1.5.9)
|
|
76
|
+
method_source (0.9.0)
|
|
77
|
+
mime-types (3.2.2)
|
|
78
|
+
mime-types-data (~> 3.2015)
|
|
79
|
+
mime-types-data (3.2018.0812)
|
|
80
|
+
mini_portile2 (2.3.0)
|
|
81
|
+
minitest (5.11.3)
|
|
82
|
+
netrc (0.11.0)
|
|
83
|
+
nokogiri (1.8.4)
|
|
84
|
+
mini_portile2 (~> 2.3.0)
|
|
85
|
+
pry (0.11.3)
|
|
86
|
+
coderay (~> 1.1.0)
|
|
87
|
+
method_source (~> 0.9.0)
|
|
88
|
+
pry-byebug (3.6.0)
|
|
89
|
+
byebug (~> 10.0)
|
|
90
|
+
pry (~> 0.10)
|
|
91
|
+
public_suffix (3.0.3)
|
|
92
|
+
pundit (2.0.0)
|
|
93
|
+
activesupport (>= 3.0.0)
|
|
94
|
+
rack (2.0.5)
|
|
95
|
+
rack-test (1.1.0)
|
|
96
|
+
rack (>= 1.0, < 3)
|
|
97
|
+
rails-dom-testing (2.0.3)
|
|
98
|
+
activesupport (>= 4.2.0)
|
|
99
|
+
nokogiri (>= 1.6)
|
|
100
|
+
rails-html-sanitizer (1.0.4)
|
|
101
|
+
loofah (~> 2.2, >= 2.2.2)
|
|
102
|
+
rake (10.5.0)
|
|
103
|
+
request_store (1.3.2)
|
|
104
|
+
rest-client (2.0.2)
|
|
105
|
+
http-cookie (>= 1.0.2, < 2.0)
|
|
106
|
+
mime-types (>= 1.16, < 4.0)
|
|
107
|
+
netrc (~> 0.8)
|
|
108
|
+
rspec (3.8.0)
|
|
109
|
+
rspec-core (~> 3.8.0)
|
|
110
|
+
rspec-expectations (~> 3.8.0)
|
|
111
|
+
rspec-mocks (~> 3.8.0)
|
|
112
|
+
rspec-core (3.8.0)
|
|
113
|
+
rspec-support (~> 3.8.0)
|
|
114
|
+
rspec-expectations (3.8.1)
|
|
115
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
116
|
+
rspec-support (~> 3.8.0)
|
|
117
|
+
rspec-mocks (3.8.0)
|
|
118
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
119
|
+
rspec-support (~> 3.8.0)
|
|
120
|
+
rspec-support (3.8.0)
|
|
121
|
+
safe_yaml (1.0.4)
|
|
122
|
+
shoulda-matchers (3.1.2)
|
|
123
|
+
activesupport (>= 4.0.0)
|
|
124
|
+
simplecov (0.16.1)
|
|
125
|
+
docile (~> 1.1)
|
|
126
|
+
json (>= 1.8, < 3)
|
|
127
|
+
simplecov-html (~> 0.10.0)
|
|
128
|
+
simplecov-html (0.10.2)
|
|
129
|
+
thread_safe (0.3.6)
|
|
130
|
+
tzinfo (1.2.5)
|
|
131
|
+
thread_safe (~> 0.1)
|
|
132
|
+
unf (0.1.4)
|
|
133
|
+
unf_ext
|
|
134
|
+
unf_ext (0.0.7.5)
|
|
135
|
+
vcr (4.0.0)
|
|
136
|
+
webmock (3.4.2)
|
|
137
|
+
addressable (>= 2.3.6)
|
|
138
|
+
crack (>= 0.3.2)
|
|
139
|
+
hashdiff
|
|
140
|
+
will_paginate (3.1.6)
|
|
141
|
+
|
|
142
|
+
PLATFORMS
|
|
143
|
+
ruby
|
|
144
|
+
|
|
145
|
+
DEPENDENCIES
|
|
146
|
+
actionpack (~> 5)
|
|
147
|
+
bundler (~> 1.16)
|
|
148
|
+
dotenv
|
|
149
|
+
identity_toolbox!
|
|
150
|
+
pry-byebug
|
|
151
|
+
rake (~> 10.0)
|
|
152
|
+
rspec (~> 3.0)
|
|
153
|
+
shoulda-matchers (~> 3.1)
|
|
154
|
+
simplecov
|
|
155
|
+
vcr
|
|
156
|
+
webmock
|
|
157
|
+
|
|
158
|
+
BUNDLED WITH
|
|
159
|
+
1.16.4
|
data/README.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# IdentityToolbox
|
|
2
|
+
|
|
3
|
+
A IdentityToolBox é uma gem para realizar filtros nos dados de acordo com a permissão que o usuário possuí.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Instalação
|
|
7
|
+
|
|
8
|
+
Adicione essa linha em seu gem file:
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
gem 'identity_toolbox'
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Execute:
|
|
15
|
+
|
|
16
|
+
$ bundle
|
|
17
|
+
|
|
18
|
+
Ou instale você mesmo.
|
|
19
|
+
|
|
20
|
+
$ gem install identity_toolbox
|
|
21
|
+
----
|
|
22
|
+
## Configuração
|
|
23
|
+
|
|
24
|
+
Adicione no `config/initializers/` o file `identity_toolbox.rb` para configurar as variáveis de ambiente.
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
IdentityToolbox.configure do |config|
|
|
28
|
+
config.identity_service_url = ENV['identity_service_url']
|
|
29
|
+
config.identity_cache_url = ENV['identity_cache_url']
|
|
30
|
+
end
|
|
31
|
+
```
|
|
32
|
+
----
|
|
33
|
+
## Como Usuar
|
|
34
|
+
|
|
35
|
+
### Policies
|
|
36
|
+
|
|
37
|
+
Crie a policy na pasta `app/policies`, com o nome baseado no modelo.
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
class ModelPolicy
|
|
41
|
+
include IdentityToolbox::DefaultPolicy
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
#### Atributos de permissionamento
|
|
46
|
+
|
|
47
|
+
A gem possui os seguintes atributos que realizam a validação:
|
|
48
|
+
|
|
49
|
+
- account_id
|
|
50
|
+
- sinacor_advisor_id
|
|
51
|
+
- client_id
|
|
52
|
+
- identification_document
|
|
53
|
+
|
|
54
|
+
São atributos retornados do serviço de permissão do usuário.
|
|
55
|
+
|
|
56
|
+
Para adiciona-los basta incluir o metodo como o exemplo a seguir
|
|
57
|
+
|
|
58
|
+
Exemplo:
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
class ModelPolicy
|
|
62
|
+
include IdentityToolbox::DefaultPolicy
|
|
63
|
+
|
|
64
|
+
account_id :sinacor_account_id
|
|
65
|
+
client_id :client_id
|
|
66
|
+
end
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Rotas fora dos padrões *REST*
|
|
70
|
+
|
|
71
|
+
A gem ja traz as rotas padrões como `create`, `update`, `index`, `delete`, `show`, com aplicação do filtro, não sendo necesário a criação desse métodos.
|
|
72
|
+
|
|
73
|
+
Se for necessário realizar os filtros em uma rota diferente do *REST* padrão, basta criar um alias por exemplo `alias cancel? allowed?` no caso para uma collection basta sobrescrever a class scope com o metodo resolve.
|
|
74
|
+
|
|
75
|
+
Exemplo
|
|
76
|
+
```ruby
|
|
77
|
+
class ModelPolicy
|
|
78
|
+
include IdentityToolbox::DefaultPolicy
|
|
79
|
+
|
|
80
|
+
account_id :sinacor_account
|
|
81
|
+
|
|
82
|
+
alias cancel? allowed?
|
|
83
|
+
|
|
84
|
+
class Scope
|
|
85
|
+
def resolve
|
|
86
|
+
scope.where(sinacor_account: account_ids)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
A Gem disponibiliza os seguintes metodos que retornas o valores permitidos do usuário
|
|
93
|
+
|
|
94
|
+
- account_ids
|
|
95
|
+
- sinacor_advisor_ids
|
|
96
|
+
- client_ids
|
|
97
|
+
- identification_documents
|
|
98
|
+
|
|
99
|
+
Basta chama-los dentro da policy customizada que ela retornará os valores
|
|
100
|
+
|
|
101
|
+
#### Testes Policies
|
|
102
|
+
Para realizar teste nas policies, basta adicionar o shared example na pasta `app/policies`.
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
require 'rails_helper'
|
|
106
|
+
|
|
107
|
+
RSpec.describe ModelPolicy::Scope do
|
|
108
|
+
it_behaves_like 'a default policy'
|
|
109
|
+
it_behaves_like 'a default policy scope'
|
|
110
|
+
end
|
|
111
|
+
```
|
|
112
|
+
----
|
|
113
|
+
### Controllers
|
|
114
|
+
Inclua em seu controller
|
|
115
|
+
```ruby
|
|
116
|
+
include IdentityToolbox::Authorizable
|
|
117
|
+
```
|
|
118
|
+
Para realizar a autorização nos controllers apenas seguir o exemplo abaixo.
|
|
119
|
+
|
|
120
|
+
- **policy_scope**
|
|
121
|
+
```ruby
|
|
122
|
+
search = Model.ransack(params[:q])
|
|
123
|
+
result = policy_scope(search.result)
|
|
124
|
+
```
|
|
125
|
+
- **authorize**
|
|
126
|
+
```ruby
|
|
127
|
+
model = Model.find(params.require(:id))
|
|
128
|
+
authorize(model)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Exemplo inclusão em uma rota collection.
|
|
132
|
+
```ruby
|
|
133
|
+
class ExampleController < ApplicationController
|
|
134
|
+
include IdentityToolbox::Authorizable
|
|
135
|
+
|
|
136
|
+
def index
|
|
137
|
+
search = Example.ransack(params[:q])
|
|
138
|
+
result = policy_scope(search.result)
|
|
139
|
+
render_object(result)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Testes
|
|
145
|
+
Para realizar os testes em suas policies, basta adicionar os shareds examples nas rotas na qual foi adicionado o authorize.
|
|
146
|
+
|
|
147
|
+
- **policy_scope**
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
it_behaves_like 'an authorizable collection action' do
|
|
151
|
+
after { get :index }
|
|
152
|
+
end
|
|
153
|
+
```
|
|
154
|
+
- **authorize**
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
it_behaves_like 'an authorizable record action' do
|
|
158
|
+
after { get :show, params: { id: id } }
|
|
159
|
+
end
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Exemplo de um teste em uma collection.
|
|
163
|
+
|
|
164
|
+
Adicione a tag `authorizable: true`
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
require 'rails_helper'
|
|
168
|
+
|
|
169
|
+
RSpec.describe ExampleController, type: :controller, authorizable: true do
|
|
170
|
+
describe 'GET' do
|
|
171
|
+
describe '#index' do
|
|
172
|
+
it_behaves_like 'an authorizable collection action' do
|
|
173
|
+
after { get :index }
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
```
|
|
179
|
+
----
|
|
180
|
+
|
|
181
|
+
### Entities
|
|
182
|
+
Caso possua alguma rota que retorne um Entity, ao invés do ActiveRecord, basta seguir o mesmo padrão anterior para modelos.
|
|
183
|
+
|
|
184
|
+
```ruby
|
|
185
|
+
class EntityPolicy
|
|
186
|
+
include IdentityToolbox::DefaultPolicy
|
|
187
|
+
|
|
188
|
+
account_id :sinacor_account
|
|
189
|
+
|
|
190
|
+
alias index? allowed?
|
|
191
|
+
|
|
192
|
+
class Scope
|
|
193
|
+
def resolve
|
|
194
|
+
scope.select { |record| account_ids.include?(record.sinacor_account)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
```
|
|
199
|
+
----
|
|
200
|
+
|
|
201
|
+
### Teste de Aceitação com Turnip
|
|
202
|
+
A gem já vem implementado o step para adicionar caso o serviço esteja utilizando o turnip.
|
|
203
|
+
|
|
204
|
+
#### Configuração
|
|
205
|
+
No arquivo `turnip_helper` adicionar o seguinte include
|
|
206
|
+
```ruby
|
|
207
|
+
RSpec.configure do |config|
|
|
208
|
+
config.include IdentityToolbox::SpecSupport::AuthorizationSteps
|
|
209
|
+
end
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
#### Feature
|
|
213
|
+
Para isso basta adicionar o step com o nome do controller no background da feature
|
|
214
|
+
```ruby
|
|
215
|
+
And user is authorized on "Controller"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "identity_toolbox"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
image: ruby:2.5.1
|
|
2
|
+
|
|
3
|
+
pipelines:
|
|
4
|
+
default:
|
|
5
|
+
- step:
|
|
6
|
+
script:
|
|
7
|
+
- git archive --remote=git@bitbucket.org:guideinvestimentos/rails_defaults.git HEAD .rubocop.yml | tar -x
|
|
8
|
+
- bundle install
|
|
9
|
+
- mv .env.pipelines .env
|
|
10
|
+
- gem install rubocop
|
|
11
|
+
- rspec -fdoc
|
|
12
|
+
- rubocop .
|
|
13
|
+
|
|
14
|
+
branches:
|
|
15
|
+
master:
|
|
16
|
+
- step:
|
|
17
|
+
script:
|
|
18
|
+
- mkdir -p ~/.gem
|
|
19
|
+
- gem build identity_toolbox.gemspec
|
|
20
|
+
- curl -u $RUBYGEMS_USERNAME:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
|
|
21
|
+
- chmod 0600 ~/.gem/credentials
|
|
22
|
+
- gem push $(ls *.gem)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require 'identity_toolbox/version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |spec|
|
|
8
|
+
spec.name = 'identity_toolbox'
|
|
9
|
+
spec.version = IdentityToolbox::VERSION
|
|
10
|
+
spec.authors = ['Codeminer 42']
|
|
11
|
+
spec.email = ['contato@codeminer42.com.br']
|
|
12
|
+
spec.summary = 'Tools to provide user authorization and data scoping.'
|
|
13
|
+
|
|
14
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
15
|
+
f.match(%r{^(test|spec|features)/})
|
|
16
|
+
end
|
|
17
|
+
spec.bindir = 'exe'
|
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
19
|
+
spec.require_paths = ['lib']
|
|
20
|
+
|
|
21
|
+
spec.add_dependency 'json_api_toolbox', '~> 0.16'
|
|
22
|
+
spec.add_dependency 'pundit', '~> 2.0'
|
|
23
|
+
spec.add_dependency 'request_store', '~> 1.3'
|
|
24
|
+
spec.add_dependency 'rspec'
|
|
25
|
+
|
|
26
|
+
spec.add_development_dependency 'actionpack', '~> 5'
|
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
|
28
|
+
spec.add_development_dependency 'dotenv'
|
|
29
|
+
spec.add_development_dependency 'pry-byebug'
|
|
30
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
31
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
32
|
+
spec.add_development_dependency 'shoulda-matchers', '~> 3.1'
|
|
33
|
+
spec.add_development_dependency 'simplecov'
|
|
34
|
+
spec.add_development_dependency 'vcr'
|
|
35
|
+
spec.add_development_dependency 'webmock'
|
|
36
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'dotenv/load'
|
|
4
|
+
require 'pundit'
|
|
5
|
+
require 'json_api_toolbox'
|
|
6
|
+
require 'request_store'
|
|
7
|
+
require 'identity_toolbox/configuration'
|
|
8
|
+
require 'identity_toolbox/version'
|
|
9
|
+
require 'identity_toolbox/identity_service'
|
|
10
|
+
require 'identity_toolbox/policy_methods'
|
|
11
|
+
require 'identity_toolbox/default_policy'
|
|
12
|
+
require 'identity_toolbox/authorizable'
|
|
13
|
+
require 'identity_toolbox/spec_support/authorization_steps' if defined?(Turnip)
|
|
14
|
+
require 'identity_toolbox/spec_support/shared_examples_for_controllers'
|
|
15
|
+
require 'identity_toolbox/spec_support/shared_examples_for_policies'
|
|
16
|
+
require 'identity_toolbox/spec_support/shared_examples_for_policy_scopes'
|
|
17
|
+
require 'identity_toolbox/spec_support/tags'
|
|
18
|
+
|
|
19
|
+
module IdentityToolbox
|
|
20
|
+
class << self
|
|
21
|
+
def reset
|
|
22
|
+
@configuration = Configuration.new
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def configuration
|
|
26
|
+
@configuration ||= Configuration.new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def configure
|
|
30
|
+
yield(configuration)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IdentityToolbox
|
|
4
|
+
module Authorizable
|
|
5
|
+
def self.included(klass)
|
|
6
|
+
klass.class_eval do
|
|
7
|
+
include Pundit
|
|
8
|
+
rescue_from Pundit::NotAuthorizedError, with: :render_forbidden
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def current_user
|
|
13
|
+
RequestStore.store[:token]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def render_forbidden(_exception)
|
|
17
|
+
render(errors)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def errors
|
|
23
|
+
{ jsonapi_errors: { title: 'Forbidden',
|
|
24
|
+
detail: 'Not allowed to perform this action.',
|
|
25
|
+
status: 403,
|
|
26
|
+
source: {} },
|
|
27
|
+
jsonapi_class:
|
|
28
|
+
{ class:
|
|
29
|
+
{ Hash: JsonApiToolbox::Serializables::SerializableException } },
|
|
30
|
+
status: :forbidden }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IdentityToolbox
|
|
4
|
+
module DefaultPolicy
|
|
5
|
+
include PolicyMethods
|
|
6
|
+
|
|
7
|
+
IDENTITY_ATTRIBUTES = %i[account_id client_id identification_document
|
|
8
|
+
sinacor_advisor_id].freeze
|
|
9
|
+
|
|
10
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
11
|
+
def self.policy_class(klass)
|
|
12
|
+
Class.new do
|
|
13
|
+
include PolicyMethods
|
|
14
|
+
|
|
15
|
+
attr_reader :scope
|
|
16
|
+
|
|
17
|
+
delegate :attributes, to: klass.name.to_sym
|
|
18
|
+
|
|
19
|
+
def initialize(_user, scope)
|
|
20
|
+
@scope = scope
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def resolve
|
|
24
|
+
return scope if queries.blank?
|
|
25
|
+
|
|
26
|
+
queries.reduce(nil) do |new_scope, query|
|
|
27
|
+
if new_scope.nil?
|
|
28
|
+
scope.where(query)
|
|
29
|
+
else
|
|
30
|
+
new_scope.or(scope.where(query))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def queries
|
|
38
|
+
IDENTITY_ATTRIBUTES.map(&method(:to_query)).compact
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def to_query(attribute)
|
|
42
|
+
return if attributes.nil? || attributes[attribute].nil?
|
|
43
|
+
|
|
44
|
+
{ attributes[attribute] => send("#{attribute}s") }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
49
|
+
|
|
50
|
+
def self.included(klass)
|
|
51
|
+
klass.class_eval do
|
|
52
|
+
extend ClassMethods
|
|
53
|
+
klass.const_set('Scope', DefaultPolicy.policy_class(klass))
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
module ClassMethods
|
|
58
|
+
def attributes
|
|
59
|
+
@attributes ||= {}
|
|
60
|
+
@attributes
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
IDENTITY_ATTRIBUTES.each do |attribute|
|
|
64
|
+
define_method(attribute) do |value|
|
|
65
|
+
@attributes ||= {}
|
|
66
|
+
@attributes[attribute] = value
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
delegate :attributes, to: :class
|
|
72
|
+
|
|
73
|
+
attr_reader :record
|
|
74
|
+
|
|
75
|
+
def initialize(_user, record)
|
|
76
|
+
@record = record
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def allowed?
|
|
80
|
+
IDENTITY_ATTRIBUTES.map(&method(:include_attribute?)).
|
|
81
|
+
compact.reduce(:|)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
alias show? allowed?
|
|
85
|
+
alias create? allowed?
|
|
86
|
+
alias update? allowed?
|
|
87
|
+
alias destroy? allowed?
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def include_attribute?(attribute)
|
|
92
|
+
return if attributes.nil? || attributes[attribute].nil?
|
|
93
|
+
|
|
94
|
+
send("#{attribute}s").include?(record.send(attributes[attribute]).to_s)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IdentityToolbox
|
|
4
|
+
class IdentityService < ::JsonApiToolbox::Service
|
|
5
|
+
def self.find_view_models
|
|
6
|
+
get(url: "#{config.identity_service_url}/users/accounts")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.config
|
|
10
|
+
@config ||= IdentityToolbox.configuration
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IdentityToolbox
|
|
4
|
+
module PolicyMethods
|
|
5
|
+
def identification_documents
|
|
6
|
+
view_models.map(&:document).map(&:to_s).uniq
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def client_ids
|
|
10
|
+
view_models.map(&:client_id).map(&:to_s).uniq
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def account_ids
|
|
14
|
+
view_models.map(&:account_id).map(&:to_s).uniq
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def sinacor_advisor_ids
|
|
18
|
+
view_models.map(&:sinacor_advisor_id).map(&:to_s).uniq
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def view_models
|
|
24
|
+
@view_models ||= IdentityService.find_view_models
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IdentityToolbox
|
|
4
|
+
module SpecSupport
|
|
5
|
+
module AuthorizationSteps
|
|
6
|
+
step 'user is authorized on :controller' do |controller|
|
|
7
|
+
allow_any_instance_of(controller.constantize).to receive(:authorize)
|
|
8
|
+
allow_any_instance_of(controller.constantize).
|
|
9
|
+
to receive(:policy_scope) do |_receiver, scope|
|
|
10
|
+
scope
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IdentityToolbox
|
|
4
|
+
module SpecSupport
|
|
5
|
+
module SharedExamplesForControllers
|
|
6
|
+
RSpec.shared_examples 'an authorizable record action' do
|
|
7
|
+
it { expect_any_instance_of(described_class).to receive(:authorize) }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
RSpec.shared_examples 'an authorizable collection action' do
|
|
11
|
+
it do
|
|
12
|
+
expect_any_instance_of(described_class).
|
|
13
|
+
to receive(:policy_scope) do |scope|
|
|
14
|
+
scope
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IdentityToolbox
|
|
4
|
+
module SpecSupport
|
|
5
|
+
module SharedExamplesForPolicies
|
|
6
|
+
RSpec.shared_context 'default policy records' do |attributes|
|
|
7
|
+
let(:model_name) do
|
|
8
|
+
described_class.name.match(/\A(.*)Policy\z/).captures.first
|
|
9
|
+
end
|
|
10
|
+
let(:model_sym) { model_name.underscore.to_sym }
|
|
11
|
+
let!(:matched_record) do
|
|
12
|
+
build(model_sym, { attributes[:account_id] => 1,
|
|
13
|
+
attributes[:client_id] => 2,
|
|
14
|
+
attributes[:identification_document] => '3',
|
|
15
|
+
attributes[:sinacor_advisor_id] => '4' }.
|
|
16
|
+
except(nil))
|
|
17
|
+
end
|
|
18
|
+
let!(:unmatched_record) do
|
|
19
|
+
build(model_sym, { attributes[:account_id] => 11,
|
|
20
|
+
attributes[:client_id] => 22,
|
|
21
|
+
attributes[:identification_document] => '33',
|
|
22
|
+
attributes[:sinacor_advisor_id] => 44 }.
|
|
23
|
+
except(nil))
|
|
24
|
+
end
|
|
25
|
+
let(:scope) { model_name.constantize.all }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
RSpec.shared_examples 'a default policy for' do |attributes|
|
|
29
|
+
include_context 'default policy records', attributes
|
|
30
|
+
|
|
31
|
+
before do
|
|
32
|
+
allow(IdentityToolbox::IdentityService).
|
|
33
|
+
to receive(:find_view_models).and_return(view_models)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
subject { described_class.new(nil, record).allowed? }
|
|
37
|
+
|
|
38
|
+
def self.join(attributes)
|
|
39
|
+
attributes.values.join(', ')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "when #{join(attributes)} matches the view models" do
|
|
43
|
+
let(:view_models) do
|
|
44
|
+
[double(account_id: 1, client_id: 2,
|
|
45
|
+
document: 3, sinacor_advisor_id: 4)]
|
|
46
|
+
end
|
|
47
|
+
let(:record) { matched_record }
|
|
48
|
+
|
|
49
|
+
it { is_expected.to be_truthy }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "when #{join(attributes)} doesn't match the view models" do
|
|
53
|
+
let(:view_models) do
|
|
54
|
+
[double(account_id: 111, client_id: 222,
|
|
55
|
+
document: 333, sinacor_advisor_id: 444)]
|
|
56
|
+
end
|
|
57
|
+
let(:record) { unmatched_record }
|
|
58
|
+
|
|
59
|
+
it { is_expected.to be_falsey }
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
RSpec.shared_examples 'a default policy' do
|
|
64
|
+
def self.combinations
|
|
65
|
+
(1..4).flat_map do |quantity|
|
|
66
|
+
described_class.attributes.keys.combination(quantity).to_a
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.slice(combination)
|
|
71
|
+
described_class.attributes.slice(*combination)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe '#allowed?' do
|
|
75
|
+
combinations.each do |combination|
|
|
76
|
+
include_examples 'a default policy for', slice(combination)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IdentityToolbox
|
|
4
|
+
module SpecSupport
|
|
5
|
+
module SharedExamplesForPolicyScopes
|
|
6
|
+
RSpec.shared_context 'default policy scope records' do |attributes|
|
|
7
|
+
let(:model_name) do
|
|
8
|
+
described_class.parent.name.match(/\A(.*)Policy\z/).captures.first
|
|
9
|
+
end
|
|
10
|
+
let(:model_sym) { model_name.underscore.to_sym }
|
|
11
|
+
let!(:matched_record) do
|
|
12
|
+
create(model_sym, { attributes[:account_id] => 1,
|
|
13
|
+
attributes[:client_id] => 2,
|
|
14
|
+
attributes[:identification_document] => '3',
|
|
15
|
+
attributes[:sinacor_advisor_id] => '4' }.
|
|
16
|
+
except(nil))
|
|
17
|
+
end
|
|
18
|
+
let!(:unmatched_record) do
|
|
19
|
+
create(model_sym, { attributes[:account_id] => 11,
|
|
20
|
+
attributes[:client_id] => 22,
|
|
21
|
+
attributes[:identification_document] => '33',
|
|
22
|
+
attributes[:sinacor_advisor_id] => 44 }.
|
|
23
|
+
except(nil))
|
|
24
|
+
end
|
|
25
|
+
let(:scope) { model_name.constantize.all }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
RSpec.shared_examples 'resolve method' do |attributes|
|
|
29
|
+
def self.join(attributes)
|
|
30
|
+
attributes.values.join(', ')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "when #{join(attributes)} matches the view models" do
|
|
34
|
+
let(:view_models) do
|
|
35
|
+
[double(account_id: 1, client_id: 2,
|
|
36
|
+
document: '3', sinacor_advisor_id: 4)]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'includes the matched record' do
|
|
40
|
+
is_expected.to contain_exactly(matched_record)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'does not include the unmatched record' do
|
|
44
|
+
is_expected.not_to include(unmatched_record)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context "when #{join(attributes)} doesn't match the view models" do
|
|
49
|
+
let(:view_models) do
|
|
50
|
+
[double(account_id: 111, client_id: 222,
|
|
51
|
+
document: '333', sinacor_advisor_id: 444)]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it { is_expected.to be_empty }
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
RSpec.shared_examples 'a default policy scope' do
|
|
59
|
+
describe described_class::Scope do
|
|
60
|
+
shared_examples 'a default policy scope for' do |attributes|
|
|
61
|
+
include_context 'default policy scope records', attributes
|
|
62
|
+
|
|
63
|
+
before do
|
|
64
|
+
allow(IdentityToolbox::IdentityService).
|
|
65
|
+
to receive(:find_view_models).and_return(view_models)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
subject { described_class.new(nil, scope).resolve }
|
|
69
|
+
|
|
70
|
+
include_examples 'resolve method', attributes
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def self.combinations
|
|
74
|
+
(1..4).flat_map do |quantity|
|
|
75
|
+
described_class.parent.attributes.keys.combination(quantity).to_a
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def self.slice(combination)
|
|
80
|
+
described_class.parent.attributes.slice(*combination)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe '#resolve' do
|
|
84
|
+
combinations.each do |combination|
|
|
85
|
+
include_examples 'a default policy scope for', slice(combination)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IdentityToolbox
|
|
4
|
+
module SpecSupport
|
|
5
|
+
module Tags
|
|
6
|
+
RSpec.configure do |config|
|
|
7
|
+
config.before(authorizable: true) do
|
|
8
|
+
allow_any_instance_of(described_class).to receive(:authorize)
|
|
9
|
+
allow_any_instance_of(described_class).
|
|
10
|
+
to receive(:policy_scope) do |_receiver, scope|
|
|
11
|
+
scope
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: identity_toolbox
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Codeminer 42
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2018-10-02 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: json_api_toolbox
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.16'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.16'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: pundit
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: request_store
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.3'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.3'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rspec
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: actionpack
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '5'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '5'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: bundler
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '1.16'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '1.16'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: dotenv
|
|
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'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: pry-byebug
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rake
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '10.0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '10.0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: rspec
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '3.0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '3.0'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: shoulda-matchers
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '3.1'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '3.1'
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: simplecov
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '0'
|
|
174
|
+
type: :development
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - ">="
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '0'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: vcr
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - ">="
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '0'
|
|
188
|
+
type: :development
|
|
189
|
+
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - ">="
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '0'
|
|
195
|
+
- !ruby/object:Gem::Dependency
|
|
196
|
+
name: webmock
|
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
|
198
|
+
requirements:
|
|
199
|
+
- - ">="
|
|
200
|
+
- !ruby/object:Gem::Version
|
|
201
|
+
version: '0'
|
|
202
|
+
type: :development
|
|
203
|
+
prerelease: false
|
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
205
|
+
requirements:
|
|
206
|
+
- - ">="
|
|
207
|
+
- !ruby/object:Gem::Version
|
|
208
|
+
version: '0'
|
|
209
|
+
description:
|
|
210
|
+
email:
|
|
211
|
+
- contato@codeminer42.com.br
|
|
212
|
+
executables: []
|
|
213
|
+
extensions: []
|
|
214
|
+
extra_rdoc_files: []
|
|
215
|
+
files:
|
|
216
|
+
- ".env.pipelines"
|
|
217
|
+
- ".gitignore"
|
|
218
|
+
- ".rspec"
|
|
219
|
+
- ".ruby-gemset"
|
|
220
|
+
- ".ruby-version"
|
|
221
|
+
- ".simplecov"
|
|
222
|
+
- CHANGELOG.md
|
|
223
|
+
- Gemfile
|
|
224
|
+
- Gemfile.lock
|
|
225
|
+
- README.md
|
|
226
|
+
- Rakefile
|
|
227
|
+
- bin/console
|
|
228
|
+
- bin/setup
|
|
229
|
+
- bitbucket-pipelines.yml
|
|
230
|
+
- identity_toolbox.gemspec
|
|
231
|
+
- lib/identity_toolbox.rb
|
|
232
|
+
- lib/identity_toolbox/authorizable.rb
|
|
233
|
+
- lib/identity_toolbox/configuration.rb
|
|
234
|
+
- lib/identity_toolbox/default_policy.rb
|
|
235
|
+
- lib/identity_toolbox/identity_service.rb
|
|
236
|
+
- lib/identity_toolbox/policy_methods.rb
|
|
237
|
+
- lib/identity_toolbox/spec_support/authorization_steps.rb
|
|
238
|
+
- lib/identity_toolbox/spec_support/shared_examples_for_controllers.rb
|
|
239
|
+
- lib/identity_toolbox/spec_support/shared_examples_for_policies.rb
|
|
240
|
+
- lib/identity_toolbox/spec_support/shared_examples_for_policy_scopes.rb
|
|
241
|
+
- lib/identity_toolbox/spec_support/tags.rb
|
|
242
|
+
- lib/identity_toolbox/version.rb
|
|
243
|
+
homepage:
|
|
244
|
+
licenses: []
|
|
245
|
+
metadata: {}
|
|
246
|
+
post_install_message:
|
|
247
|
+
rdoc_options: []
|
|
248
|
+
require_paths:
|
|
249
|
+
- lib
|
|
250
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
251
|
+
requirements:
|
|
252
|
+
- - ">="
|
|
253
|
+
- !ruby/object:Gem::Version
|
|
254
|
+
version: '0'
|
|
255
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
256
|
+
requirements:
|
|
257
|
+
- - ">="
|
|
258
|
+
- !ruby/object:Gem::Version
|
|
259
|
+
version: '0'
|
|
260
|
+
requirements: []
|
|
261
|
+
rubyforge_project:
|
|
262
|
+
rubygems_version: 2.7.7
|
|
263
|
+
signing_key:
|
|
264
|
+
specification_version: 4
|
|
265
|
+
summary: Tools to provide user authorization and data scoping.
|
|
266
|
+
test_files: []
|