keycloak-admin 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 107fe1a9772c1ca9f9014e1e089d5eb4a9c66a6a
4
+ data.tar.gz: f4c5918e8e3f3654bb6f8e8f63d0480b2f7b5d98
5
+ SHA512:
6
+ metadata.gz: c5be1ffcad5a514578de150dae7a6b55d1ca7af1466fe3f45ec007c17da164ea877b190357fa50227f1e68ac3861a3daea793389cd2044b31ef9c5c0f1e30aa9
7
+ data.tar.gz: 40932b69af9e0ba619a3d267cd50bbf0146f4a5573aee005e9d362c57e2536f39c4ba77320cbb0b0323cb37b9a07e1a347a05919da040cead84022368f1daf4c
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ test/dummy/db/*.sqlite3
5
+ test/dummy/db/*.sqlite3-journal
6
+ test/dummy/log/*.log
7
+ test/dummy/tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Dockerfile ADDED
@@ -0,0 +1,11 @@
1
+ FROM ruby:2.3
2
+ RUN mkdir -p /usr/src/app/lib/keycloak-admin
3
+ WORKDIR /usr/src/app
4
+
5
+ COPY Gemfile /usr/src/app/
6
+ COPY Gemfile.lock /usr/src/app/
7
+ COPY keycloak-admin.gemspec /usr/src/app/
8
+ COPY lib/keycloak-admin/version.rb /usr/src/app/lib/keycloak-admin/
9
+ RUN bundle install
10
+ COPY . /usr/src/app
11
+ RUN bundle install
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,133 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ keycloak-admin (0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ actioncable (5.1.4)
10
+ actionpack (= 5.1.4)
11
+ nio4r (~> 2.0)
12
+ websocket-driver (~> 0.6.1)
13
+ actionmailer (5.1.4)
14
+ actionpack (= 5.1.4)
15
+ actionview (= 5.1.4)
16
+ activejob (= 5.1.4)
17
+ mail (~> 2.5, >= 2.5.4)
18
+ rails-dom-testing (~> 2.0)
19
+ actionpack (5.1.4)
20
+ actionview (= 5.1.4)
21
+ activesupport (= 5.1.4)
22
+ rack (~> 2.0)
23
+ rack-test (>= 0.6.3)
24
+ rails-dom-testing (~> 2.0)
25
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
26
+ actionview (5.1.4)
27
+ activesupport (= 5.1.4)
28
+ builder (~> 3.1)
29
+ erubi (~> 1.4)
30
+ rails-dom-testing (~> 2.0)
31
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
32
+ activejob (5.1.4)
33
+ activesupport (= 5.1.4)
34
+ globalid (>= 0.3.6)
35
+ activemodel (5.1.4)
36
+ activesupport (= 5.1.4)
37
+ activerecord (5.1.4)
38
+ activemodel (= 5.1.4)
39
+ activesupport (= 5.1.4)
40
+ arel (~> 8.0)
41
+ activesupport (5.1.4)
42
+ concurrent-ruby (~> 1.0, >= 1.0.2)
43
+ i18n (~> 0.7)
44
+ minitest (~> 5.1)
45
+ tzinfo (~> 1.1)
46
+ arel (8.0.0)
47
+ builder (3.2.3)
48
+ byebug (9.1.0)
49
+ concurrent-ruby (1.0.5)
50
+ crass (1.0.3)
51
+ diff-lcs (1.3)
52
+ erubi (1.7.0)
53
+ globalid (0.4.1)
54
+ activesupport (>= 4.2.0)
55
+ i18n (0.9.1)
56
+ concurrent-ruby (~> 1.0)
57
+ loofah (2.1.1)
58
+ crass (~> 1.0.2)
59
+ nokogiri (>= 1.5.9)
60
+ mail (2.7.0)
61
+ mini_mime (>= 0.1.1)
62
+ method_source (0.9.0)
63
+ mini_mime (1.0.0)
64
+ mini_portile2 (2.3.0)
65
+ minitest (5.11.1)
66
+ nio4r (2.2.0)
67
+ nokogiri (1.8.1)
68
+ mini_portile2 (~> 2.3.0)
69
+ rack (2.0.3)
70
+ rack-test (0.8.2)
71
+ rack (>= 1.0, < 3)
72
+ rails (5.1.4)
73
+ actioncable (= 5.1.4)
74
+ actionmailer (= 5.1.4)
75
+ actionpack (= 5.1.4)
76
+ actionview (= 5.1.4)
77
+ activejob (= 5.1.4)
78
+ activemodel (= 5.1.4)
79
+ activerecord (= 5.1.4)
80
+ activesupport (= 5.1.4)
81
+ bundler (>= 1.3.0)
82
+ railties (= 5.1.4)
83
+ sprockets-rails (>= 2.0.0)
84
+ rails-dom-testing (2.0.3)
85
+ activesupport (>= 4.2.0)
86
+ nokogiri (>= 1.6)
87
+ rails-html-sanitizer (1.0.3)
88
+ loofah (~> 2.0)
89
+ railties (5.1.4)
90
+ actionpack (= 5.1.4)
91
+ activesupport (= 5.1.4)
92
+ method_source
93
+ rake (>= 0.8.7)
94
+ thor (>= 0.18.1, < 2.0)
95
+ rake (12.3.0)
96
+ rspec (3.7.0)
97
+ rspec-core (~> 3.7.0)
98
+ rspec-expectations (~> 3.7.0)
99
+ rspec-mocks (~> 3.7.0)
100
+ rspec-core (3.7.1)
101
+ rspec-support (~> 3.7.0)
102
+ rspec-expectations (3.7.0)
103
+ diff-lcs (>= 1.2.0, < 2.0)
104
+ rspec-support (~> 3.7.0)
105
+ rspec-mocks (3.7.0)
106
+ diff-lcs (>= 1.2.0, < 2.0)
107
+ rspec-support (~> 3.7.0)
108
+ rspec-support (3.7.0)
109
+ sprockets (3.7.1)
110
+ concurrent-ruby (~> 1.0)
111
+ rack (> 1, < 3)
112
+ sprockets-rails (3.2.1)
113
+ actionpack (>= 4.0)
114
+ activesupport (>= 4.0)
115
+ sprockets (>= 3.0.0)
116
+ thor (0.20.0)
117
+ thread_safe (0.3.6)
118
+ tzinfo (1.2.4)
119
+ thread_safe (~> 0.1)
120
+ websocket-driver (0.6.5)
121
+ websocket-extensions (>= 0.1.0)
122
+ websocket-extensions (0.1.3)
123
+
124
+ PLATFORMS
125
+ ruby
126
+
127
+ DEPENDENCIES
128
+ byebug (= 9.1.0)
129
+ keycloak-admin!
130
+ rspec (= 3.7.0)
131
+
132
+ BUNDLED WITH
133
+ 1.16.1
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2018
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,107 @@
1
+
2
+ # Keycloak Admin Ruby
3
+
4
+ Ruby client that acts as a client for the Keycloak REST API.
5
+ This gem basically acts as an url builder using `http-client` to get responses and serialize them into _representation_ objects.
6
+
7
+ _Warning: This beta gem is currently used for personal used. Most Keycloak Admin features are not implemented yet._
8
+
9
+ ## Install
10
+
11
+ This gem *does not* require Rails.
12
+
13
+ ```ruby
14
+ gem "keycloak-admin"
15
+ ```
16
+
17
+ ## Configuration
18
+
19
+ To configure this gem, call `KeycloakAdmin.configure`.
20
+ For instance, to configure this gem based on environment variables, write (and load if required) a `keycloak_admin.rb`:
21
+ ```ruby
22
+ KeycloakAdmin.configure do |config|
23
+ config.server_url = ENV["KEYCLOAK_SERVER_URL"]
24
+ config.client_id = ENV["KEYCLOAK_ADMIN_CLIENT_ID"]
25
+ config.user_realm_name = ENV["KEYCLOAK_REALM_ID"]
26
+ config.username = ENV["KEYCLOAK_ADMIN_USER"]
27
+ config.password = ENV["KEYCLOAK_ADMIN_PASSWORD"]
28
+ config.logger = Rails.logger
29
+ end
30
+ ```
31
+ This example is autoloaded in a Rails environment.
32
+
33
+ ### Overall configuration options
34
+
35
+ All options have a default value. However, all of them can be changed in your initializer file.
36
+
37
+ | Option | Default Value | Type | Required? | Description | Example |
38
+ | ---- | ----- | ------ | ----- | ------ | ----- |
39
+ | `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:8080/auth` |
40
+ | `user_realm_name` | `""`| String | Required | Name of the realm that contain the admin client and user. | `master` |
41
+ | `client_id` | `admin-cli`| String | Required | Client that should be used to access admin capabilities. | `api-cli` |
42
+ | `username` | `nil`| String | Required | Username that access to the Admin REST API | `mummy` |
43
+ | `password` | `nil`| String | Required | Clear password that access to the Admin REST API | `bobby` |
44
+ | `logger` | `Logger.new(STDOUT)`| Logger | Optional | The logger used by `keycloak-admin` | `Rails.logger` | 
45
+
46
+
47
+ ## Use Case
48
+ exit
49
+ ### Supported features
50
+
51
+ * Get an access token
52
+ * Create a user
53
+ * Reset credentials
54
+ * Delete a user
55
+
56
+ ### Get an access token
57
+
58
+ Returns an instance of `KeycloakAdmin::TokenRepresentation`.
59
+
60
+ ```ruby
61
+ KeycloakAdmin.realm("a_realm").token.get
62
+ ```
63
+
64
+ ### Search for users
65
+
66
+ Returns an array of `KeycloakAdmin::UserRepresentation`.
67
+
68
+ ```ruby
69
+ KeycloakAdmin.realm("a_realm").users.search("a_username_or_an_email")
70
+ ```
71
+
72
+ ### Save a user
73
+
74
+ Returns the provided `user`, which must be of type `KeycloakAdmin::UserRepresentation`.
75
+
76
+ ```ruby
77
+ KeycloakAdmin.realm("a_realm").users.save(user)
78
+ ```
79
+
80
+ ### Create and save a user with password
81
+
82
+ Returns the created user of type `KeycloakAdmin::UserRepresentation`.
83
+
84
+ ```ruby
85
+ username = "pioupioux"
86
+ email = "pioupioux@email.com"
87
+ password = "acme0"
88
+ email_verified = true
89
+ KeycloakAdmin.realm("a_realm").users.create!(username, email, password, email_verified)
90
+ ```
91
+
92
+ ### Reset a password
93
+
94
+ ```ruby
95
+ user_id = "95985b21-d884-4bbd-b852-cb8cd365afc2"
96
+ new_password = "coco"
97
+ KeycloakAdmin.realm("commuty").users.update_password(user_id, new_password)
98
+ ```
99
+
100
+ ## How to execute library tests
101
+
102
+ From the `keycloak-admin-api` directory:
103
+
104
+ ```
105
+ $ docker build . -t keycloak-admin:test
106
+ $ docker run -v `pwd`:/usr/src/app/ keycloak-admin:test bundle exec rspec spec
107
+ ```
@@ -0,0 +1,20 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "keycloak-admin/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "keycloak-admin"
7
+ spec.version = KeycloakAdmin::VERSION
8
+ spec.authors = ["Lorent Lempereur"]
9
+ spec.email = ["lorent.lempereur.dev@gmail.com"]
10
+ spec.homepage = "https://github.com/looorent/keycloak-admin-ruby"
11
+ spec.summary = "Keycloak Admin REST API client written in Ruby"
12
+ spec.description = "Keycloak Admin REST API client written in Ruby"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.add_development_dependency "rspec", "3.7.0"
19
+ spec.add_development_dependency "byebug", "9.1.0"
20
+ end
@@ -0,0 +1,30 @@
1
+ module KeycloakAdmin
2
+ class Client
3
+
4
+ def initialize(configuration)
5
+ @configuration = configuration
6
+ end
7
+
8
+ def server_url
9
+ @configuration.server_url
10
+ end
11
+
12
+ def token
13
+ @token ||= KeycloakAdmin.realm(@configuration.user_realm_name).token.get
14
+ end
15
+
16
+ def headers
17
+ {
18
+ Authorization: "Bearer #{token.access_token}",
19
+ content_type: :json,
20
+ accept: :json
21
+ }
22
+ end
23
+
24
+ private
25
+
26
+ def error(response)
27
+ raise "Keycloak: The request failed with response code #{response.code} and message: #{response.body}"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,36 @@
1
+ module KeycloakAdmin
2
+ class RealmClient < Client
3
+ def initialize(configuration, realm_name=nil)
4
+ super(configuration)
5
+ @realm_name = realm_name
6
+ end
7
+
8
+ def realm_url
9
+ if @realm_name
10
+ "#{server_url}/realms/#{@realm_name}"
11
+ else
12
+ "#{server_url}/realms"
13
+ end
14
+ end
15
+
16
+ def realm_admin_url
17
+ if @realm_name
18
+ "#{server_url}/admin/realms/#{@realm_name}"
19
+ else
20
+ "#{server_url}/admin/realms"
21
+ end
22
+ end
23
+
24
+ def token
25
+ TokenClient.new(@configuration, self)
26
+ end
27
+
28
+ def users
29
+ UserClient.new(@configuration, self)
30
+ end
31
+
32
+ def name_defined?
33
+ !@realm_name.nil?
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ module KeycloakAdmin
2
+ class TokenClient < Client
3
+ def initialize(configuration, realm_client)
4
+ super(configuration)
5
+ raise ArgumentError.new("realm must be defined") unless realm_client.name_defined?
6
+ @realm_client = realm_client
7
+ end
8
+
9
+ def token_url
10
+ "#{realm_url}/protocol/openid-connect/token"
11
+ end
12
+
13
+ def realm_url
14
+ @realm_client.realm_url
15
+ end
16
+
17
+ def get
18
+ response = RestClient.post(token_url,
19
+ username: @configuration.username,
20
+ password: @configuration.password,
21
+ grant_type: "password",
22
+ client_id: @configuration.client_id
23
+ )
24
+ if response.code == 200
25
+ TokenRepresentation.from_json(response.body)
26
+ else
27
+ error(response)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,75 @@
1
+ module KeycloakAdmin
2
+ class UserClient < Client
3
+ def initialize(configuration, realm_client)
4
+ super(configuration)
5
+ raise ArgumentError.new("realm must be defined") unless realm_client.name_defined?
6
+ @realm_client = realm_client
7
+ end
8
+
9
+ def create!(username, email, password, email_verified)
10
+ user = save(build(username, email, password, email_verified))
11
+ search(user.email)&.first
12
+ end
13
+
14
+ def save(user_representation)
15
+ response = RestClient.post(users_url, user_representation.to_json, headers)
16
+ if response.code == 201
17
+ user_representation
18
+ else
19
+ error(response)
20
+ end
21
+ end
22
+
23
+ def search(query)
24
+ response = RestClient.get(users_url, headers.merge({params: { search: query }}))
25
+ if response.code == 200
26
+ JSON.parse(response).map { |user_as_hash| UserRepresentation.from_hash(user_as_hash) }
27
+ else
28
+ error(response)
29
+ end
30
+ end
31
+
32
+ def delete(user_id)
33
+ response = RestClient.delete(users_url(user_id), headers)
34
+ response.code == 204 || error(response)
35
+ end
36
+
37
+ def update_password(user_id, new_password)
38
+ response = RestClient.put(reset_password_url(user_id), {
39
+ type: "password",
40
+ value: new_password,
41
+ temporary: false
42
+ }.to_json, headers)
43
+ if response.code == 204
44
+ user_id
45
+ else
46
+ error(response)
47
+ end
48
+ end
49
+
50
+ def users_url(id=nil)
51
+ if id
52
+ "#{@realm_client.realm_admin_url}/users/#{id}"
53
+ else
54
+ "#{@realm_client.realm_admin_url}/users"
55
+ end
56
+ end
57
+
58
+ def reset_password_url(user_id)
59
+ raise ArgumentError.new("user_id must be defined") if user_id.nil?
60
+ "#{users_url(user_id)}/reset-password"
61
+ end
62
+
63
+ private
64
+
65
+ def build(username, email, password, email_verified)
66
+ user = UserRepresentation.new
67
+ user.email = email
68
+ user.username = username
69
+ user.email_verified = email_verified
70
+ user.enabled = true
71
+ user.add_credential(CredentialRepresentation.from_password(password))
72
+ user
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,5 @@
1
+ module KeycloakAdmin
2
+ class Configuration
3
+ attr_accessor :server_url, :client_id, :user_realm_name, :username, :password, :logger
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module KeycloakAdmin
2
+ module CamelJson
3
+
4
+ def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
5
+ if first_letter_in_uppercase
6
+ lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
7
+ else
8
+ lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,39 @@
1
+ module KeycloakAdmin
2
+ class CredentialRepresentation < Representation
3
+ attr_accessor :type,
4
+ :device,
5
+ :value,
6
+ :hashedSaltedValue,
7
+ :salt,
8
+ :hashIterations,
9
+ :counter,
10
+ :algorithm,
11
+ :digits,
12
+ :period,
13
+ :created_date,
14
+ :config,
15
+ :temporary
16
+
17
+ def self.from_password(password, temporary=false)
18
+ credential = new
19
+ credential.value = password
20
+ credential.type = "password"
21
+ credential.temporary = temporary
22
+ credential
23
+ end
24
+
25
+ def self.from_json(json)
26
+ attributes = JSON.parse(json)
27
+ from_hash(attributes)
28
+ end
29
+
30
+ def self.from_hash(hash)
31
+ credential = new
32
+ hash.each do |key, value|
33
+ property = "@#{key}".to_sym
34
+ credential.instance_variable_set(property, value)
35
+ end
36
+ credential
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "camel_json"
2
+
3
+ class Representation
4
+ include ::KeycloakAdmin::CamelJson
5
+
6
+ def to_json(options=nil)
7
+ snaked_hash = as_json
8
+ snaked_hash.keys.reduce({}) do |camelized_hash, key|
9
+ camelized_hash[camelize(key, false)] = snaked_hash[key]
10
+ camelized_hash
11
+ end.to_json(options)
12
+ end
13
+
14
+ def self.from_json(json)
15
+ hash = JSON.parse(json)
16
+ from_hash(hash)
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module KeycloakAdmin
3
+ class TokenRepresentation < Representation
4
+ attr_accessor :access_token
5
+
6
+ def initialize(access_token)
7
+ @access_token = access_token
8
+ end
9
+
10
+ def self.from_hash(hash)
11
+ new(hash["access_token"])
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ module KeycloakAdmin
2
+ class UserRepresentation < Representation
3
+ attr_accessor :id,
4
+ :created_at,
5
+ :attributes,
6
+ :origin,
7
+ :username,
8
+ :email,
9
+ :enabled,
10
+ :email_verified,
11
+ :first_name,
12
+ :last_name,
13
+ :credentials
14
+
15
+ def self.from_hash(hash)
16
+ user = new
17
+ user.id = hash["id"]
18
+ user.created_at = Time.at(hash["createdTimestamp"] / 1000).to_datetime
19
+ user.origin = hash["origin"]
20
+ user.username = hash["username"]
21
+ user.email = hash["email"]
22
+ user.enabled = hash["enabled"]
23
+ user.email_verified = hash["emailVerified"]
24
+ user.first_name = hash["firstName"]
25
+ user.last_name = hash["lastName"]
26
+ user.attributes = hash["attributes"]
27
+ user.credentials = hash["credentials"]&.map{ |hash| CredentialRepresentation.from_hash(hash) } || []
28
+ user
29
+ end
30
+
31
+ def add_credential(credential_representation)
32
+ @credentials ||= []
33
+ @credentials.push(credential_representation)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module KeycloakAdmin
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,44 @@
1
+ require "logger"
2
+
3
+ require_relative "keycloak-admin/configuration"
4
+ require_relative "keycloak-admin/client/client"
5
+ require_relative "keycloak-admin/client/realm_client"
6
+ require_relative "keycloak-admin/client/token_client"
7
+ require_relative "keycloak-admin/client/user_client"
8
+ require_relative "keycloak-admin/representation/camel_json"
9
+ require_relative "keycloak-admin/representation/representation"
10
+ require_relative "keycloak-admin/representation/token_representation"
11
+ require_relative "keycloak-admin/representation/credential_representation"
12
+ require_relative "keycloak-admin/representation/user_representation"
13
+
14
+ module KeycloakAdmin
15
+
16
+ def self.configure
17
+ yield @configuration ||= KeycloakAdmin::Configuration.new
18
+ end
19
+
20
+ def self.config
21
+ @configuration
22
+ end
23
+
24
+ def self.realm(realm_name)
25
+ RealmClient.new(@configuration, realm_name)
26
+ end
27
+
28
+ def self.logger
29
+ config.logger
30
+ end
31
+
32
+ def self.load_configuration
33
+ configure do |config|
34
+ config.server_url = nil
35
+ config.user_realm_name = ""
36
+ config.client_id = "admin-cli"
37
+ config.logger = ::Logger.new(STDOUT)
38
+ config.username = nil
39
+ config.password = nil
40
+ end
41
+ end
42
+
43
+ load_configuration
44
+ end
@@ -0,0 +1,47 @@
1
+ RSpec.describe KeycloakAdmin::RealmClient do
2
+ describe "#realm_url" do
3
+
4
+ let(:realm_name) { nil }
5
+
6
+ before(:each) do
7
+ @built_url = KeycloakAdmin.realm(realm_name).realm_url
8
+ end
9
+
10
+ context "when realm_name is defined" do
11
+ let(:realm_name) { "master2" }
12
+ it "return a proper url with realm_name" do
13
+ expect(@built_url).to eq "http://auth.service.io/auth/realms/master2"
14
+ end
15
+ end
16
+
17
+ context "when realm_name is not defined" do
18
+ let(:realm_name) { nil }
19
+ it "return a proper url without realm_name" do
20
+ expect(@built_url).to eq "http://auth.service.io/auth/realms"
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "#admin_realm_url" do
26
+
27
+ let(:realm_name) { nil }
28
+
29
+ before(:each) do
30
+ @built_url = KeycloakAdmin.realm(realm_name).realm_admin_url
31
+ end
32
+
33
+ context "when realm_name is defined" do
34
+ let(:realm_name) { "master2" }
35
+ it "return a proper url with realm_name" do
36
+ expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/master2"
37
+ end
38
+ end
39
+
40
+ context "when realm_name is not defined" do
41
+ let(:realm_name) { nil }
42
+ it "return a proper url without realm_name" do
43
+ expect(@built_url).to eq "http://auth.service.io/auth/admin/realms"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,37 @@
1
+ RSpec.describe KeycloakAdmin::TokenClient do
2
+ describe "#initialize" do
3
+ let(:realm_name) { nil }
4
+ before(:each) do
5
+ @realm = KeycloakAdmin.realm(realm_name)
6
+ end
7
+
8
+ context "when realm_name is defined" do
9
+ let(:realm_name) { "master" }
10
+ it "does not raise any error" do
11
+ expect {
12
+ @realm.token
13
+ }.to_not raise_error
14
+ end
15
+ end
16
+
17
+ context "when realm_name is not defined" do
18
+ let(:realm_name) { nil }
19
+ it "raises any error" do
20
+ expect {
21
+ @realm.token
22
+ }.to raise_error(ArgumentError)
23
+ end
24
+ end
25
+ end
26
+
27
+ describe "#token_url" do
28
+ let(:realm_name) { "valid-realm" }
29
+ before(:each) do
30
+ @built_url = KeycloakAdmin.realm(realm_name).token.token_url
31
+ end
32
+
33
+ it "return a proper url" do
34
+ expect(@built_url).to eq "http://auth.service.io/auth/realms/valid-realm/protocol/openid-connect/token"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,74 @@
1
+ RSpec.describe KeycloakAdmin::TokenClient do
2
+ describe "#initialize" do
3
+ let(:realm_name) { nil }
4
+ before(:each) do
5
+ @realm = KeycloakAdmin.realm(realm_name)
6
+ end
7
+
8
+ context "when realm_name is defined" do
9
+ let(:realm_name) { "master" }
10
+ it "does not raise any error" do
11
+ expect {
12
+ @realm.users
13
+ }.to_not raise_error
14
+ end
15
+ end
16
+
17
+ context "when realm_name is not defined" do
18
+ let(:realm_name) { nil }
19
+ it "raises any error" do
20
+ expect {
21
+ @realm.users
22
+ }.to raise_error(ArgumentError)
23
+ end
24
+ end
25
+ end
26
+
27
+ describe "#users_url" do
28
+ let(:realm_name) { "valid-realm" }
29
+ let(:user_id) { nil }
30
+
31
+ before(:each) do
32
+ @built_url = KeycloakAdmin.realm(realm_name).users.users_url(user_id)
33
+ end
34
+
35
+ context "when user_id is not defined" do
36
+ let(:user_id) { nil }
37
+ it "return a proper url without user id" do
38
+ expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/users"
39
+ end
40
+ end
41
+
42
+ context "when user_id is defined" do
43
+ let(:user_id) { "95985b21-d884-4bbd-b852-cb8cd365afc2" }
44
+ it "return a proper url with the user id" do
45
+ expect(@built_url).to eq "http://auth.service.io/auth/admin/realms/valid-realm/users/95985b21-d884-4bbd-b852-cb8cd365afc2"
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#reset_password_url" do
51
+ let(:realm_name) { "valid-realm" }
52
+ let(:user_id) { nil }
53
+
54
+ before(:each) do
55
+ @client = KeycloakAdmin.realm(realm_name).users
56
+ end
57
+
58
+ context "when user_id is not defined" do
59
+ let(:user_id) { nil }
60
+ it "raises an error" do
61
+ expect {
62
+ @client.reset_password_url(user_id)
63
+ }.to raise_error(ArgumentError)
64
+ end
65
+ end
66
+
67
+ context "when user_id is defined" do
68
+ let(:user_id) { 42 }
69
+ it "return a proper url" do
70
+ expect(@client.reset_password_url(user_id)).to eq "http://auth.service.io/auth/admin/realms/valid-realm/users/42/reset-password"
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "../lib/keycloak-admin"
2
+
3
+ require "byebug"
4
+
5
+ def configure
6
+ KeycloakAdmin.configure do |config|
7
+ config.server_url = "http://auth.service.io/auth"
8
+ config.client_id = "admin-cli"
9
+ config.user_realm_name = "master2"
10
+ config.username = "bobby"
11
+ config.password = "coucou"
12
+ end
13
+ end
14
+
15
+ RSpec.configure do |config|
16
+ config.expect_with :rspec do |expectations|
17
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
18
+ end
19
+
20
+ configure
21
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keycloak-admin
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Lorent Lempereur
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-01-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.7.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.7.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 9.1.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 9.1.0
41
+ description: Keycloak Admin REST API client written in Ruby
42
+ email:
43
+ - lorent.lempereur.dev@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - ".rspec"
50
+ - Dockerfile
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - MIT-LICENSE
54
+ - README.md
55
+ - keycloak-admin.gemspec
56
+ - lib/keycloak-admin.rb
57
+ - lib/keycloak-admin/client/client.rb
58
+ - lib/keycloak-admin/client/realm_client.rb
59
+ - lib/keycloak-admin/client/token_client.rb
60
+ - lib/keycloak-admin/client/user_client.rb
61
+ - lib/keycloak-admin/configuration.rb
62
+ - lib/keycloak-admin/representation/camel_json.rb
63
+ - lib/keycloak-admin/representation/credential_representation.rb
64
+ - lib/keycloak-admin/representation/representation.rb
65
+ - lib/keycloak-admin/representation/token_representation.rb
66
+ - lib/keycloak-admin/representation/user_representation.rb
67
+ - lib/keycloak-admin/version.rb
68
+ - spec/client/realm_client_spec.rb
69
+ - spec/client/token_client_spec.rb
70
+ - spec/client/user_client_spec.rb
71
+ - spec/spec_helper.rb
72
+ homepage: https://github.com/looorent/keycloak-admin-ruby
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.6.4
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: Keycloak Admin REST API client written in Ruby
96
+ test_files: []