keycloak_oauth 0.1.2 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36235d5a3f0e96e1b1ddac55c9825545ee11244ec785fff42c30029ee1ba33eb
4
- data.tar.gz: 7778aeab5443dcaa32dd301e2fe45a0b4c099e0ea9cd6fe289b6d2de8f1dc113
3
+ metadata.gz: 45b0a220afa0ca575a22ed7fd5cf958dc4d7ad2450a116f3bdf7e5e3546d6eac
4
+ data.tar.gz: eeb8fcb58d29e1cf18d4cf3fadddbf184029576b97bb9194e4218f4889636f05
5
5
  SHA512:
6
- metadata.gz: 4284790fc0cf71a7dd853d7e45f2b894500ff485b1e502857801ce5b453abb5658db95f078bb4c32b132a3f075e7ca7460b42093583a9eeba688cb3ebf1f6cf7
7
- data.tar.gz: 8d81ce99e61b047f6c1cd426d73e700b8c27dd9361ae5639994932e5b3c2ed06ba844fea3c5bf69ac1ca92a0206c19154fbe0a42e34a72bae9e07f65acba3b60
6
+ metadata.gz: 58a27c6c046d783c0f83db3a8857d06aab9402e85d00a6d880eb0ad637d2b5f8a4e4c4e4df03065f03097bfda98439f735b8257d10c52046be85d0c210aeef3e
7
+ data.tar.gz: dc6cc4e9a90c8f78a09e3b2b90d19ca7973aea125678170ba2be0902d490eba1ff17cbcfcce9a22e78f9b85324f3bce77f5bb878a722dfc8113cf72b01505581
data/README.md CHANGED
@@ -65,6 +65,19 @@ KeycloakOauth.configure do |config|
65
65
  end
66
66
  ```
67
67
 
68
+ **User mapping**
69
+ The host app is responsible for mapping a Keycloak session with a Rails user session. This can be achieved
70
+ by implementing the `map_authenticatable` method in the module configured above (e.g. `KeycloakOauthCallbacks` in our example).
71
+ You can get the user information by making a call to `KeycloakOauth.connection.get_user_information` to which you pass in the access token.
72
+ See here an example of retrieving the user information and saving the email address in the Rails session:
73
+
74
+ ```ruby
75
+ def map_authenticatable(_request)
76
+ service = KeycloakOauth.connection.get_user_information(access_token: session[:access_token])
77
+ session[:user_email_address] = service.user_information['email']
78
+ end
79
+ ```
80
+
68
81
  ## Development
69
82
 
70
83
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -10,6 +10,7 @@ module KeycloakOauth
10
10
  session: session
11
11
  )
12
12
  authentication_service.authenticate
13
+ map_authenticatable_if_implemented(session)
13
14
 
14
15
  redirect_to self.class.method_defined?(:after_sign_in_path) ? after_sign_in_path(request) : '/'
15
16
  end
@@ -19,5 +20,13 @@ module KeycloakOauth
19
20
  def authentication_params
20
21
  params.permit(:code)
21
22
  end
23
+
24
+ def map_authenticatable_if_implemented(request)
25
+ if self.class.method_defined?(:map_authenticatable)
26
+ map_authenticatable(request)
27
+ else
28
+ raise NotImplementedError.new('User mapping must be handled by the host app. See README for more information.')
29
+ end
30
+ end
22
31
  end
23
32
  end
@@ -0,0 +1,45 @@
1
+ require 'net/http'
2
+
3
+ module KeycloakOauth
4
+ class UserInfoRetrievalError < StandardError; end
5
+
6
+ class UserInfoRetrievalService
7
+ AUTHORIZATION_HEADER = 'Authorization'.freeze
8
+ CONTENT_TYPE = 'application/x-www-form-urlencoded'.freeze
9
+
10
+ attr_reader :user_information
11
+
12
+ def initialize(access_token:)
13
+ @access_token = access_token
14
+ end
15
+
16
+ def retrieve
17
+ @user_information = parsed_user_information(get_user)
18
+ end
19
+
20
+ private
21
+
22
+ attr_accessor :access_token
23
+
24
+ def get_user
25
+ uri = URI.parse(KeycloakOauth.connection.user_info_endpoint)
26
+ Net::HTTP.start(uri.host, uri.port) do |http|
27
+ request = Net::HTTP::Get.new(uri)
28
+ request.set_content_type(CONTENT_TYPE)
29
+ request[AUTHORIZATION_HEADER] = "Bearer #{access_token}"
30
+ http.request(request)
31
+ end
32
+ end
33
+
34
+ def parsed_user_information(http_response)
35
+ response_hash = JSON.parse(http_response.body)
36
+
37
+ return response_hash if http_response.code_type == Net::HTTPOK
38
+
39
+ # TODO: For now, we assume that the access token is always valid.
40
+ # We do not yet handle the case where a refresh token is passed in and
41
+ # used if the access token has expired.
42
+ raise KeycloakOauth::UserInfoRetrievalError.new(response_hash)
43
+ end
44
+ end
45
+ end
@@ -1,8 +1,10 @@
1
+ require 'keycloak_oauth/endpoints'
2
+
1
3
  module KeycloakOauth
2
4
  class Connection
3
- attr_reader :auth_url, :realm, :client_id, :client_secret, :callback_module
5
+ include KeycloakOauth::Endpoints
4
6
 
5
- DEFAULT_RESPONSE_TYPE = 'code'.freeze
7
+ attr_reader :auth_url, :realm, :client_id, :client_secret, :callback_module
6
8
 
7
9
  def initialize(auth_url:, realm:, client_id:, client_secret:, callback_module: nil)
8
10
  @auth_url = auth_url
@@ -12,13 +14,10 @@ module KeycloakOauth
12
14
  @callback_module = callback_module
13
15
  end
14
16
 
15
- def authorization_endpoint(options: {})
16
- endpoint = "#{auth_url}/realms/#{realm}/protocol/openid-connect/auth?client_id=#{client_id}"
17
- endpoint += "&response_type=#{options[:response_type] || DEFAULT_RESPONSE_TYPE}"
18
- end
19
-
20
- def authentication_endpoint
21
- "#{auth_url}/realms/#{realm}/protocol/openid-connect/token"
17
+ def get_user_information(access_token:)
18
+ service = KeycloakOauth::UserInfoRetrievalService.new(access_token: access_token)
19
+ service.retrieve
20
+ service.user_information
22
21
  end
23
22
  end
24
23
  end
@@ -0,0 +1,18 @@
1
+ module KeycloakOauth
2
+ module Endpoints
3
+ DEFAULT_RESPONSE_TYPE = 'code'.freeze
4
+
5
+ def authorization_endpoint(options: {})
6
+ endpoint = "#{auth_url}/realms/#{realm}/protocol/openid-connect/auth?client_id=#{client_id}"
7
+ endpoint += "&response_type=#{options[:response_type] || DEFAULT_RESPONSE_TYPE}"
8
+ end
9
+
10
+ def authentication_endpoint
11
+ "#{auth_url}/realms/#{realm}/protocol/openid-connect/token"
12
+ end
13
+
14
+ def user_info_endpoint
15
+ "#{auth_url}/realms/#{realm}/protocol/openid-connect/userinfo"
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module KeycloakOauth
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keycloak_oauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - simplificator
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: 6.0.3
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 6.0.3.3
22
+ version: 6.0.3.2
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: 6.0.3
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 6.0.3.3
32
+ version: 6.0.3.2
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rspec-rails
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -70,10 +70,12 @@ files:
70
70
  - app/controllers/keycloak_oauth/application_controller.rb
71
71
  - app/controllers/keycloak_oauth/callbacks_controller.rb
72
72
  - app/services/keycloak_oauth/authentication_service.rb
73
+ - app/services/keycloak_oauth/user_info_retrieval_service.rb
73
74
  - config/routes.rb
74
75
  - lib/keycloak_oauth.rb
75
76
  - lib/keycloak_oauth/configuration.rb
76
77
  - lib/keycloak_oauth/connection.rb
78
+ - lib/keycloak_oauth/endpoints.rb
77
79
  - lib/keycloak_oauth/engine.rb
78
80
  - lib/keycloak_oauth/version.rb
79
81
  homepage: https://rubygems.org/gems/keycloak_oauth