keycloak-admin 0.2 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +9 -1
- data/README.md +25 -4
- data/keycloak-admin.gemspec +1 -0
- data/lib/keycloak-admin.rb +3 -0
- data/lib/keycloak-admin/client/user_client.rb +17 -0
- data/lib/keycloak-admin/configuration.rb +1 -1
- data/lib/keycloak-admin/representation/impersonation_redirection_representation.rb +16 -0
- data/lib/keycloak-admin/representation/impersonation_representation.rb +43 -0
- data/lib/keycloak-admin/version.rb +1 -1
- data/spec/client/user_client_spec.rb +25 -0
- data/spec/configuration_spec.rb +111 -0
- data/spec/representation/impersonation_representation_spec.rb +163 -0
- data/spec/spec_helper.rb +1 -0
- metadata +26 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0b8ec4ab66da0bc2e63c8aa0cf41107da8b7430
|
4
|
+
data.tar.gz: 21e5f3c5b983bf197607f280ff34a743811bc2fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f7ae98056acef279fac3365b9121dbca089a34a36076d1a31a62cb1a4b6af246c18899ea23418b8668fea59eb88a119b2e5fec9326bf7514a2150fdab560bc5
|
7
|
+
data.tar.gz: 3e44a7ddf4fe78650136b73c73ddeb982e7baf55866674b0c32aadf655423be042eee46722274bf93b80f6cd126924d803a9b8743137576b3156bfd083459883
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
keycloak-admin (0.
|
4
|
+
keycloak-admin (0.4)
|
5
|
+
http-cookie (~> 1.0, >= 1.0.3)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
8
9
|
specs:
|
9
10
|
byebug (9.1.0)
|
10
11
|
diff-lcs (1.3)
|
12
|
+
domain_name (0.5.20170404)
|
13
|
+
unf (>= 0.0.5, < 1.0.0)
|
14
|
+
http-cookie (1.0.3)
|
15
|
+
domain_name (~> 0.5)
|
11
16
|
rspec (3.7.0)
|
12
17
|
rspec-core (~> 3.7.0)
|
13
18
|
rspec-expectations (~> 3.7.0)
|
@@ -21,6 +26,9 @@ GEM
|
|
21
26
|
diff-lcs (>= 1.2.0, < 2.0)
|
22
27
|
rspec-support (~> 3.7.0)
|
23
28
|
rspec-support (3.7.0)
|
29
|
+
unf (0.1.4)
|
30
|
+
unf_ext
|
31
|
+
unf_ext (0.0.7.4)
|
24
32
|
|
25
33
|
PLATFORMS
|
26
34
|
ruby
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@ This gem *does not* require Rails.
|
|
12
12
|
For example, using `bundle`, add this line to your Gemfile.
|
13
13
|
|
14
14
|
```ruby
|
15
|
-
gem "keycloak-admin", "0.
|
15
|
+
gem "keycloak-admin", "0.4"
|
16
16
|
```
|
17
17
|
|
18
18
|
## Login
|
@@ -37,7 +37,8 @@ Using a service account to use the REST Admin API does not require to create a d
|
|
37
37
|
* In Keycloak
|
38
38
|
* Make your client `confidential`
|
39
39
|
* Check its toggle `Service Accounts Enabled`
|
40
|
-
*
|
40
|
+
* Disable both `Standard Flow Enabled` and `Implicit Flow Enabled `
|
41
|
+
* Enable `Direct Access Grants Enabled`
|
41
42
|
* After saving this client, open the `Service Account Roles` and add relevant `realm-management.` client's roles. For instance: `view-users` if you want to search for users using this gem.
|
42
43
|
* In this gem's configuration
|
43
44
|
* Set `use_service_account` to `true`
|
@@ -51,6 +52,7 @@ For instance, to configure this gem based on environment variables, write (and l
|
|
51
52
|
KeycloakAdmin.configure do |config|
|
52
53
|
config.use_service_account = false
|
53
54
|
config.server_url = ENV["KEYCLOAK_SERVER_URL"]
|
55
|
+
config.server_domain = ENV["KEYCLOAK_SERVER_DOMAIN"]
|
54
56
|
config.client_id = ENV["KEYCLOAK_ADMIN_CLIENT_ID"]
|
55
57
|
config.client_realm_name = ENV["KEYCLOAK_REALM_ID"]
|
56
58
|
config.username = ENV["KEYCLOAK_ADMIN_USER"]
|
@@ -66,7 +68,7 @@ All options have a default value. However, all of them can be changed in your in
|
|
66
68
|
|
67
69
|
| Option | Default Value | Type | Required? | Description | Example |
|
68
70
|
| ---- | ----- | ------ | ----- | ------ | ----- |
|
69
|
-
| `server_url` | `nil`| String | Required | The base url where your Keycloak server is located. This value can be retrieved in your Keycloak client configuration. | `auth
|
71
|
+
| `server_url` | `nil`| String | Required | The base url where your Keycloak server is located. This value can be retrieved in your Keycloak client configuration. | `server_domain` | `nil`| String | Required | Public domain that identify your authentication cookies. | `auth.service.io` |
|
70
72
|
| `client_realm_name` | `""`| String | Required | Name of the realm that contain the admin client. | `master` |
|
71
73
|
| `client_id` | `admin-cli`| String | Required | Client that should be used to access admin capabilities. | `api-cli` |
|
72
74
|
| `client_secret` | `nil`| String | Optional | If your client is `confidential`, this parameter must be specified. | `4e3c481c-f823-4a6a-b8a7-bf8c86e3eac3` |
|
@@ -84,6 +86,7 @@ exit
|
|
84
86
|
* Create a user
|
85
87
|
* Reset credentials
|
86
88
|
* Delete a user
|
89
|
+
* Impersonate a user
|
87
90
|
|
88
91
|
### Get an access token
|
89
92
|
|
@@ -126,7 +129,25 @@ KeycloakAdmin.realm("a_realm").users.create!(username, email, password, email_ve
|
|
126
129
|
```ruby
|
127
130
|
user_id = "95985b21-d884-4bbd-b852-cb8cd365afc2"
|
128
131
|
new_password = "coco"
|
129
|
-
KeycloakAdmin.realm("
|
132
|
+
KeycloakAdmin.realm("a_realm").users.update_password(user_id, new_password)
|
133
|
+
```
|
134
|
+
|
135
|
+
### Impersonate a password directly
|
136
|
+
|
137
|
+
Returns an instance of `KeycloakAdmin::ImpersonationRepresentation`.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
user_id = "95985b21-d884-4bbd-b852-cb8cd365afc2"
|
141
|
+
KeycloakAdmin.realm("a_realm").users.impersonate(user_id)
|
142
|
+
```
|
143
|
+
|
144
|
+
### Impersonate a password indirectly
|
145
|
+
|
146
|
+
To have enough information to execute an impersonation by yourself, `get_redirect_impersonation` returns an instance of `KeycloakAdmin::ImpersonationRedirectionRepresentation`.
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
user_id = "95985b21-d884-4bbd-b852-cb8cd365afc2"
|
150
|
+
KeycloakAdmin.realm("a_realm").users.get_redirect_impersonation(user_id)
|
130
151
|
```
|
131
152
|
|
132
153
|
## How to execute library tests
|
data/keycloak-admin.gemspec
CHANGED
@@ -15,6 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
|
18
|
+
spec.add_dependency "http-cookie", "~> 1.0", ">= 1.0.3"
|
18
19
|
spec.add_development_dependency "rspec", "3.7.0"
|
19
20
|
spec.add_development_dependency "byebug", "9.1.0"
|
20
21
|
end
|
data/lib/keycloak-admin.rb
CHANGED
@@ -8,6 +8,8 @@ require_relative "keycloak-admin/client/user_client"
|
|
8
8
|
require_relative "keycloak-admin/representation/camel_json"
|
9
9
|
require_relative "keycloak-admin/representation/representation"
|
10
10
|
require_relative "keycloak-admin/representation/token_representation"
|
11
|
+
require_relative "keycloak-admin/representation/impersonation_redirection_representation"
|
12
|
+
require_relative "keycloak-admin/representation/impersonation_representation"
|
11
13
|
require_relative "keycloak-admin/representation/credential_representation"
|
12
14
|
require_relative "keycloak-admin/representation/user_representation"
|
13
15
|
|
@@ -32,6 +34,7 @@ module KeycloakAdmin
|
|
32
34
|
def self.load_configuration
|
33
35
|
configure do |config|
|
34
36
|
config.server_url = nil
|
37
|
+
config.server_domain = nil
|
35
38
|
config.client_realm_name = ""
|
36
39
|
config.client_id = "admin-cli"
|
37
40
|
config.logger = ::Logger.new(STDOUT)
|
@@ -43,6 +43,18 @@ module KeycloakAdmin
|
|
43
43
|
user_id
|
44
44
|
end
|
45
45
|
|
46
|
+
def impersonate(user_id)
|
47
|
+
impersonation = get_redirect_impersonation(user_id)
|
48
|
+
response = execute_http do
|
49
|
+
RestClient.post(impersonation.impersonation_url, impersonation.body.to_json, impersonation.headers)
|
50
|
+
end
|
51
|
+
ImpersonationRepresentation.from_response(response, @configuration.server_domain)
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_redirect_impersonation(user_id)
|
55
|
+
ImpersonationRedirectionRepresentation.from_url(impersonation_url(user_id), headers)
|
56
|
+
end
|
57
|
+
|
46
58
|
def users_url(id=nil)
|
47
59
|
if id
|
48
60
|
"#{@realm_client.realm_admin_url}/users/#{id}"
|
@@ -56,6 +68,11 @@ module KeycloakAdmin
|
|
56
68
|
"#{users_url(user_id)}/reset-password"
|
57
69
|
end
|
58
70
|
|
71
|
+
def impersonation_url(user_id)
|
72
|
+
raise ArgumentError.new("user_id must be defined") if user_id.nil?
|
73
|
+
"#{users_url(user_id)}/impersonation"
|
74
|
+
end
|
75
|
+
|
59
76
|
private
|
60
77
|
|
61
78
|
def build(username, email, password, email_verified)
|
@@ -2,7 +2,7 @@ require "base64"
|
|
2
2
|
|
3
3
|
module KeycloakAdmin
|
4
4
|
class Configuration
|
5
|
-
attr_accessor :server_url, :client_id, :client_secret, :client_realm_name, :use_service_account, :username, :password, :logger
|
5
|
+
attr_accessor :server_url, :server_domain, :client_id, :client_secret, :client_realm_name, :use_service_account, :username, :password, :logger
|
6
6
|
|
7
7
|
def body_for_token_retrieval
|
8
8
|
if use_service_account
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module KeycloakAdmin
|
2
|
+
class ImpersonationRedirectionRepresentation < Representation
|
3
|
+
attr_reader :headers, :impersonation_url, :http_method, :body
|
4
|
+
|
5
|
+
def initialize(http_method, body, impersonation_url, headers)
|
6
|
+
@http_method = http_method
|
7
|
+
@body = body
|
8
|
+
@impersonation_url = impersonation_url
|
9
|
+
@headers = headers
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from_url(url, headers)
|
13
|
+
new(:post, {}, url, headers)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "http-cookie"
|
2
|
+
|
3
|
+
module KeycloakAdmin
|
4
|
+
class ImpersonationRepresentation < Representation
|
5
|
+
attr_accessor :set_cookie_strings,
|
6
|
+
:set_cookies,
|
7
|
+
:same_realm,
|
8
|
+
:redirect,
|
9
|
+
:domain
|
10
|
+
|
11
|
+
def self.from_response(response, origin)
|
12
|
+
body = JSON.parse(response.body)
|
13
|
+
representation = new
|
14
|
+
representation.set_cookie_strings = response.headers[:set_cookie]
|
15
|
+
representation.set_cookies = representation.set_cookie_strings.map { |set_cookie| parse_set_cookie_string(set_cookie, origin) }
|
16
|
+
representation.same_realm = body["sameRealm"]
|
17
|
+
representation.redirect = body["redirect"]
|
18
|
+
representation.domain = origin
|
19
|
+
representation
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.parse_set_cookie_string(set_cookie_string, origin)
|
23
|
+
HTTP::Cookie.parse(set_cookie_string, origin).first
|
24
|
+
end
|
25
|
+
|
26
|
+
def cookies_to_rails_hash
|
27
|
+
@set_cookies.map do |cookie|
|
28
|
+
rails_cookie = {
|
29
|
+
name: cookie.name,
|
30
|
+
value: cookie.value,
|
31
|
+
httponly: cookie.httponly,
|
32
|
+
expires: cookie.expires,
|
33
|
+
path: cookie.path,
|
34
|
+
domain: cookie.domain
|
35
|
+
}
|
36
|
+
|
37
|
+
rails_cookie[:max_age] = cookie.max_age if cookie.max_age
|
38
|
+
rails_cookie[:secure] = cookie.secure if cookie.secure
|
39
|
+
rails_cookie
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -71,4 +71,29 @@ RSpec.describe KeycloakAdmin::TokenClient do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
74
|
+
|
75
|
+
describe "#impersonation_url" do
|
76
|
+
let(:realm_name) { "valid-realm" }
|
77
|
+
let(:user_id) { nil }
|
78
|
+
|
79
|
+
before(:each) do
|
80
|
+
@client = KeycloakAdmin.realm(realm_name).users
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when user_id is not defined" do
|
84
|
+
let(:user_id) { nil }
|
85
|
+
it "raises an error" do
|
86
|
+
expect {
|
87
|
+
@client.impersonation_url(user_id)
|
88
|
+
}.to raise_error(ArgumentError)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "when user_id is defined" do
|
93
|
+
let(:user_id) { 42 }
|
94
|
+
it "return a proper url" do
|
95
|
+
expect(@client.impersonation_url(user_id)).to eq "http://auth.service.io/auth/admin/realms/valid-realm/users/42/impersonation"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
74
99
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
RSpec.describe KeycloakAdmin::RealmClient do
|
2
|
+
|
3
|
+
let(:client_id) { "admin-cli" }
|
4
|
+
let(:client_secret) { "aaaaaaaa" }
|
5
|
+
let(:client_realm_name) { "master2" }
|
6
|
+
let(:use_service_account) { true }
|
7
|
+
let(:username) { "a" }
|
8
|
+
let(:password) { "b" }
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
@configuration = KeycloakAdmin::Configuration.new
|
12
|
+
@configuration.server_url = "http://auth.service.io/auth"
|
13
|
+
@configuration.server_domain = "auth.service.io"
|
14
|
+
@configuration.client_id = client_id
|
15
|
+
@configuration.client_secret = client_secret
|
16
|
+
@configuration.client_realm_name = client_realm_name
|
17
|
+
@configuration.use_service_account = use_service_account
|
18
|
+
@configuration.username = username
|
19
|
+
@configuration.password = password
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#headers_for_token_retrieval" do
|
23
|
+
before(:each) do
|
24
|
+
@headers = @configuration.headers_for_token_retrieval
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when use_service_account is false" do
|
28
|
+
let(:use_service_account) { false }
|
29
|
+
it "returns an empty hash" do
|
30
|
+
expect(@headers).to be_empty
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when use_service_account is true" do
|
35
|
+
let(:use_service_account) { true }
|
36
|
+
it "returns a single element" do
|
37
|
+
expect(@headers.size).to eq 1
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns the Authorization Key" do
|
41
|
+
expect(@headers.has_key?(:Authorization)).to be true
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns a Basic Authorization Key" do
|
45
|
+
expect(@headers[:Authorization]).to start_with "Basic"
|
46
|
+
end
|
47
|
+
|
48
|
+
context "client_id='a' and client_secret='b'" do
|
49
|
+
let(:client_id) { "a" }
|
50
|
+
let(:client_secret) { "b" }
|
51
|
+
|
52
|
+
it "returns a Basic Authorization = 'Basic YTpi'" do
|
53
|
+
expect(@headers[:Authorization]).to eq "Basic YTpi"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "client_id='365e3c66-fd0f-11e7-8be5-0ed5f89f718b' and client_secret='411e6f9a-fd0f-11e7-8be5-0ed5f89f718b'" do
|
58
|
+
let(:client_id) { "365e3c66-fd0f-11e7-8be5-0ed5f89f718b" }
|
59
|
+
let(:client_secret) { "411e6f9a-fd0f-11e7-8be5-0ed5f89f718b" }
|
60
|
+
|
61
|
+
it "returns a Basic Authorization = 'Basic MzY1ZTNjNjYtZmQwZi0xMWU3LThiZTUtMGVkNWY4OWY3MThiOjQxMWU2ZjlhLWZkMGYtMTFlNy04YmU1LTBlZDVmODlmNzE4Yg=='" do
|
62
|
+
expect(@headers[:Authorization]).to eq "Basic MzY1ZTNjNjYtZmQwZi0xMWU3LThiZTUtMGVkNWY4OWY3MThiOjQxMWU2ZjlhLWZkMGYtMTFlNy04YmU1LTBlZDVmODlmNzE4Yg=="
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#body_for_token_retrieval" do
|
70
|
+
before(:each) do
|
71
|
+
@body = @configuration.body_for_token_retrieval
|
72
|
+
end
|
73
|
+
context "when use_service_account is false" do
|
74
|
+
let(:use_service_account) { false }
|
75
|
+
it "returns a hash of 5 elements" do
|
76
|
+
expect(@body.size).to eq 5
|
77
|
+
end
|
78
|
+
|
79
|
+
it "returns a hash containing the username" do
|
80
|
+
expect(@body[:username]).to eq username
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns a hash containing the password" do
|
84
|
+
expect(@body[:password]).to eq password
|
85
|
+
end
|
86
|
+
|
87
|
+
it "returns a hash containing the grant_type 'password'" do
|
88
|
+
expect(@body[:grant_type]).to eq "password"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "returns a hash containing the client_id" do
|
92
|
+
expect(@body[:client_id]).to eq client_id
|
93
|
+
end
|
94
|
+
|
95
|
+
it "returns a hash containing the client_secret" do
|
96
|
+
expect(@body[:client_secret]).to eq client_secret
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when use_service_account is true" do
|
101
|
+
let(:use_service_account) { true }
|
102
|
+
it "returns a hash of 1 element" do
|
103
|
+
expect(@body.size).to eq 1
|
104
|
+
end
|
105
|
+
|
106
|
+
it "returns a hash containing the grant_type" do
|
107
|
+
expect(@body[:grant_type]).to eq "client_credentials"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
RSpec.describe KeycloakAdmin::ImpersonationRepresentation do
|
2
|
+
describe "#parse_set_cookie_string" do
|
3
|
+
|
4
|
+
let(:origin) { "http://auth.service.io" }
|
5
|
+
let(:set_cookie_string) { "" }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@cookie = KeycloakAdmin::ImpersonationRepresentation.parse_set_cookie_string(set_cookie_string, origin)
|
9
|
+
end
|
10
|
+
|
11
|
+
shared_context "common properties are read properly" do
|
12
|
+
it "parses its domain property" do
|
13
|
+
expect(@cookie.domain).to eq "auth.service.io"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "parses its for_domain property" do
|
17
|
+
expect(@cookie.for_domain).to be false
|
18
|
+
end
|
19
|
+
|
20
|
+
it "parses its Path property" do
|
21
|
+
expect(@cookie.path).to eq "/auth/realms/a-realm"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "parses its Secure property" do
|
25
|
+
expect(@cookie.secure).to be false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when result is an expiring empty KEYCLOAK_IDENTITY" do
|
30
|
+
let(:set_cookie_string) { "KEYCLOAK_IDENTITY=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/a-realm; HttpOnly" }
|
31
|
+
|
32
|
+
include_examples "common properties are read properly"
|
33
|
+
|
34
|
+
it "parses its name property" do
|
35
|
+
expect(@cookie.name).to eq "KEYCLOAK_IDENTITY"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "parses its value property" do
|
39
|
+
expect(@cookie.value).to eq ""
|
40
|
+
end
|
41
|
+
|
42
|
+
it "parses its Expires property" do
|
43
|
+
expect(@cookie.expires).to be <= Time.now
|
44
|
+
end
|
45
|
+
|
46
|
+
it "parses its Max-Age property" do
|
47
|
+
expect(@cookie.max_age).to eq 0
|
48
|
+
end
|
49
|
+
|
50
|
+
it "parses its HttpOnly property" do
|
51
|
+
expect(@cookie.httponly).to be true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
context "when result is an expiring empty KEYCLOAK_SESSION" do
|
57
|
+
let(:set_cookie_string) { "KEYCLOAK_SESSION=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/a-realm" }
|
58
|
+
|
59
|
+
include_examples "common properties are read properly"
|
60
|
+
|
61
|
+
it "parses its name property" do
|
62
|
+
expect(@cookie.name).to eq "KEYCLOAK_SESSION"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "parses its value property" do
|
66
|
+
expect(@cookie.value).to eq ""
|
67
|
+
end
|
68
|
+
|
69
|
+
it "parses its Expires property" do
|
70
|
+
expect(@cookie.expires).to be <= Time.now
|
71
|
+
end
|
72
|
+
|
73
|
+
it "parses its Max-Age property" do
|
74
|
+
expect(@cookie.max_age).to eq 0
|
75
|
+
end
|
76
|
+
|
77
|
+
it "parses its HttpOnly property" do
|
78
|
+
expect(@cookie.httponly).to be false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
context "when result is an expiring empty KEYCLOAK_REMEMBER_ME" do
|
84
|
+
let(:set_cookie_string) { "KEYCLOAK_REMEMBER_ME=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/a-realm; HttpOnly" }
|
85
|
+
|
86
|
+
include_examples "common properties are read properly"
|
87
|
+
|
88
|
+
it "parses its name property" do
|
89
|
+
expect(@cookie.name).to eq "KEYCLOAK_REMEMBER_ME"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "parses its value property" do
|
93
|
+
expect(@cookie.value).to eq ""
|
94
|
+
end
|
95
|
+
|
96
|
+
it "parses its Expires property" do
|
97
|
+
expect(@cookie.expires).to be <= Time.now
|
98
|
+
end
|
99
|
+
|
100
|
+
it "parses its Max-Age property" do
|
101
|
+
expect(@cookie.max_age).to eq 0
|
102
|
+
end
|
103
|
+
|
104
|
+
it "parses its HttpOnly property" do
|
105
|
+
expect(@cookie.httponly).to be true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "when result is a new KEYCLOAK_IDENTITY" do
|
110
|
+
let(:set_cookie_string) { "KEYCLOAK_IDENTITY=eyJhbGciOiJIUzI1NiIsImtpZCIgOiAiMDQyMTcwMWItY2I2Ny00YzQ4LWIzZWYtMDBlMDhhMmE4MjNjIn0.eyJqdGkiOiI5ZTEyODc3MC1mN2U1LTQ0OWYtYWMzYi03OTAzN2Q5NDBhOTMiLCJleHAiOjE1MTY2ODE2ODIsIm5iZiI6MCwiaWF0IjoxNTE2NjQ1NjgyLCJpc3MiOiJodHRwOi8vYXV0aDo4MDgwL2F1dGgvcmVhbG1zL2NvbW11dHkiLCJzdWIiOiI0NGM1MzdmMi1iMzBiLTRlZTctYjI4Ni1lZTY2NjI2NDcwYWMiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI3ZDI5NTJlZS0xMjllLTRmOGQtYmFjNy1jMWE0YWUxNGRjY2QiLCJyZXNvdXJjZV9hY2Nlc3MiOnt9LCJzdGF0ZV9jaGVja2VyIjoiUEdXZVdXc3hMRmN3WG1QelFmMGxBQTJrN1V3Skg3UUlHU0lrN3hmWUFEbyJ9.Hw9EM1rZLXkUfE97tfS8jw8MFogfMoGpT34yoMupK3E; Version=1; Path=/auth/realms/a-realm; HttpOnly" }
|
111
|
+
|
112
|
+
include_examples "common properties are read properly"
|
113
|
+
|
114
|
+
it "parses its name property" do
|
115
|
+
expect(@cookie.name).to eq "KEYCLOAK_IDENTITY"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "parses its value property" do
|
119
|
+
expect(@cookie.value).to eq "eyJhbGciOiJIUzI1NiIsImtpZCIgOiAiMDQyMTcwMWItY2I2Ny00YzQ4LWIzZWYtMDBlMDhhMmE4MjNjIn0.eyJqdGkiOiI5ZTEyODc3MC1mN2U1LTQ0OWYtYWMzYi03OTAzN2Q5NDBhOTMiLCJleHAiOjE1MTY2ODE2ODIsIm5iZiI6MCwiaWF0IjoxNTE2NjQ1NjgyLCJpc3MiOiJodHRwOi8vYXV0aDo4MDgwL2F1dGgvcmVhbG1zL2NvbW11dHkiLCJzdWIiOiI0NGM1MzdmMi1iMzBiLTRlZTctYjI4Ni1lZTY2NjI2NDcwYWMiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI3ZDI5NTJlZS0xMjllLTRmOGQtYmFjNy1jMWE0YWUxNGRjY2QiLCJyZXNvdXJjZV9hY2Nlc3MiOnt9LCJzdGF0ZV9jaGVja2VyIjoiUEdXZVdXc3hMRmN3WG1QelFmMGxBQTJrN1V3Skg3UUlHU0lrN3hmWUFEbyJ9.Hw9EM1rZLXkUfE97tfS8jw8MFogfMoGpT34yoMupK3E"
|
120
|
+
end
|
121
|
+
|
122
|
+
it "parses its Expires property" do
|
123
|
+
expect(@cookie.expires).to be_nil
|
124
|
+
end
|
125
|
+
|
126
|
+
it "parses its Max-Age property" do
|
127
|
+
expect(@cookie.max_age).to be nil
|
128
|
+
end
|
129
|
+
|
130
|
+
it "parses its HttpOnly property" do
|
131
|
+
expect(@cookie.httponly).to be true
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when result is a new KEYCLOAK_SESSION" do
|
136
|
+
let(:set_cookie_string) { "KEYCLOAK_SESSION=commuty/44c537f2-b30b-4ee7-b286-ee66626470ac/cd79f3c2-7cee-4c4e-980b-43293aaaff88; Version=1; Expires=Tue, 23-Jan-2018 23:56:32 GMT; Max-Age=36000; Path=/auth/realms/a-realm" }
|
137
|
+
|
138
|
+
include_examples "common properties are read properly"
|
139
|
+
|
140
|
+
it "parses its name property" do
|
141
|
+
expect(@cookie.name).to eq "KEYCLOAK_SESSION"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "parses its value property" do
|
145
|
+
expect(@cookie.value).to eq "commuty/44c537f2-b30b-4ee7-b286-ee66626470ac/cd79f3c2-7cee-4c4e-980b-43293aaaff88"
|
146
|
+
end
|
147
|
+
|
148
|
+
it "parses its Expires property" do
|
149
|
+
expect(@cookie.expires).to_not be_nil
|
150
|
+
end
|
151
|
+
|
152
|
+
it "parses its Max-Age property" do
|
153
|
+
expect(@cookie.max_age).to be 36000
|
154
|
+
end
|
155
|
+
|
156
|
+
it "parses its HttpOnly property" do
|
157
|
+
expect(@cookie.httponly).to be false
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -5,6 +5,7 @@ require "byebug"
|
|
5
5
|
def configure
|
6
6
|
KeycloakAdmin.configure do |config|
|
7
7
|
config.server_url = "http://auth.service.io/auth"
|
8
|
+
config.server_domain = "auth.service.io"
|
8
9
|
config.client_id = "admin-cli"
|
9
10
|
config.client_secret = "aaaaaaaa"
|
10
11
|
config.client_realm_name = "master2"
|
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keycloak-admin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.4'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorent Lempereur
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: http-cookie
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.0.3
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.3
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: rspec
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -61,6 +81,8 @@ files:
|
|
61
81
|
- lib/keycloak-admin/configuration.rb
|
62
82
|
- lib/keycloak-admin/representation/camel_json.rb
|
63
83
|
- lib/keycloak-admin/representation/credential_representation.rb
|
84
|
+
- lib/keycloak-admin/representation/impersonation_redirection_representation.rb
|
85
|
+
- lib/keycloak-admin/representation/impersonation_representation.rb
|
64
86
|
- lib/keycloak-admin/representation/representation.rb
|
65
87
|
- lib/keycloak-admin/representation/token_representation.rb
|
66
88
|
- lib/keycloak-admin/representation/user_representation.rb
|
@@ -68,6 +90,8 @@ files:
|
|
68
90
|
- spec/client/realm_client_spec.rb
|
69
91
|
- spec/client/token_client_spec.rb
|
70
92
|
- spec/client/user_client_spec.rb
|
93
|
+
- spec/configuration_spec.rb
|
94
|
+
- spec/representation/impersonation_representation_spec.rb
|
71
95
|
- spec/spec_helper.rb
|
72
96
|
homepage: https://github.com/looorent/keycloak-admin-ruby
|
73
97
|
licenses:
|