ripple_keycloak 0.1.0 → 0.2.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: 0c695a14343b4ad57269888035cff4e7f1cf6c358a265cc21bc730b0a3356f86
4
- data.tar.gz: 467cd8d7424584d050c1ff9cbc3a2156cf71556e5b8e454994d522375666f51d
3
+ metadata.gz: a1110e9ee63adcb8fe9c9b21859d4b887b2041f4cb0b1890d11fb4b9e1850ba4
4
+ data.tar.gz: ea16bf655491f58786463fd8809b29572ed2dc8fbf11453ac287185c7e50f0dd
5
5
  SHA512:
6
- metadata.gz: 1b3184c41d29d70f9b7b4ac59a2d45bdb949108ba74cc4169400dc80fe4821f1b2cbaab331584507cfac8cf7ecbd8aa3875768daf68e790894353baf1f1e2e74
7
- data.tar.gz: e9a2534b9e40c6043679720b6f039a37994cb555252d74c86b5aa375269e7b6f13e4088459f095158d2a2b0e8df162c07dbf1dd7c9a83c8cf5c623ef51b48802
6
+ metadata.gz: 72a51cd15b79be3aa6fb54aa469d0e71a5012e38999fa7f69d96f83630a7a948c4defec527eb725ec09d7e106bce4f0a63a066e09c7002b0c6f960f18f149d96
7
+ data.tar.gz: 57cd5ae0d044e93e8a814af2a10fe9b3c98576bf0838dbabc672fabf7de8cba974710c882a62662d35094b8b949b2f8d29f5edd5424a696ff5c21a4939f24881
@@ -0,0 +1,17 @@
1
+ name: Bump gem version tag
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+
7
+ jobs:
8
+ tag-new-versions:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v2
12
+ with:
13
+ fetch-depth: 2
14
+ - uses: salsify/action-detect-and-tag-new-version@v1
15
+ with:
16
+ version-command: |
17
+ cat lib/ripple_keycloak/version.rb
@@ -0,0 +1,29 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - v*
7
+
8
+ jobs:
9
+ build:
10
+ name: Build + Publish
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Set up Ruby 2.7.1
16
+ uses: actions/setup-ruby@v1
17
+ with:
18
+ ruby-version: 2.7.1
19
+
20
+ - name: Publish to RubyGems
21
+ run: |
22
+ mkdir -p $HOME/.gem
23
+ touch $HOME/.gem/credentials
24
+ chmod 0600 $HOME/.gem/credentials
25
+ printf -- "---\n:rubygems_api_key: ${RUBYGEMS_API_KEY}\n" > $HOME/.gem/credentials
26
+ gem build *.gemspec
27
+ gem push *.gem
28
+ env:
29
+ RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
@@ -0,0 +1,34 @@
1
+ name: Lint and test
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ build:
11
+ name: Lint + Test
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - name: Set up Ruby 2.7.1
17
+ uses: actions/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.7.1
20
+ - name: Restore cache
21
+ uses: actions/cache@v2
22
+ with:
23
+ path: vendor/bundle
24
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
25
+ restore-keys: |
26
+ ${{ runner.os }}-gems-
27
+ - name: Install dependencies
28
+ run: |
29
+ bundle config path vendor/bundle
30
+ bundle install --jobs 4 --retry 3
31
+ - name: Run Rubocop
32
+ run: bundle exec rubocop
33
+ - name: Run rspec
34
+ run: bundle exec rspec
data/.gitignore CHANGED
File without changes
data/.rspec CHANGED
@@ -1,3 +1 @@
1
- --format documentation
2
- --color
3
1
  --require spec_helper
@@ -27,3 +27,16 @@ Style/SlicingWithRange:
27
27
 
28
28
  Style/Documentation:
29
29
  Enabled: false
30
+
31
+ Metrics/BlockLength:
32
+ Exclude:
33
+ - spec/**/**
34
+
35
+ Style/TrivialAccessors:
36
+ Exclude:
37
+ - lib/ripple_keycloak/base_model.rb
38
+
39
+ AllCops:
40
+ Exclude:
41
+ - bin/**
42
+ - vendor/**/**
File without changes
data/Gemfile CHANGED
File without changes
File without changes
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # RippleKeycloak
1
+ # Ripple Keycloak
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ripple_keycloak`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ ![Lint and test](https://github.com/hex-event-solutions/ripple_keycloak/workflows/Lint%20and%20test/badge.svg)
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ Slim interface focused on groups, roles and users for Keycloak's Admin REST API
6
6
 
7
7
  ## Installation
8
8
 
@@ -22,7 +22,48 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ The client must be configured before usage
26
+
27
+ ```ruby
28
+ RippleKeycloak::Client.configure do |c|
29
+ c.base_url = <keycloak_url>
30
+ c.realm = <keycloak_realm>
31
+ c.client_id = <client_id>
32
+ c.client_secret = <client_secret>
33
+ end
34
+ ```
35
+
36
+ The supplied client must be of 'confidential' type, and allow service account login.
37
+
38
+ After configuring, use the supplied interfaces to query, create, update or delete resources in Keycloak.
39
+
40
+ ### Standard methods
41
+
42
+ The below methods are available on `RippleKeycloak::User`, `RippleKeycloak::Group` and `RippleKeycloak::Role`.
43
+
44
+ - find(id) - returns the resource with the given id
45
+ - find_by(field:, value:) - searches the resource type for an exact match against field and value
46
+ - search(value) - searches the resource type for a match in any field
47
+ - all - returns all resources
48
+ - delete(id) - deletes the resource with the given id
49
+
50
+ ### RippleKeycloak::User
51
+
52
+ - create(payload) - posts given payload to user create
53
+ - add_to_group(user_id, group_id) - adds given user to given group
54
+ - remove_from_group(user_id, group_id) - removes given user from given group
55
+ - add_role(user_id, role_name) - adds given role to user
56
+ - remove_role(user_id, role_name) - removes given role from user
57
+
58
+ ### RippleKeycloak::Group
59
+
60
+ - create(name:, parent: false) - creates a group with the given name, optionally under the given parent
61
+ - add_role(group_id, role_name) - adds given role to group
62
+ - remove_role(group_id, role_name) - removes given role from group
63
+
64
+ ### RippleKeycloak::Role
65
+
66
+ - create(name:) - creates a role with the given name
26
67
 
27
68
  ## Development
28
69
 
@@ -32,7 +73,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
32
73
 
33
74
  ## Contributing
34
75
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ripple_keycloak. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/ripple_keycloak/blob/master/CODE_OF_CONDUCT.md).
76
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hex-event-solutions/ripple_keycloak. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/hex-event-solutions/ripple_keycloak/blob/master/CODE_OF_CONDUCT.md).
36
77
 
37
78
 
38
79
  ## License
@@ -41,4 +82,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
41
82
 
42
83
  ## Code of Conduct
43
84
 
44
- Everyone interacting in the RippleKeycloak project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/ripple_keycloak/blob/master/CODE_OF_CONDUCT.md).
85
+ Everyone interacting in the RippleKeycloak project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/hex-event-solutions/ripple_keycloak/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
File without changes
File without changes
data/bin/setup CHANGED
File without changes
File without changes
@@ -10,12 +10,12 @@ module RippleKeycloak
10
10
  end
11
11
 
12
12
  def search(value)
13
- client.search(@object_type, value)
13
+ client.get("#{@object_type}?search=#{value}")
14
14
  end
15
15
 
16
16
  def all(first: nil, max: nil)
17
17
  url = "#{@object_type}?"
18
- url += "first=#{first}" if first
18
+ url += "first=#{first}&" if first
19
19
  url += "max=#{max}" if max
20
20
 
21
21
  client.get(url)
@@ -26,7 +26,13 @@ module RippleKeycloak
26
26
  end
27
27
 
28
28
  def find_by(field:, value:)
29
- client.find_by(@object_type, field, value)
29
+ results = search(value).parsed_response
30
+ if results.is_a? Array
31
+ results.each do |instance|
32
+ return instance if instance[field] == value
33
+ end
34
+ end
35
+ raise NotFoundError, "Object type: #{@object_type}, field: #{field}, value: #{value}"
30
36
  end
31
37
 
32
38
  def delete(id)
@@ -40,6 +46,6 @@ module RippleKeycloak
40
46
  end
41
47
  end
42
48
 
43
- delegate :base_model, to: :class
49
+ delegate :object_type, to: :class
44
50
  end
45
51
  end
@@ -24,10 +24,7 @@ module RippleKeycloak
24
24
  options = add_auth_header(options)
25
25
  resource = "admin/realms/#{realm}/" + resource
26
26
  end
27
- if json
28
- options = add_header(options, 'Content-Type', 'application/json')
29
- options[:body] = options[:body].to_json
30
- end
27
+ options = format_as_json(options) if json
31
28
 
32
29
  return_or_raise post("#{base_uri}/#{resource}", options)
33
30
  end
@@ -37,10 +34,7 @@ module RippleKeycloak
37
34
  options = add_auth_header(options)
38
35
  resource = "admin/realms/#{realm}/" + resource
39
36
  end
40
- if json
41
- options = add_header(options, 'Content-Type', 'application/json')
42
- options[:body] = options[:body].to_json
43
- end
37
+ options = format_as_json(options) if json
44
38
 
45
39
  return_or_raise put("#{base_uri}/#{resource}", options)
46
40
  end
@@ -59,43 +53,37 @@ module RippleKeycloak
59
53
  options = add_auth_header(options)
60
54
  resource = "admin/realms/#{realm}/" + resource
61
55
  end
62
- if json
63
- options = add_header(options, 'Content-Type', 'application/json')
64
- options[:body] = options[:body].to_json
65
- end
56
+ options = format_as_json(options) if json
66
57
 
67
58
  return_or_raise delete("#{base_uri}/#{resource}", options)
68
59
  end
69
60
 
70
61
  private
71
62
 
72
- attr_accessor :configuration,
73
- :access_token,
74
- :access_token_expiry
63
+ attr_accessor :configuration, :access_token, :access_token_expiry
75
64
 
76
- delegate :base_url,
77
- :realm,
78
- :client_id,
79
- :client_secret,
80
- to: :configuration
65
+ delegate :base_url, :realm, :client_id, :client_secret, to: :configuration
81
66
 
82
67
  delegate :raise_error, to: :error_handler
83
68
 
69
+ def format_as_json(options)
70
+ options = add_header(options, 'Content-Type', 'application/json')
71
+ options[:body] = options[:body].to_json
72
+ options
73
+ end
74
+
84
75
  def return_or_raise(response)
85
- if [200, 201, 204].include? response.code
86
- response
87
- else
88
- raise_error response
89
- end
76
+ return response if [200, 201, 204].include? response.code
77
+
78
+ raise_error response
90
79
  end
91
80
 
92
81
  def auth
93
- response = post_formatted("realms/#{realm}/protocol/openid-connect/token",
94
- body: {
95
- grant_type: 'client_credentials',
96
- client_id: client_id,
97
- client_secret: client_secret
98
- }, json: false, authed: false)
82
+ response = post_formatted(
83
+ "realms/#{realm}/protocol/openid-connect/token",
84
+ body: { grant_type: 'client_credentials', client_id: client_id, client_secret: client_secret },
85
+ json: false, authed: false
86
+ )
99
87
  update_token_fields response
100
88
  access_token
101
89
  end
@@ -115,11 +103,9 @@ module RippleKeycloak
115
103
 
116
104
  def token
117
105
  now = Time.now
118
- if access_token_expiry < now
119
- auth
120
- else
121
- access_token
122
- end
106
+ return auth if access_token_expiry < now
107
+
108
+ access_token
123
109
  end
124
110
 
125
111
  def add_auth_header(options)
@@ -148,19 +134,5 @@ module RippleKeycloak
148
134
  def delete(resource, body = {})
149
135
  self.class.delete_formatted(resource, body: body)
150
136
  end
151
-
152
- def search(type, value)
153
- get("#{type}?search=#{value}")
154
- end
155
-
156
- def find_by(type, field, value)
157
- results = search(type, value).parsed_response
158
- if results.is_a? Array
159
- results.each do |instance|
160
- return instance if instance[field] == value
161
- end
162
- end
163
- raise NotFoundError, "Object type: #{type}, field: #{field}, value: #{value}"
164
- end
165
137
  end
166
138
  end
File without changes
File without changes
File without changes
File without changes
@@ -13,10 +13,13 @@ module RippleKeycloak
13
13
  end
14
14
 
15
15
  def add_to_group(user_id, group_id)
16
- client.put("users/#{user_id}/groups/#{group_id}", {
17
- groupId: group_id,
18
- userId: user_id
19
- })
16
+ client.put(
17
+ "users/#{user_id}/groups/#{group_id}",
18
+ {
19
+ groupId: group_id,
20
+ userId: user_id
21
+ }
22
+ )
20
23
  end
21
24
 
22
25
  def remove_from_group(user_id, group_id)
@@ -33,7 +36,7 @@ module RippleKeycloak
33
36
  client.delete("users/#{user_id}/role-mappings/realm", [role])
34
37
  end
35
38
 
36
- def send_email(user_id, actions, lifespan: 86400, client_id: false, redirect_uri: false)
39
+ def send_email(user_id, actions, lifespan: 86_400, client_id: false, redirect_uri: false)
37
40
  url = "users/#{user_id}/execute-actions-email?"
38
41
  url += "?lifespan=#{lifespan}"
39
42
  url += "&client_id=#{client_id}" if client_id
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RippleKeycloak
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -27,4 +27,7 @@ Gem::Specification.new do |spec|
27
27
 
28
28
  spec.add_dependency('activesupport', '6.0.3.1')
29
29
  spec.add_dependency('httparty', '0.18.0')
30
+
31
+ spec.add_development_dependency('rspec', '3.9.0')
32
+ spec.add_development_dependency('rubocop', '0.85.1')
30
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ripple_keycloak
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hex Event Solutions Limited
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-16 00:00:00.000000000 Z
11
+ date: 2020-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.18.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 3.9.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.9.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.85.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.85.1
41
69
  description:
42
70
  email:
43
71
  - ruby@hexes.co.uk
@@ -45,6 +73,9 @@ executables: []
45
73
  extensions: []
46
74
  extra_rdoc_files: []
47
75
  files:
76
+ - ".github/workflows/bump-version.yml"
77
+ - ".github/workflows/gem-push.yml"
78
+ - ".github/workflows/lint-and-test.yml"
48
79
  - ".gitignore"
49
80
  - ".rspec"
50
81
  - ".rubocop.yml"