zaikio-oauth_client 0.12.0 → 0.15.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 +4 -4
- data/README.md +50 -21
- data/Rakefile +1 -3
- data/app/controllers/zaikio/oauth_client/subscriptions_controller.rb +0 -1
- data/app/models/zaikio/access_token.rb +2 -2
- data/lib/zaikio/oauth_client.rb +7 -7
- data/lib/zaikio/oauth_client/authenticatable.rb +4 -4
- data/lib/zaikio/oauth_client/client_configuration.rb +1 -1
- data/lib/zaikio/oauth_client/system_test_helper.rb +18 -0
- data/lib/zaikio/oauth_client/test_helper.rb +1 -1
- data/lib/zaikio/oauth_client/version.rb +1 -1
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb0748eddd282729e6a9ca264b17a59d58b9822c5e900f1bc3690b2b10549567
|
4
|
+
data.tar.gz: 191d4f0652fa8dfb9dae28bbfcd550ef8b2114366ef41ad291f25620011e8d3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21c66faa4cd6cad8b787b39f919b0e1c30ec718b912f5442ad0fd4c96b7871a0db798bdf84e798d3ddaf441f8ae96819abea31fad7b4a631b12d2983fef378be
|
7
|
+
data.tar.gz: acc5550981b27d38cb986e0b934d4dad992ea7f3c462d9dd1f6c202a304e4cd13bb8e202db070f66f458e3263606601943d1f078d9967125c89b068d82554126
|
data/README.md
CHANGED
@@ -36,32 +36,34 @@ mount Zaikio::OAuthClient::Engine => "/zaikio"
|
|
36
36
|
|
37
37
|
```rb
|
38
38
|
# config/initializers/zaikio_oauth_client.rb
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
39
|
+
Rails.application.reloader.to_prepare do
|
40
|
+
Zaikio::OAuthClient.configure do |config|
|
41
|
+
config.environment = :sandbox
|
42
|
+
|
43
|
+
config.register_client :warehouse do |warehouse|
|
44
|
+
warehouse.client_id = "52022d7a-7ba2-41ed-8890-97d88e6472f6"
|
45
|
+
warehouse.client_secret = "ShiKTnHqEf3M8nyHQPyZgbz7"
|
46
|
+
warehouse.default_scopes = %w[directory.person.r]
|
47
|
+
|
48
|
+
warehouse.register_organization_connection do |org|
|
49
|
+
org.default_scopes = %w[directory.organization.r]
|
50
|
+
end
|
49
51
|
end
|
50
|
-
end
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
config.register_client :warehouse_goods_call_of do |warehouse_goods_call_of|
|
54
|
+
warehouse_goods_call_of.client_id = "12345-7ba2-41ed-8890-97d88e6472f6"
|
55
|
+
warehouse_goods_call_of.client_secret = "secret"
|
56
|
+
warehouse_goods_call_of.default_scopes = %w[directory.person.r]
|
56
57
|
|
57
|
-
|
58
|
-
|
58
|
+
warehouse_goods_call_of.register_organization_connection do |org|
|
59
|
+
org.default_scopes = %w[directory.organization.r]
|
60
|
+
end
|
59
61
|
end
|
60
|
-
end
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
config.around_auth do |access_token, block|
|
64
|
+
Zaikio::Hub.with_token(access_token.token) do
|
65
|
+
block.call(access_token)
|
66
|
+
end
|
65
67
|
end
|
66
68
|
end
|
67
69
|
end
|
@@ -239,6 +241,21 @@ class MyControllerTest < ActionDispatch::IntegrationTest
|
|
239
241
|
end
|
240
242
|
```
|
241
243
|
|
244
|
+
For system tests (e.g. with a separate browser instance), there's a special helper:
|
245
|
+
|
246
|
+
```rb
|
247
|
+
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
248
|
+
include Zaikio::OAuthClient::SystemTestHelper
|
249
|
+
|
250
|
+
test "does request" do
|
251
|
+
person = people(:my_person)
|
252
|
+
logged_in_as(person)
|
253
|
+
|
254
|
+
visit "/"
|
255
|
+
end
|
256
|
+
end
|
257
|
+
```
|
258
|
+
|
242
259
|
#### Authenticated requests
|
243
260
|
|
244
261
|
Now further requests to the Directory API or to other Zaikio APIs should be made. For this purpose the OAuthClient provides a helper method `with_auth` that automatically fetches an access token from the database, requests a refresh token or creates a new access token via client credentials flow.
|
@@ -249,6 +266,18 @@ Zaikio::OAuthClient.with_auth(bearer_type: "Organization", bearer_id: "fd61f5f5-
|
|
249
266
|
end
|
250
267
|
```
|
251
268
|
|
269
|
+
If you need the token for a certain period (e.g. a long-running job which makes many
|
270
|
+
requests in sequence), you can specify the `valid_for` interval when requesting the token.
|
271
|
+
By default, it won't return an access token which was due to expire in less than 30
|
272
|
+
seconds from now. If there is an existing token, but it was due to expire before the end
|
273
|
+
of the validity period, this will go and get a fresh token anyway:
|
274
|
+
|
275
|
+
```rb
|
276
|
+
Zaikio::OAuthClient.with_auth(..., valid_for: 10.minutes) do |access_token|
|
277
|
+
# ...
|
278
|
+
end
|
279
|
+
```
|
280
|
+
|
252
281
|
## Use of dummy app
|
253
282
|
|
254
283
|
You can use the included dummy app as a showcase for the workflow and to adjust your own application. To set up the dummy application properly, go into `test/dummy` and use [puma-dev](https://github.com/puma/puma-dev) like this:
|
data/Rakefile
CHANGED
@@ -35,9 +35,7 @@ require 'rubocop/rake_task'
|
|
35
35
|
|
36
36
|
namespace :test do
|
37
37
|
desc 'Runs RuboCop on specified directories'
|
38
|
-
RuboCop::RakeTask.new(:rubocop)
|
39
|
-
task.fail_on_error = false
|
40
|
-
end
|
38
|
+
RuboCop::RakeTask.new(:rubocop)
|
41
39
|
end
|
42
40
|
|
43
41
|
Rake::Task[:test].enhance ['test:rubocop']
|
@@ -3,7 +3,6 @@ module Zaikio
|
|
3
3
|
class SubscriptionsController < ConnectionsController
|
4
4
|
def new
|
5
5
|
opts = params.permit(:client_name, :state, :plan, :organization_id)
|
6
|
-
opts[:redirect_with_error] = 1
|
7
6
|
opts[:state] ||= session[:state] = SecureRandom.urlsafe_base64(32)
|
8
7
|
|
9
8
|
plan = opts.delete(:plan)
|
@@ -5,7 +5,7 @@ module Zaikio
|
|
5
5
|
class AccessToken < ApplicationRecord
|
6
6
|
self.table_name = "zaikio_access_tokens"
|
7
7
|
|
8
|
-
def self.build_from_access_token(access_token, requested_scopes: nil)
|
8
|
+
def self.build_from_access_token(access_token, requested_scopes: nil)
|
9
9
|
payload = JWT.decode(access_token.token, nil, false).first rescue {} # rubocop:disable Style/RescueModifier
|
10
10
|
scopes = access_token.params["scope"].split(",")
|
11
11
|
new(
|
@@ -37,7 +37,7 @@ module Zaikio
|
|
37
37
|
where("expires_at <= :now AND created_at > :created_at_max",
|
38
38
|
now: Time.current,
|
39
39
|
created_at_max: Time.current - refresh_token_valid_for)
|
40
|
-
.where(
|
40
|
+
.where.not(refresh_token: nil)
|
41
41
|
.where.not(id: Zaikio::JWTAuth.revoked_token_ids)
|
42
42
|
}
|
43
43
|
scope :by_bearer, lambda { |bearer_id:, requested_scopes: [], bearer_type: "Person"|
|
data/lib/zaikio/oauth_client.rb
CHANGED
@@ -49,7 +49,7 @@ module Zaikio
|
|
49
49
|
get_access_token(**options_or_access_token)
|
50
50
|
end
|
51
51
|
|
52
|
-
return unless
|
52
|
+
return unless block
|
53
53
|
|
54
54
|
if configuration.around_auth_block
|
55
55
|
configuration.around_auth_block.call(access_token, block)
|
@@ -62,7 +62,7 @@ module Zaikio
|
|
62
62
|
# * If the token has expired, it will be refreshed using the refresh_token flow
|
63
63
|
# (if this fails, we fallback to getting a new token using client_credentials)
|
64
64
|
# * If the token does not exist, we'll get a new one using the client_credentials flow
|
65
|
-
def get_access_token(bearer_id:, client_name: nil, bearer_type: "Person", scopes: nil)
|
65
|
+
def get_access_token(bearer_id:, client_name: nil, bearer_type: "Person", scopes: nil, valid_for: 30.seconds)
|
66
66
|
client_config = client_config_for(client_name || self.client_name)
|
67
67
|
scopes ||= client_config.default_scopes_for(bearer_type)
|
68
68
|
|
@@ -71,7 +71,7 @@ module Zaikio
|
|
71
71
|
bearer_id: bearer_id,
|
72
72
|
requested_scopes: scopes)
|
73
73
|
|
74
|
-
token = token.refresh! if token
|
74
|
+
token = token.refresh! if token && (token.expired? || token.expires_at < valid_for.from_now)
|
75
75
|
|
76
76
|
token ||= fetch_new_token(client_config: client_config,
|
77
77
|
bearer_type: bearer_type,
|
@@ -82,9 +82,9 @@ module Zaikio
|
|
82
82
|
|
83
83
|
# Finds the best usable access token. Note that this token may have expired and
|
84
84
|
# would require refreshing.
|
85
|
-
def find_usable_access_token(client_name:, bearer_type:, bearer_id:, requested_scopes:)
|
85
|
+
def find_usable_access_token(client_name:, bearer_type:, bearer_id:, requested_scopes:) # rubocop:disable Metrics/MethodLength
|
86
86
|
configuration.logger.debug "Try to fetch token for client_name: #{client_name}, "\
|
87
|
-
|
87
|
+
"bearer #{bearer_type}/#{bearer_id}, requested_scopes: #{requested_scopes}"
|
88
88
|
|
89
89
|
fetch_access_token = lambda {
|
90
90
|
Zaikio::AccessToken
|
@@ -117,9 +117,9 @@ module Zaikio
|
|
117
117
|
|
118
118
|
def get_plain_scopes(scopes)
|
119
119
|
regex = /^((Org|Per)\.)?(.*)$/
|
120
|
-
scopes.
|
120
|
+
scopes.filter_map do |scope|
|
121
121
|
(regex.match(scope) || [])[3]
|
122
|
-
end
|
122
|
+
end
|
123
123
|
end
|
124
124
|
|
125
125
|
private
|
@@ -4,8 +4,8 @@ module Zaikio
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
def new
|
7
|
-
opts = params.permit(:client_name, :show_signup, :force_login, :state)
|
8
|
-
opts[:
|
7
|
+
opts = params.permit(:client_name, :show_signup, :prompt, :force_login, :state, :lang)
|
8
|
+
opts[:lang] ||= I18n.locale if defined?(I18n)
|
9
9
|
client_name = opts.delete(:client_name)
|
10
10
|
opts[:state] ||= session[:state] = SecureRandom.urlsafe_base64(32)
|
11
11
|
|
@@ -16,7 +16,7 @@ module Zaikio
|
|
16
16
|
)
|
17
17
|
end
|
18
18
|
|
19
|
-
def approve
|
19
|
+
def approve # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
20
20
|
if params[:error].present?
|
21
21
|
redirect_to send(
|
22
22
|
respond_to?(:error_path_for) ? :error_path_for : :default_error_path_for,
|
@@ -81,7 +81,7 @@ module Zaikio
|
|
81
81
|
|
82
82
|
def client_config
|
83
83
|
client_config = Zaikio::OAuthClient.configuration.find!(client_name)
|
84
|
-
client_config =
|
84
|
+
client_config = client_config.org_config if use_org_config?
|
85
85
|
|
86
86
|
client_config or raise ActiveRecord::RecordNotFound
|
87
87
|
end
|
@@ -20,7 +20,7 @@ module Zaikio
|
|
20
20
|
client_secret,
|
21
21
|
authorize_url: "oauth/authorize",
|
22
22
|
token_url: "oauth/access_token",
|
23
|
-
connection_opts: { headers: {
|
23
|
+
connection_opts: { headers: { Accept: "application/json" } },
|
24
24
|
site: Zaikio::OAuthClient.configuration.host
|
25
25
|
)
|
26
26
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative "./test_helper"
|
2
|
+
|
3
|
+
module Zaikio
|
4
|
+
module OAuthClient
|
5
|
+
module SystemTestHelper
|
6
|
+
include ::Zaikio::OAuthClient::TestHelper
|
7
|
+
|
8
|
+
def set_session(key, value)
|
9
|
+
visit "/zaikio/oauth_client/test_helper/session?#{{ key: key, id: value }.to_query}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_session(key)
|
13
|
+
visit "/zaikio/oauth_client/test_helper/get_session?#{{ key: key }.to_query}"
|
14
|
+
page.text
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -3,7 +3,7 @@ module Zaikio
|
|
3
3
|
module TestHelper
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
class TestSessionController < ActionController::Base
|
6
|
+
class TestSessionController < ActionController::Base # rubocop:disable Rails/ApplicationController
|
7
7
|
def show
|
8
8
|
if session[params[:key]].nil?
|
9
9
|
head :no_content
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zaikio-oauth_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zaikio GmbH
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -84,16 +84,22 @@ dependencies:
|
|
84
84
|
name: zaikio-jwt_auth
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0.5'
|
90
|
+
- - "<"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '2.0'
|
90
93
|
type: :runtime
|
91
94
|
prerelease: false
|
92
95
|
version_requirements: !ruby/object:Gem::Requirement
|
93
96
|
requirements:
|
94
|
-
- - "
|
97
|
+
- - ">="
|
95
98
|
- !ruby/object:Gem::Version
|
96
99
|
version: '0.5'
|
100
|
+
- - "<"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '2.0'
|
97
103
|
- !ruby/object:Gem::Dependency
|
98
104
|
name: pg
|
99
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,6 +164,7 @@ files:
|
|
158
164
|
- lib/zaikio/oauth_client/configuration.rb
|
159
165
|
- lib/zaikio/oauth_client/engine.rb
|
160
166
|
- lib/zaikio/oauth_client/error.rb
|
167
|
+
- lib/zaikio/oauth_client/system_test_helper.rb
|
161
168
|
- lib/zaikio/oauth_client/test_helper.rb
|
162
169
|
- lib/zaikio/oauth_client/version.rb
|
163
170
|
homepage: https://github.com/zaikio/zaikio-oauth_client
|