ruby-keycloak-admin 26.0.8
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 +7 -0
- data/lib/keycloak/admin/agent.rb +144 -0
- data/lib/keycloak/admin/clients.rb +24 -0
- data/lib/keycloak/admin/error.rb +52 -0
- data/lib/keycloak/admin/groups.rb +67 -0
- data/lib/keycloak/admin/realms.rb +29 -0
- data/lib/keycloak/admin/resource/pagination.rb +47 -0
- data/lib/keycloak/admin/resource.rb +103 -0
- data/lib/keycloak/admin/users.rb +87 -0
- data/lib/keycloak/admin/version.rb +7 -0
- data/lib/keycloak/admin.rb +118 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3e0ce0221f1b819d51a1b15b34e9c143f5200df7dbfb470f078e75d971c53792
|
4
|
+
data.tar.gz: ab7bfe86c2b7967661c9f0df6f7ca3deb7d894ff73bfdee7df74dd6c1a89583f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 292f27418bf59e5db36b15b476a4a666c4cc4c68ff0685e2b22555fb3a3931ec25d194993169c98e4cfe17c0a78196e6584befa9c2bf89bd88d8b53be28ae76f
|
7
|
+
data.tar.gz: 815897d5d7ce17ecd3d84ca7602fc135f905e610f44d6347fca0802d11e96532245066884697586472145163ca63205b0ea01b04fc1c4f515aee0de2b8b5cb42
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
require 'keycloak/admin/error'
|
7
|
+
|
8
|
+
module Keycloak
|
9
|
+
module Admin
|
10
|
+
class Agent # :nodoc: all
|
11
|
+
include HTTParty
|
12
|
+
headers 'Accept' => 'application/json', 'Content-Type' => 'application/json'
|
13
|
+
debug_output $stdout if ENV['KEYCLOAK_ADMIN_DEBUG']
|
14
|
+
|
15
|
+
attr_accessor :base_url, :username, :password, :realm, :grant_type, :always_terminate
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@base_url = 'http://localhost:8080'
|
19
|
+
@realm = 'master'
|
20
|
+
@username = 'nil'
|
21
|
+
@password = 'nil'
|
22
|
+
@grant_type = 'password'
|
23
|
+
@always_terminate = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def logout
|
27
|
+
terminate_session
|
28
|
+
end
|
29
|
+
|
30
|
+
%i[get post put delete head].each do |method|
|
31
|
+
define_method method do |path, params: {}|
|
32
|
+
request(method, path, params:)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def request(method, path, params: {})
|
37
|
+
refresh_session || create_session
|
38
|
+
|
39
|
+
params[:headers] ||= {}
|
40
|
+
params[:headers][:Authorization] = "Bearer #{@session['access_token']}"
|
41
|
+
|
42
|
+
response = self.class.send(
|
43
|
+
method,
|
44
|
+
"#{@base_url}/#{path}",
|
45
|
+
body: params[:body],
|
46
|
+
headers: params[:headers]
|
47
|
+
)
|
48
|
+
|
49
|
+
terminate_session if @always_terminate
|
50
|
+
|
51
|
+
Keycloak::Admin.raise_error(response) if !response.code.between?(200, 299)
|
52
|
+
|
53
|
+
response.parsed_response
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def create_session
|
59
|
+
return false if !session_expired?
|
60
|
+
|
61
|
+
response = self.class.post(
|
62
|
+
"#{@base_url}/realms/master/protocol/openid-connect/token",
|
63
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
64
|
+
body: {
|
65
|
+
grant_type: 'password',
|
66
|
+
client_id: 'admin-cli',
|
67
|
+
username: @username,
|
68
|
+
password: @password
|
69
|
+
}
|
70
|
+
)
|
71
|
+
|
72
|
+
Keycloak::Admin.raise_error(response) if !response.code.between?(200, 299)
|
73
|
+
|
74
|
+
store_session(response)
|
75
|
+
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
def refresh_session
|
80
|
+
return false if !session_running?
|
81
|
+
return false if refresh_expired?
|
82
|
+
|
83
|
+
response = self.class.post(
|
84
|
+
"#{@base_url}/realms/master/protocol/openid-connect/token",
|
85
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
86
|
+
body: {
|
87
|
+
grant_type: 'refresh_token',
|
88
|
+
client_id: 'admin-cli',
|
89
|
+
refresh_token: @session['refresh_token']
|
90
|
+
}
|
91
|
+
)
|
92
|
+
|
93
|
+
return false if response.code.eql?(400)
|
94
|
+
return Keycloak::Admin.raise_error(response) if !response.code.between?(200, 299)
|
95
|
+
|
96
|
+
store_session(response)
|
97
|
+
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
101
|
+
def terminate_session
|
102
|
+
return false if !session_running?
|
103
|
+
return false if refresh_expired?
|
104
|
+
|
105
|
+
response = self.class.post(
|
106
|
+
"#{@base_url}/realms/master/protocol/openid-connect/logout",
|
107
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
108
|
+
body: {
|
109
|
+
client_id: 'admin-cli',
|
110
|
+
refresh_token: @session['refresh_token']
|
111
|
+
}
|
112
|
+
)
|
113
|
+
|
114
|
+
@session = nil
|
115
|
+
|
116
|
+
Keycloak::Admin.raise_error(response) if !response.code.between?(200, 299)
|
117
|
+
|
118
|
+
true
|
119
|
+
end
|
120
|
+
|
121
|
+
def store_session(response)
|
122
|
+
@session = response.parsed_response
|
123
|
+
@session['expires_at'] = Time.now + @session['expires_in']
|
124
|
+
@session['refresh_expires_at'] = Time.now + @session['refresh_expires_in']
|
125
|
+
end
|
126
|
+
|
127
|
+
def session_running?
|
128
|
+
!@session.nil?
|
129
|
+
end
|
130
|
+
|
131
|
+
def session_expired?
|
132
|
+
return true if @session.nil?
|
133
|
+
|
134
|
+
Time.now > @session['expires_at']
|
135
|
+
end
|
136
|
+
|
137
|
+
def refresh_expired?
|
138
|
+
return true if @session.nil?
|
139
|
+
|
140
|
+
Time.now > @session['refresh_expires_at']
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'keycloak/admin/resource'
|
4
|
+
|
5
|
+
module Keycloak
|
6
|
+
module Admin
|
7
|
+
##
|
8
|
+
# Clients resource.
|
9
|
+
#
|
10
|
+
# The class is based on Keycloak::Admin::Resource and
|
11
|
+
# Keycloak::Admin::Resource::Pagination.
|
12
|
+
module Clients
|
13
|
+
class << self
|
14
|
+
include Keycloak::Admin::Resource
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def resource
|
19
|
+
"admin/realms/#{@agent.realm}/clients"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Keycloak
|
4
|
+
module Admin
|
5
|
+
class ConfigurationError < StandardError; end # :nodoc:
|
6
|
+
class ConnectionFailedError < StandardError; end # :nodoc:
|
7
|
+
class NotFoundError < StandardError; end # :nodoc:
|
8
|
+
class UnauthorizedError < StandardError; end # :nodoc:
|
9
|
+
class ForbiddenError < StandardError; end # :nodoc:
|
10
|
+
class BadRequestError < StandardError; end # :nodoc:
|
11
|
+
class ConflictError < StandardError; end # :nodoc:
|
12
|
+
class InternalServerError < StandardError; end # :nodoc:
|
13
|
+
class ServiceUnavailableError < StandardError; end # :nodoc:
|
14
|
+
class MethodNotAllowedError < StandardError; end # :nodoc:
|
15
|
+
class BadGatewayError < StandardError; end # :nodoc:
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def raise_error(response)
|
19
|
+
error_classes = {
|
20
|
+
400 => BadRequestError,
|
21
|
+
401 => UnauthorizedError,
|
22
|
+
403 => ForbiddenError,
|
23
|
+
404 => NotFoundError,
|
24
|
+
405 => MethodNotAllowedError,
|
25
|
+
409 => ConflictError,
|
26
|
+
500 => InternalServerError,
|
27
|
+
502 => BadGatewayError,
|
28
|
+
503 => ServiceUnavailableError
|
29
|
+
}
|
30
|
+
error_class = error_classes[response.code] || StandardError
|
31
|
+
|
32
|
+
raise error_class, error_message(response)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def error_message(response)
|
38
|
+
parsed_response = response.parsed_response
|
39
|
+
|
40
|
+
return parsed_response if response.parsed_response.is_a?(String)
|
41
|
+
|
42
|
+
if response.parsed_response.is_a?(Hash)
|
43
|
+
return parsed_response['errorMessage'] ||
|
44
|
+
parsed_response['error'] ||
|
45
|
+
'Unknown error'
|
46
|
+
end
|
47
|
+
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'keycloak/admin/resource'
|
4
|
+
require 'keycloak/admin/resource/pagination'
|
5
|
+
|
6
|
+
module Keycloak
|
7
|
+
module Admin
|
8
|
+
##
|
9
|
+
# Groups resource.
|
10
|
+
#
|
11
|
+
# The class is based on Keycloak::Admin::Resource and
|
12
|
+
# Keycloak::Admin::Resource::Pagination. It provides following
|
13
|
+
# additional methods:
|
14
|
+
#
|
15
|
+
# * ::add
|
16
|
+
# * ::remove
|
17
|
+
# * ::members
|
18
|
+
module Groups
|
19
|
+
class << self
|
20
|
+
include Keycloak::Admin::Resource
|
21
|
+
include Keycloak::Admin::Resource::Pagination
|
22
|
+
|
23
|
+
##
|
24
|
+
# Add user to group.
|
25
|
+
def add(id, user_id)
|
26
|
+
@agent.put("/admin/realms/#{@agent.realm}/users/#{user_id}/groups/#{id}")
|
27
|
+
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Remove user from group.
|
33
|
+
def remove(id, user_id)
|
34
|
+
@agent.delete("/admin/realms/#{@agent.realm}/users/#{user_id}/groups/#{id}")
|
35
|
+
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Get group members.
|
41
|
+
def members(id)
|
42
|
+
objects = []
|
43
|
+
(1..pages).each do |page|
|
44
|
+
first = (page * MAX_ENTRIES) - MAX_ENTRIES
|
45
|
+
objects << @agent.get("#{resource}/#{id}/members?first=#{first}&max=#{MAX_ENTRIES}")
|
46
|
+
end
|
47
|
+
|
48
|
+
objects.flatten.map { |object| mash(object) }
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Create subgroup.
|
53
|
+
def subgroup(id, attributes)
|
54
|
+
@agent.post("#{resource}/#{id}/children", params: { body: attributes.to_json })
|
55
|
+
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def resource
|
62
|
+
"admin/realms/#{@agent.realm}/groups"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'keycloak/admin/resource'
|
4
|
+
|
5
|
+
module Keycloak
|
6
|
+
module Admin
|
7
|
+
##
|
8
|
+
# Realms resource.
|
9
|
+
#
|
10
|
+
# The class is based on Keycloak::Admin::Resource and
|
11
|
+
# Keycloak::Admin::Resource::Pagination. The method #find_by_id is renamed
|
12
|
+
# to +find_by_name+.
|
13
|
+
module Realms
|
14
|
+
class << self
|
15
|
+
include Keycloak::Admin::Resource
|
16
|
+
if method_defined? :find_by_id
|
17
|
+
alias find_by_name find_by_id
|
18
|
+
undef find_by_id
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def resource
|
24
|
+
'/admin/realms'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Keycloak
|
4
|
+
module Admin
|
5
|
+
module Resource
|
6
|
+
##
|
7
|
+
# Abstract class extension for Keycloak::Admin resources with methods
|
8
|
+
# providing pagination.
|
9
|
+
#
|
10
|
+
# * #all
|
11
|
+
module Pagination
|
12
|
+
MAX_ENTRIES = 100
|
13
|
+
|
14
|
+
##
|
15
|
+
# List all resources.
|
16
|
+
def all
|
17
|
+
objects = []
|
18
|
+
(1..pages).each do |page|
|
19
|
+
first = (page * MAX_ENTRIES) - MAX_ENTRIES
|
20
|
+
objects << @agent.get("#{resource}?first=#{first}&max=#{MAX_ENTRIES}")
|
21
|
+
end
|
22
|
+
|
23
|
+
objects.flatten.map { |object| mash(object) }
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def count
|
29
|
+
@agent.get("#{resource}/count")
|
30
|
+
end
|
31
|
+
|
32
|
+
def pages
|
33
|
+
count = count()
|
34
|
+
count = count['count'] if count.is_a?(Hash)
|
35
|
+
|
36
|
+
return 0 if count.zero?
|
37
|
+
return 1 if count <= MAX_ENTRIES
|
38
|
+
|
39
|
+
pages = count / MAX_ENTRIES
|
40
|
+
pages += 1 if (count % MAX_ENTRIES).positive?
|
41
|
+
|
42
|
+
pages
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hashie'
|
4
|
+
|
5
|
+
module Keycloak
|
6
|
+
module Admin
|
7
|
+
##
|
8
|
+
# Abstract class for Keycloak::Admin resources with common methods.
|
9
|
+
#
|
10
|
+
# * #all
|
11
|
+
# * #create
|
12
|
+
# * #count
|
13
|
+
# * #delete
|
14
|
+
# * #find_by, alias #lookup
|
15
|
+
# * #find_by_id, alias #get
|
16
|
+
# * #update, alias #edit
|
17
|
+
module Resource
|
18
|
+
attr_writer :agent
|
19
|
+
|
20
|
+
##
|
21
|
+
# List all resource objects.
|
22
|
+
def all
|
23
|
+
objects = @agent.get(resource)
|
24
|
+
|
25
|
+
objects.map { |object| mash(object) }
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Create a new resource object.
|
30
|
+
def create(attributes)
|
31
|
+
@agent.post(resource, params: { body: attributes.to_json })
|
32
|
+
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Delete a resource object by id.
|
38
|
+
def delete(id)
|
39
|
+
@agent.delete("#{resource}/#{id}")
|
40
|
+
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Find resource objects by attributes, name and value.
|
46
|
+
def find_by(lookup)
|
47
|
+
objects = all
|
48
|
+
|
49
|
+
lookup.each do |key, value|
|
50
|
+
objects = objects.select do |object|
|
51
|
+
match_value?(object, key, value)
|
52
|
+
end
|
53
|
+
break if !objects
|
54
|
+
end
|
55
|
+
|
56
|
+
objects || []
|
57
|
+
end
|
58
|
+
alias lookup find_by
|
59
|
+
|
60
|
+
##
|
61
|
+
# Find a resource object by id.
|
62
|
+
def find_by_id(id)
|
63
|
+
object = @agent.get("#{resource}/#{id}")
|
64
|
+
|
65
|
+
mash(object)
|
66
|
+
end
|
67
|
+
alias get find_by_id
|
68
|
+
|
69
|
+
##
|
70
|
+
# Update a resource object by id.
|
71
|
+
def update(id, attributes)
|
72
|
+
@agent.put("#{resource}/#{id}", params: { body: attributes.to_json })
|
73
|
+
|
74
|
+
true
|
75
|
+
end
|
76
|
+
alias edit update
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def resource
|
81
|
+
raise NotImplementedError
|
82
|
+
end
|
83
|
+
|
84
|
+
def match_value?(object, key, value)
|
85
|
+
return false if !object.key?(key)
|
86
|
+
|
87
|
+
if value.is_a?(String)
|
88
|
+
object[key].match?(value)
|
89
|
+
else
|
90
|
+
object[key] == value
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def mash(object)
|
95
|
+
if object.is_a?(Array)
|
96
|
+
object.map { |item| Hashie::Mash.new(item) }
|
97
|
+
else
|
98
|
+
Hashie::Mash.new(object)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'keycloak/admin/resource'
|
4
|
+
require 'keycloak/admin/resource/pagination'
|
5
|
+
|
6
|
+
module Keycloak
|
7
|
+
module Admin
|
8
|
+
##
|
9
|
+
# Users resource.
|
10
|
+
#
|
11
|
+
# The class is based on Keycloak::Admin::Resource and
|
12
|
+
# Keycloak::Admin::Resource::Pagination. It provides following
|
13
|
+
# additional methods:
|
14
|
+
#
|
15
|
+
# * ::join
|
16
|
+
# * ::leave
|
17
|
+
# * ::logout
|
18
|
+
# * ::password
|
19
|
+
# * ::sessions
|
20
|
+
module Users
|
21
|
+
class << self
|
22
|
+
include Keycloak::Admin::Resource
|
23
|
+
include Keycloak::Admin::Resource::Pagination
|
24
|
+
|
25
|
+
##
|
26
|
+
# Add user to group.
|
27
|
+
def join(id, group_id)
|
28
|
+
@agent.put("#{resource}/#{id}/groups/#{group_id}")
|
29
|
+
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Remove user from group.
|
35
|
+
def leave(id, group_id)
|
36
|
+
@agent.delete("#{resource}/#{id}/groups/#{group_id}")
|
37
|
+
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# User membership.
|
43
|
+
def membership(id)
|
44
|
+
objects = []
|
45
|
+
(1..pages).each do |page|
|
46
|
+
first = (page * MAX_ENTRIES) - MAX_ENTRIES
|
47
|
+
objects << @agent.get("#{resource}/#{id}/groups?first=#{first}&max=#{MAX_ENTRIES}")
|
48
|
+
end
|
49
|
+
|
50
|
+
objects.flatten.map { |object| mash(object) }
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Logout user from all sessions.
|
55
|
+
def logout(id)
|
56
|
+
@agent.post("#{resource}/#{id}/logout")
|
57
|
+
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Set new password for user.
|
63
|
+
def password(id, attributes)
|
64
|
+
# { temporary: false, value: 'password' }
|
65
|
+
attributes[:type] = 'password'
|
66
|
+
@agent.put("#{resource}/#{id}/reset-password", params: { body: attributes.to_json })
|
67
|
+
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Get user sessions.
|
73
|
+
def sessions(id)
|
74
|
+
objects = @agent.get("#{resource}/#{id}/sessions")
|
75
|
+
|
76
|
+
objects.map { |object| mash(object) }
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def resource
|
82
|
+
"admin/realms/#{@agent.realm}/users"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'keycloak/admin/version'
|
4
|
+
require 'keycloak/admin/agent'
|
5
|
+
require 'keycloak/admin/error'
|
6
|
+
|
7
|
+
require 'keycloak/admin/realms'
|
8
|
+
require 'keycloak/admin/clients'
|
9
|
+
require 'keycloak/admin/users'
|
10
|
+
require 'keycloak/admin/groups'
|
11
|
+
|
12
|
+
module Keycloak
|
13
|
+
##
|
14
|
+
# Keycloak::Admin is a Ruby client for the Keycloak administration API.
|
15
|
+
#
|
16
|
+
# This is the main module. It provides methods to configure the connection to
|
17
|
+
# any Keycloak service, as well as methods to manage and control the several
|
18
|
+
# Keycloak resources.
|
19
|
+
module Admin
|
20
|
+
class << self
|
21
|
+
##
|
22
|
+
# Configure Keycloak::Admin, the handler for all administration tasks.
|
23
|
+
#
|
24
|
+
# Provide Keycloak server base *url*, master realm admin user
|
25
|
+
# *credentials* and id of *realm* to be managed.
|
26
|
+
#
|
27
|
+
# Keycloak::Admin.configure do |config|
|
28
|
+
# config.username = 'admin',
|
29
|
+
# config.password = 'admin',
|
30
|
+
# config.realm = 'zone', # default: master
|
31
|
+
# config.base_url = 'https://keycloak.example.com' # default: http://localhost:8080
|
32
|
+
# end
|
33
|
+
def configure
|
34
|
+
@agent ||= Keycloak::Admin::Agent.new
|
35
|
+
yield @agent
|
36
|
+
@configured = true
|
37
|
+
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Verify if Keycloak::Admin is configured.
|
43
|
+
def configured?
|
44
|
+
@configured.nil? ? false : @configured
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Raise error if Keycloak::Admin is not configured.
|
49
|
+
def configured!
|
50
|
+
raise Keycloak::Admin::ConfigurationError, 'Keycloak::Admin is not configured' if !configured?
|
51
|
+
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Reset Keycloak::Admin configuration.
|
57
|
+
def reset!
|
58
|
+
@agent&.logout
|
59
|
+
@agent = nil
|
60
|
+
@configured = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Manage server realms. See Keycloak::Admin::Realms for usage.
|
65
|
+
def realms
|
66
|
+
configured!
|
67
|
+
Keycloak::Admin::Realms.agent = @agent
|
68
|
+
|
69
|
+
Keycloak::Admin::Realms
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Manage realm clients. See Keycloak::Admin::Clients for usage.
|
74
|
+
def clients
|
75
|
+
configured!
|
76
|
+
Keycloak::Admin::Clients.agent = @agent
|
77
|
+
|
78
|
+
Keycloak::Admin::Clients
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# Manage realm users. See Keycloak::Admin::Users for usage.
|
83
|
+
def users
|
84
|
+
configured!
|
85
|
+
Keycloak::Admin::Users.agent = @agent
|
86
|
+
|
87
|
+
Keycloak::Admin::Users
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Manage realm groups. See Keycloak::Admin::Groups for usage.
|
92
|
+
def groups
|
93
|
+
configured!
|
94
|
+
Keycloak::Admin::Groups.agent = @agent
|
95
|
+
|
96
|
+
Keycloak::Admin::Groups
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Verify if the Keycloak server is ready.
|
101
|
+
#
|
102
|
+
# Beware, method returns +nil+ if the server does not respond (404 not
|
103
|
+
# found) to health checks.
|
104
|
+
def ready?
|
105
|
+
configured!
|
106
|
+
|
107
|
+
begin
|
108
|
+
@agent.head('health/ready')
|
109
|
+
true
|
110
|
+
rescue Keycloak::Admin::NotFoundError
|
111
|
+
nil
|
112
|
+
rescue Keycloak::Admin::ServiceUnavailableError
|
113
|
+
false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-keycloak-admin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 26.0.8
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tobias Schäfer
|
8
|
+
bindir: bin
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-01-15 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: hashie
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 5.0.0
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 5.0.0
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: httparty
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.21.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.21.0
|
40
|
+
description: |+
|
41
|
+
Ruby Keycloack admin API wrapper.
|
42
|
+
|
43
|
+
This gem provides a simple wrapper for the Keycloak admin API.
|
44
|
+
|
45
|
+
* https://www.keycloak.org
|
46
|
+
* https://www.keycloak.org/documentation
|
47
|
+
* https://www.keycloak.org/docs-api/26.0.8/rest-api/index.html
|
48
|
+
|
49
|
+
email:
|
50
|
+
- github@blackox.org
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- lib/keycloak/admin.rb
|
56
|
+
- lib/keycloak/admin/agent.rb
|
57
|
+
- lib/keycloak/admin/clients.rb
|
58
|
+
- lib/keycloak/admin/error.rb
|
59
|
+
- lib/keycloak/admin/groups.rb
|
60
|
+
- lib/keycloak/admin/realms.rb
|
61
|
+
- lib/keycloak/admin/resource.rb
|
62
|
+
- lib/keycloak/admin/resource/pagination.rb
|
63
|
+
- lib/keycloak/admin/users.rb
|
64
|
+
- lib/keycloak/admin/version.rb
|
65
|
+
homepage: https://github.com/tschaefer/keycloak-admin
|
66
|
+
licenses:
|
67
|
+
- MIT
|
68
|
+
metadata:
|
69
|
+
rubygems_mfa_required: 'true'
|
70
|
+
source_code_uri: https://github.com/tschaefer/keycloak-admin
|
71
|
+
bug_tracker_uri: https://github.com/tschaefer/keycloak-admin/issues
|
72
|
+
post_install_message: All your Keycloak are belong to us!
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '3.1'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubygems_version: 3.6.2
|
88
|
+
specification_version: 4
|
89
|
+
summary: Ruby Keycloack admin API wrapper.
|
90
|
+
test_files: []
|
91
|
+
...
|