zaikio-oauth_client 0.10.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84383fd7b0b03f23cc671489124b6b8f90613cad840bd668080ea04c59a4ff54
4
- data.tar.gz: e7b8f6759983ffad763780b392be0500888affd117c1ccfb9f87449ed1b1a9de
3
+ metadata.gz: 35a2d3f9ebe6c1f7eadc74624d9f9f1f0f8cd34aefb6ce9fff5cccb7b5fd5bd9
4
+ data.tar.gz: 075dde605bc8835dc73cdfab45cf16181ab79af764105ab37a61d520d7bb2692
5
5
  SHA512:
6
- metadata.gz: caae8092591d3d47a03ddf598d8da76d474cc45ff01e5799f140d8dbad3ca171294217ceddc1e0ffbc364f8efd3153c5222e51711afbd8f17d39daf1f01f409b
7
- data.tar.gz: 2759d26c2826f6cf06aba7c7673eaf2ee7cf30914ca4c965eefe99409efb575916c4fe0cfdde315ed64f95e20720b83712ae2d5bb3a9820dfedb908a9e38e094
6
+ metadata.gz: 6ecc782ef623fee48306b46e348d06225e37eaae4f02444072a79f1477ca73394a5dce80628f16ccd374bb589cd588c249312981aec17d71349660ababe72428
7
+ data.tar.gz: 4327a4b1f59e38fd290654485d3ab535ccb2acc9e4cc395d117025dc6865df8d2e49f1a7e9f5a29458270df26bed65d14835229199047ed218c90d4b3529fc02
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: `cookies.encrypted[:zaikio_person_id]`.
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: cookies.encrypted[:zaikio_person_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
- cookies.encrypted[:zaikio_person_id] = access_token.bearer_id unless access_token.organization?
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
- cookies.delete :zaikio_person_id
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.
@@ -3,6 +3,8 @@ 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
+ opts[:state] ||= session[:state] = SecureRandom.urlsafe_base64(32)
6
8
 
7
9
  plan = opts.delete(:plan)
8
10
  organization_id = opts.delete(:organization_id)
@@ -0,0 +1,4 @@
1
+ de:
2
+ zaikio:
3
+ oauth_client:
4
+ error_occured: "Beim Login ist ein Fehler aufgetreten: %{error} %{description}. Bitte versuche es nochmal."
@@ -1,6 +1,7 @@
1
1
  en:
2
2
  zaikio:
3
+ oauth_client:
4
+ error_occured: "An error occurred during login: %{error} %{description}. Please try again."
3
5
  forms:
4
6
  optional: Optional
5
7
  learn_more: Learn more
6
-
@@ -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"
@@ -4,8 +4,11 @@ module Zaikio
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  def new
7
- opts = params.permit(:client_name, :show_signup, :force_login, :state)
7
+ opts = params.permit(:client_name, :show_signup, :force_login, :state, :lang)
8
+ opts[:redirect_with_error] = 1
9
+ opts[:lang] ||= I18n.locale if defined?(I18n)
8
10
  client_name = opts.delete(:client_name)
11
+ opts[:state] ||= session[:state] = SecureRandom.urlsafe_base64(32)
9
12
 
10
13
  redirect_to oauth_client.auth_code.authorize_url(
11
14
  redirect_uri: approve_url(client_name),
@@ -15,12 +18,27 @@ module Zaikio
15
18
  end
16
19
 
17
20
  def approve
21
+ if params[:error].present?
22
+ redirect_to send(
23
+ respond_to?(:error_path_for) ? :error_path_for : :default_error_path_for,
24
+ params[:error],
25
+ description: params[:error_description]
26
+ ) and return
27
+ end
28
+
29
+ if session[:state].present? && params[:state] != session[:state]
30
+ return redirect_to send(
31
+ respond_to?(:error_path_for) ? :error_path_for : :default_error_path_for,
32
+ "invalid_state"
33
+ )
34
+ end
35
+
18
36
  access_token = create_access_token
19
37
 
20
- origin = cookies.encrypted[:origin]
21
- cookies.delete :origin
38
+ origin = session[:origin]
39
+ session.delete(:origin)
22
40
 
23
- cookies.encrypted[:zaikio_access_token_id] = access_token.id unless access_token.organization?
41
+ session[:zaikio_access_token_id] = access_token.id unless access_token.organization?
24
42
 
25
43
  redirect_to send(
26
44
  respond_to?(:after_approve_path_for) ? :after_approve_path_for : :default_after_approve_path_for,
@@ -29,8 +47,9 @@ module Zaikio
29
47
  end
30
48
 
31
49
  def destroy
32
- access_token_id = cookies.encrypted[:zaikio_access_token_id]
33
- cookies.delete :zaikio_access_token_id
50
+ access_token_id = session[:zaikio_access_token_id]
51
+ session.delete(:zaikio_access_token_id)
52
+ session.delete(:origin)
34
53
 
35
54
  redirect_to send(
36
55
  respond_to?(:after_destroy_path_for) ? :after_destroy_path_for : :default_after_destroy_path_for,
@@ -77,13 +96,23 @@ module Zaikio
77
96
  end
78
97
 
79
98
  def default_after_approve_path_for(access_token, origin)
80
- cookies.encrypted[:zaikio_person_id] = access_token.bearer_id unless access_token.organization?
99
+ session[:zaikio_person_id] = access_token.bearer_id unless access_token.organization?
81
100
 
82
101
  origin || main_app.root_path
83
102
  end
84
103
 
85
104
  def default_after_destroy_path_for(_access_token_id)
86
- cookies.delete :zaikio_person_id
105
+ session.delete(:origin)
106
+
107
+ main_app.root_path
108
+ end
109
+
110
+ def default_error_path_for(error_code, description: nil)
111
+ raise Zaikio::OAuthClient::InvalidScopesError, description if error_code == "invalid_scope"
112
+
113
+ unless error_code == "access_denied"
114
+ flash[:alert] = I18n.t("zaikio.oauth_client.error_occured", error: error_code, description: description)
115
+ end
87
116
 
88
117
  main_app.root_path
89
118
  end
@@ -0,0 +1,5 @@
1
+ module Zaikio
2
+ module OAuthClient
3
+ class InvalidScopesError < StandardError; end
4
+ end
5
+ end
@@ -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
- def logged_in_as(person)
7
- # We need to manually encrypt the value since the tests cookie jar does not
8
- # support encrypted or signed cookies
9
- encrypted_cookies = ActionDispatch::Request.new(Rails.application.env_config.deep_dup).cookie_jar
10
- encrypted_cookies.encrypted[:zaikio_person_id] = person.id
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
- cookies["zaikio_person_id"] = encrypted_cookies["zaikio_person_id"]
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
@@ -1,5 +1,5 @@
1
1
  module Zaikio
2
2
  module OAuthClient
3
- VERSION = "0.10.0".freeze
3
+ VERSION = "0.13.0".freeze
4
4
  end
5
5
  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.10.0
4
+ version: 0.13.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-04-15 00:00:00.000000000 Z
11
+ date: 2021-04-28 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.2.1
89
+ version: '0.5'
90
90
  - - "<"
91
91
  - !ruby/object:Gem::Version
92
- version: 0.5.0
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.2.1
99
+ version: '0.5'
100
100
  - - "<"
101
101
  - !ruby/object:Gem::Version
102
- version: 0.5.0
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/master/CHANGELOG.md
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: