zaikio-oauth_client 0.9.0 → 0.12.1
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 +24 -4
- data/app/controllers/zaikio/oauth_client/subscriptions_controller.rb +13 -5
- data/config/locales/de.yml +4 -0
- data/config/locales/en.yml +2 -1
- data/lib/zaikio/oauth_client.rb +20 -8
- data/lib/zaikio/oauth_client/authenticatable.rb +35 -7
- data/lib/zaikio/oauth_client/configuration.rb +7 -2
- data/lib/zaikio/oauth_client/error.rb +5 -0
- data/lib/zaikio/oauth_client/system_test_helper.rb +18 -0
- data/lib/zaikio/oauth_client/test_helper.rb +41 -6
- data/lib/zaikio/oauth_client/version.rb +1 -1
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e0377cbc59afa07b79f540877cbba7c79c0a23240202cdd1e1b0b1f79d21104
|
4
|
+
data.tar.gz: 3b99c3429d501c37bb259046159794df88a26789d519a7ec50203961a62cfd43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6b9f87688b92771ee8bb9ae1eea9ae9c83a09f393860925698ffa7adf515478b70d1621e438420ae39642a27c8c193a5a8232e1d028c58858428d8835b685e2
|
7
|
+
data.tar.gz: 153edcd1c0eb91874efd44ad501c157ad5210da20447064b07d59967593cb59a2e940767f3a3c32943ae550a55e0f537a737bcab4f17fe6d373ff44f049c06f8
|
data/README.md
CHANGED
@@ -133,12 +133,12 @@ redirect_to zaikio_oauth_client.new_subscription_path(plan: "free")
|
|
133
133
|
|
134
134
|
#### Session handling
|
135
135
|
|
136
|
-
The Zaikio gem engine will set a cookie for the user after a successful OAuth flow: `
|
136
|
+
The Zaikio gem engine will set a cookie for the user after a successful OAuth flow: `session[:zaikio_person_id]`.
|
137
137
|
|
138
138
|
If you are using for example `Zaikio::Hub::Models`, you can use this snippet to set the current user:
|
139
139
|
|
140
140
|
```ruby
|
141
|
-
Current.user ||= Zaikio::Hub::Models::Person.find_by(id:
|
141
|
+
Current.user ||= Zaikio::Hub::Models::Person.find_by(id: session[:zaikio_person_id])
|
142
142
|
````
|
143
143
|
|
144
144
|
You can then use `Current.user` anywhere.
|
@@ -172,7 +172,7 @@ Additionally you can also specify your own redirect handlers in your `Applicatio
|
|
172
172
|
```rb
|
173
173
|
class ApplicationController < ActionController::Base
|
174
174
|
def after_approve_path_for(access_token, origin)
|
175
|
-
|
175
|
+
session[:zaikio_person_id] = access_token.bearer_id unless access_token.organization?
|
176
176
|
|
177
177
|
# Sync data on login
|
178
178
|
Zaikio::Hub.with_token(access_token.token) do
|
@@ -183,10 +183,15 @@ class ApplicationController < ActionController::Base
|
|
183
183
|
end
|
184
184
|
|
185
185
|
def after_destroy_path_for(access_token_id)
|
186
|
-
|
186
|
+
reset_session
|
187
187
|
|
188
188
|
main_app.root_path
|
189
189
|
end
|
190
|
+
|
191
|
+
def error_path_for(error_code, description: nil)
|
192
|
+
# Handle error
|
193
|
+
main_app.root_path
|
194
|
+
end
|
190
195
|
end
|
191
196
|
```
|
192
197
|
|
@@ -234,6 +239,21 @@ class MyControllerTest < ActionDispatch::IntegrationTest
|
|
234
239
|
end
|
235
240
|
```
|
236
241
|
|
242
|
+
For system tests (e.g. with a separate browser instance), there's a special helper:
|
243
|
+
|
244
|
+
```rb
|
245
|
+
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
246
|
+
include Zaikio::OAuthClient::SystemTestHelper
|
247
|
+
|
248
|
+
test "does request" do
|
249
|
+
person = people(:my_person)
|
250
|
+
logged_in_as(person)
|
251
|
+
|
252
|
+
visit "/"
|
253
|
+
end
|
254
|
+
end
|
255
|
+
```
|
256
|
+
|
237
257
|
#### Authenticated requests
|
238
258
|
|
239
259
|
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.
|
@@ -2,15 +2,23 @@ module Zaikio
|
|
2
2
|
module OAuthClient
|
3
3
|
class SubscriptionsController < ConnectionsController
|
4
4
|
def new
|
5
|
-
opts = params.permit(:client_name, :state, :plan)
|
6
|
-
|
7
|
-
|
5
|
+
opts = params.permit(:client_name, :state, :plan, :organization_id)
|
6
|
+
opts[:redirect_with_error] = 1
|
7
|
+
opts[:state] ||= session[:state] = SecureRandom.urlsafe_base64(32)
|
8
|
+
|
9
|
+
plan = opts.delete(:plan)
|
10
|
+
organization_id = opts.delete(:organization_id)
|
11
|
+
|
12
|
+
subscription_scope = if organization_id.present?
|
13
|
+
"Org/#{organization_id}.subscription_create"
|
14
|
+
else
|
15
|
+
"Org.subscription_create"
|
16
|
+
end
|
8
17
|
|
9
|
-
subscription_scope = "Org.subscription_create"
|
10
18
|
subscription_scope << ".#{plan}" if plan.present?
|
11
19
|
|
12
20
|
redirect_to oauth_client.auth_code.authorize_url(
|
13
|
-
redirect_uri: approve_url(client_name),
|
21
|
+
redirect_uri: approve_url(opts.delete(:client_name)),
|
14
22
|
scope: subscription_scope,
|
15
23
|
**opts
|
16
24
|
)
|
data/config/locales/en.yml
CHANGED
data/lib/zaikio/oauth_client.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "oauth2"
|
2
2
|
|
3
|
+
require "zaikio/oauth_client/error"
|
3
4
|
require "zaikio/oauth_client/engine"
|
4
5
|
require "zaikio/oauth_client/configuration"
|
5
6
|
require "zaikio/oauth_client/authenticatable"
|
@@ -82,14 +83,25 @@ module Zaikio
|
|
82
83
|
# Finds the best usable access token. Note that this token may have expired and
|
83
84
|
# would require refreshing.
|
84
85
|
def find_usable_access_token(client_name:, bearer_type:, bearer_id:, requested_scopes:)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
86
|
+
configuration.logger.debug "Try to fetch token for client_name: #{client_name}, "\
|
87
|
+
"bearer #{bearer_type}/#{bearer_id}, requested_scopes: #{requested_scopes}"
|
88
|
+
|
89
|
+
fetch_access_token = lambda {
|
90
|
+
Zaikio::AccessToken
|
91
|
+
.where(audience: client_name)
|
92
|
+
.usable(
|
93
|
+
bearer_type: bearer_type,
|
94
|
+
bearer_id: bearer_id,
|
95
|
+
requested_scopes: requested_scopes
|
96
|
+
)
|
97
|
+
.first
|
98
|
+
}
|
99
|
+
|
100
|
+
if configuration.logger.respond_to?(:silence)
|
101
|
+
configuration.logger.silence { fetch_access_token.call }
|
102
|
+
else
|
103
|
+
fetch_access_token.call
|
104
|
+
end
|
93
105
|
end
|
94
106
|
|
95
107
|
def fetch_new_token(client_config:, bearer_type:, bearer_id:, scopes:)
|
@@ -5,7 +5,9 @@ module Zaikio
|
|
5
5
|
|
6
6
|
def new
|
7
7
|
opts = params.permit(:client_name, :show_signup, :force_login, :state)
|
8
|
+
opts[:redirect_with_error] = 1
|
8
9
|
client_name = opts.delete(:client_name)
|
10
|
+
opts[:state] ||= session[:state] = SecureRandom.urlsafe_base64(32)
|
9
11
|
|
10
12
|
redirect_to oauth_client.auth_code.authorize_url(
|
11
13
|
redirect_uri: approve_url(client_name),
|
@@ -15,12 +17,27 @@ module Zaikio
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def approve
|
20
|
+
if params[:error].present?
|
21
|
+
redirect_to send(
|
22
|
+
respond_to?(:error_path_for) ? :error_path_for : :default_error_path_for,
|
23
|
+
params[:error],
|
24
|
+
description: params[:error_description]
|
25
|
+
) and return
|
26
|
+
end
|
27
|
+
|
28
|
+
if session[:state].present? && params[:state] != session[:state]
|
29
|
+
return redirect_to send(
|
30
|
+
respond_to?(:error_path_for) ? :error_path_for : :default_error_path_for,
|
31
|
+
"invalid_state"
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
18
35
|
access_token = create_access_token
|
19
36
|
|
20
|
-
origin =
|
21
|
-
|
37
|
+
origin = session[:origin]
|
38
|
+
session.delete(:origin)
|
22
39
|
|
23
|
-
|
40
|
+
session[:zaikio_access_token_id] = access_token.id unless access_token.organization?
|
24
41
|
|
25
42
|
redirect_to send(
|
26
43
|
respond_to?(:after_approve_path_for) ? :after_approve_path_for : :default_after_approve_path_for,
|
@@ -29,8 +46,9 @@ module Zaikio
|
|
29
46
|
end
|
30
47
|
|
31
48
|
def destroy
|
32
|
-
access_token_id =
|
33
|
-
|
49
|
+
access_token_id = session[:zaikio_access_token_id]
|
50
|
+
session.delete(:zaikio_access_token_id)
|
51
|
+
session.delete(:origin)
|
34
52
|
|
35
53
|
redirect_to send(
|
36
54
|
respond_to?(:after_destroy_path_for) ? :after_destroy_path_for : :default_after_destroy_path_for,
|
@@ -77,13 +95,23 @@ module Zaikio
|
|
77
95
|
end
|
78
96
|
|
79
97
|
def default_after_approve_path_for(access_token, origin)
|
80
|
-
|
98
|
+
session[:zaikio_person_id] = access_token.bearer_id unless access_token.organization?
|
81
99
|
|
82
100
|
origin || main_app.root_path
|
83
101
|
end
|
84
102
|
|
85
103
|
def default_after_destroy_path_for(_access_token_id)
|
86
|
-
|
104
|
+
session.delete(:origin)
|
105
|
+
|
106
|
+
main_app.root_path
|
107
|
+
end
|
108
|
+
|
109
|
+
def default_error_path_for(error_code, description: nil)
|
110
|
+
raise Zaikio::OAuthClient::InvalidScopesError, description if error_code == "invalid_scope"
|
111
|
+
|
112
|
+
unless error_code == "access_denied"
|
113
|
+
flash[:alert] = I18n.t("zaikio.oauth_client.error_occured", error: error_code, description: description)
|
114
|
+
end
|
87
115
|
|
88
116
|
main_app.root_path
|
89
117
|
end
|
@@ -13,7 +13,6 @@ module Zaikio
|
|
13
13
|
}.freeze
|
14
14
|
|
15
15
|
attr_accessor :host
|
16
|
-
attr_writer :logger
|
17
16
|
attr_reader :client_configurations, :environment, :around_auth_block,
|
18
17
|
:sessions_controller_name, :connections_controller_name, :subscriptions_controller_name
|
19
18
|
|
@@ -23,10 +22,16 @@ module Zaikio
|
|
23
22
|
@sessions_controller_name = "sessions"
|
24
23
|
@connections_controller_name = "connections"
|
25
24
|
@subscriptions_controller_name = "subscriptions"
|
25
|
+
Zaikio::AccessToken.logger = logger
|
26
26
|
end
|
27
27
|
|
28
28
|
def logger
|
29
|
-
@logger ||= Logger.new($stdout)
|
29
|
+
@logger ||= ActiveSupport::Logger.new($stdout)
|
30
|
+
end
|
31
|
+
|
32
|
+
def logger=(logger)
|
33
|
+
@logger = logger
|
34
|
+
Zaikio::AccessToken.logger = @logger
|
30
35
|
end
|
31
36
|
|
32
37
|
def register_client(name)
|
@@ -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,13 +3,48 @@ module Zaikio
|
|
3
3
|
module TestHelper
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
class TestSessionController < ActionController::Base
|
7
|
+
def show
|
8
|
+
if session[params[:key]].nil?
|
9
|
+
head :no_content
|
10
|
+
else
|
11
|
+
render plain: session[params[:key]]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
session[params[:key]] = params[:id]
|
17
|
+
|
18
|
+
head :ok
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
included do
|
23
|
+
# This is needed as it is not possible to set sesison values in an ActionDispatch::IntegrationTest
|
24
|
+
# This creates a dummy controller to set the session
|
25
|
+
Rails.application.routes.disable_clear_and_finalize = true # Keep existing routes
|
26
|
+
Rails.application.routes.draw do
|
27
|
+
get "/zaikio/oauth_client/test_helper/get_session", to: "zaikio/oauth_client/test_helper/test_session#show"
|
28
|
+
get "/zaikio/oauth_client/test_helper/session", to: "zaikio/oauth_client/test_helper/test_session#create"
|
29
|
+
end
|
30
|
+
end
|
11
31
|
|
12
|
-
|
32
|
+
def get_session(key)
|
33
|
+
get "/zaikio/oauth_client/test_helper/get_session", params: { key: key }
|
34
|
+
|
35
|
+
if response.status == 204
|
36
|
+
nil
|
37
|
+
else
|
38
|
+
response.body
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_session(key, value)
|
43
|
+
get "/zaikio/oauth_client/test_helper/session", params: { id: value, key: key }
|
44
|
+
end
|
45
|
+
|
46
|
+
def logged_in_as(person)
|
47
|
+
set_session(:zaikio_person_id, person.id)
|
13
48
|
end
|
14
49
|
end
|
15
50
|
end
|
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.12.1
|
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-04-
|
11
|
+
date: 2021-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -86,20 +86,20 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
89
|
+
version: '0.5'
|
90
90
|
- - "<"
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
92
|
+
version: '2.0'
|
93
93
|
type: :runtime
|
94
94
|
prerelease: false
|
95
95
|
version_requirements: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
97
|
- - ">="
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version: 0.
|
99
|
+
version: '0.5'
|
100
100
|
- - "<"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
102
|
+
version: '2.0'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: pg
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +150,7 @@ files:
|
|
150
150
|
- app/jobs/zaikio/cleanup_access_tokens_job.rb
|
151
151
|
- app/models/zaikio/access_token.rb
|
152
152
|
- config/initializers/inflections.rb
|
153
|
+
- config/locales/de.yml
|
153
154
|
- config/locales/en.yml
|
154
155
|
- config/routes.rb
|
155
156
|
- db/migrate/20190426155505_enable_postgres_extensions_for_uuids.rb
|
@@ -162,13 +163,15 @@ files:
|
|
162
163
|
- lib/zaikio/oauth_client/client_configuration.rb
|
163
164
|
- lib/zaikio/oauth_client/configuration.rb
|
164
165
|
- lib/zaikio/oauth_client/engine.rb
|
166
|
+
- lib/zaikio/oauth_client/error.rb
|
167
|
+
- lib/zaikio/oauth_client/system_test_helper.rb
|
165
168
|
- lib/zaikio/oauth_client/test_helper.rb
|
166
169
|
- lib/zaikio/oauth_client/version.rb
|
167
170
|
homepage: https://github.com/zaikio/zaikio-oauth_client
|
168
171
|
licenses:
|
169
172
|
- MIT
|
170
173
|
metadata:
|
171
|
-
changelog_uri: https://github.com/zaikio/zaikio-oauth_client/blob/
|
174
|
+
changelog_uri: https://github.com/zaikio/zaikio-oauth_client/blob/main/CHANGELOG.md
|
172
175
|
post_install_message:
|
173
176
|
rdoc_options: []
|
174
177
|
require_paths:
|