verikloak-pundit 0.2.0 → 0.2.2
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 +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +9 -1
- data/lib/verikloak/pundit/claim_utils.rb +28 -0
- data/lib/verikloak/pundit/configuration.rb +26 -40
- data/lib/verikloak/pundit/delegations.rb +29 -0
- data/lib/verikloak/pundit/helpers.rb +13 -19
- data/lib/verikloak/pundit/policy.rb +11 -20
- data/lib/verikloak/pundit/user_context.rb +81 -25
- data/lib/verikloak/pundit/version.rb +1 -1
- data/lib/verikloak/pundit.rb +11 -0
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 40f6167b3a558b93b98bcabbe529acc50b4ffef682d9fc02375ea85c8f9ce26f
|
|
4
|
+
data.tar.gz: 31ca32b4215cc022474e5f385a56f3c6b189137665cdb76b5f748842c12cdce2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7c270e29f9872f007ebd3863946cb665bc4d62973cfcf7e2f635533ae1e20eaba64511f474e7a33bb3dd6040a751fca2b25027db4457690bdafd9333c05cac1
|
|
7
|
+
data.tar.gz: 81887295612920fe124f1947e1ecc9a91143beda4097ece57015739bb1e28481d5027a2d75e1e77545f4e98c7b5c4cd5c2fab43e86c5a8b386c965dfbe0696ac
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.2.2] - 2025-09-28
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Expanded generator specs to cover pre-existing `application_policy.rb` files and verify directory creation semantics, reinforcing the install generator contract.
|
|
14
|
+
- Clarified the dummy generator base `desc` signature to mirror the Rails API and avoid warning noise in tests.
|
|
15
|
+
- Stubbed helper and policy spec deprecation warnings so suite output stays clean while still asserting the message payload.
|
|
16
|
+
|
|
17
|
+
## [0.2.1] - 2025-09-27
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- `Verikloak::Pundit.reset!` helper to restore default configuration, easing test teardown.
|
|
21
|
+
- `Verikloak::Pundit::Delegations` shared module consolidating role and permission helper methods.
|
|
22
|
+
- `Verikloak::Pundit::ClaimUtils` for consistent claim normalization across entry points.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- `UserContext` memoizes role lookups and caches mapped permissions to reduce repeated work inside policies.
|
|
26
|
+
- `UserContext` now normalizes inputs via `ClaimUtils` and supports symbolized permission comparison for mixed role map values.
|
|
27
|
+
- Configuration duplication derives from a unified `deep_dup`, ensuring hash keys are copied and nested structures remain isolated.
|
|
28
|
+
- README documents the new delegations module, configuration reset helper, and deprecation guidance.
|
|
29
|
+
|
|
10
30
|
## [0.2.0] - 2025-09-21
|
|
11
31
|
|
|
12
32
|
### Added
|
data/README.md
CHANGED
|
@@ -14,7 +14,7 @@ Pundit integration for the **Verikloak** family. This gem maps **Keycloak roles*
|
|
|
14
14
|
## Features
|
|
15
15
|
|
|
16
16
|
- **UserContext**: lightweight wrapper around JWT claims
|
|
17
|
-
- **
|
|
17
|
+
- **Delegations**: `has_role?`, `in_group?`, `resource_role?(client, role)` helpers for controllers and policies
|
|
18
18
|
- **RoleMapper**: optional map from Keycloak roles → domain permissions
|
|
19
19
|
- **Controller integration**: `pundit_user` provider for Rails controllers
|
|
20
20
|
- **Generator**: `rails g verikloak:pundit:install` creates initializer + policy template (with `has_permission?` support for realm roles plus the configured resource scope)
|
|
@@ -140,6 +140,14 @@ docker compose run --rm dev rspec
|
|
|
140
140
|
docker compose run --rm dev rubocop -a
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
+
When writing specs, call `Verikloak::Pundit.reset!` in your test teardown to ensure configuration changes do not leak between examples:
|
|
144
|
+
|
|
145
|
+
```ruby
|
|
146
|
+
RSpec.configure do |config|
|
|
147
|
+
config.after { Verikloak::Pundit.reset! }
|
|
148
|
+
end
|
|
149
|
+
```
|
|
150
|
+
|
|
143
151
|
An additional integration check exercises the gem together with the latest `verikloak` and `verikloak-rails` releases. This runs in CI automatically, and you can execute it locally with:
|
|
144
152
|
|
|
145
153
|
```bash
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verikloak
|
|
4
|
+
module Pundit
|
|
5
|
+
# Helpers for coercing incoming claims payloads into safe Hashes.
|
|
6
|
+
module ClaimUtils
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# Normalize incoming claims to a Hash to guard against odd payload types.
|
|
10
|
+
#
|
|
11
|
+
# @param claims [Object]
|
|
12
|
+
# @return [Hash]
|
|
13
|
+
def normalize(claims)
|
|
14
|
+
return {} if claims.nil?
|
|
15
|
+
return claims if claims.is_a?(Hash)
|
|
16
|
+
|
|
17
|
+
if claims.respond_to?(:to_hash)
|
|
18
|
+
coerced = claims.to_hash
|
|
19
|
+
return coerced if coerced.is_a?(Hash)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
{}
|
|
23
|
+
rescue StandardError
|
|
24
|
+
{}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -115,29 +115,33 @@ module Verikloak
|
|
|
115
115
|
dup_string(value).freeze
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
-
#
|
|
119
|
-
#
|
|
118
|
+
# Deep duplicate any object, handling nested structures recursively.
|
|
119
|
+
#
|
|
120
|
+
# @param value [Object] The value to duplicate
|
|
121
|
+
# @return [Object] A deep copy of the value
|
|
122
|
+
def deep_dup(value)
|
|
123
|
+
case value
|
|
124
|
+
when nil
|
|
125
|
+
nil
|
|
126
|
+
when Hash
|
|
127
|
+
value.each_with_object({}) do |(key, element), copy|
|
|
128
|
+
copy[deep_dup(key)] = deep_dup(element)
|
|
129
|
+
end
|
|
130
|
+
when Array
|
|
131
|
+
value.map { |element| deep_dup(element) }
|
|
132
|
+
when String
|
|
133
|
+
value.dup
|
|
134
|
+
else
|
|
135
|
+
duplicable?(value) ? value.dup : value
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Duplicate a hash using deep duplication.
|
|
120
140
|
#
|
|
121
141
|
# @param value [Hash, nil]
|
|
122
142
|
# @return [Hash, nil]
|
|
123
143
|
def dup_hash(value)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
copy = value.dup
|
|
127
|
-
copy.each do |key, element|
|
|
128
|
-
copy[key] =
|
|
129
|
-
case element
|
|
130
|
-
when Hash
|
|
131
|
-
dup_hash(element)
|
|
132
|
-
when Array
|
|
133
|
-
dup_array(element)
|
|
134
|
-
when String
|
|
135
|
-
dup_string(element)
|
|
136
|
-
else
|
|
137
|
-
duplicable?(element) ? element.dup : element
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
copy
|
|
144
|
+
deep_dup(value)
|
|
141
145
|
end
|
|
142
146
|
|
|
143
147
|
# Duplicate a string guardingly, returning `nil` when no value is present.
|
|
@@ -145,33 +149,15 @@ module Verikloak
|
|
|
145
149
|
# @param value [String, nil]
|
|
146
150
|
# @return [String, nil]
|
|
147
151
|
def dup_string(value)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
value.dup
|
|
152
|
+
deep_dup(value)
|
|
151
153
|
end
|
|
152
154
|
|
|
153
|
-
#
|
|
155
|
+
# Duplicate an array using deep duplication.
|
|
154
156
|
#
|
|
155
157
|
# @param value [Array, nil]
|
|
156
158
|
# @return [Array, nil]
|
|
157
159
|
def dup_array(value)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
copy = value.dup
|
|
161
|
-
return copy unless copy.respond_to?(:map)
|
|
162
|
-
|
|
163
|
-
copy.map do |element|
|
|
164
|
-
case element
|
|
165
|
-
when Hash
|
|
166
|
-
dup_hash(element)
|
|
167
|
-
when Array
|
|
168
|
-
dup_array(element)
|
|
169
|
-
when String
|
|
170
|
-
dup_string(element)
|
|
171
|
-
else
|
|
172
|
-
duplicable?(element) ? element.dup : element
|
|
173
|
-
end
|
|
174
|
-
end
|
|
160
|
+
deep_dup(value)
|
|
175
161
|
end
|
|
176
162
|
|
|
177
163
|
# Check whether a value can be safely duplicated using `dup`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verikloak
|
|
4
|
+
module Pundit
|
|
5
|
+
# Shared role/permission delegations to expose consistent helpers.
|
|
6
|
+
module Delegations
|
|
7
|
+
# Check whether the user has a realm role.
|
|
8
|
+
# @param role [String, Symbol]
|
|
9
|
+
# @return [Boolean]
|
|
10
|
+
def has_role?(role) = user.has_role?(role) # rubocop:disable Naming/PredicatePrefix
|
|
11
|
+
|
|
12
|
+
# Check whether the user belongs to a group (alias to role).
|
|
13
|
+
# @param group [String, Symbol]
|
|
14
|
+
# @return [Boolean]
|
|
15
|
+
def in_group?(group) = user.in_group?(group)
|
|
16
|
+
|
|
17
|
+
# Check whether the user has a role for a specific resource client.
|
|
18
|
+
# @param client [String, Symbol]
|
|
19
|
+
# @param role [String, Symbol]
|
|
20
|
+
# @return [Boolean]
|
|
21
|
+
def resource_role?(client, role) = user.resource_role?(client, role)
|
|
22
|
+
|
|
23
|
+
# Check whether the user has a mapped permission.
|
|
24
|
+
# @param perm [String, Symbol]
|
|
25
|
+
# @return [Boolean]
|
|
26
|
+
def has_permission?(perm) = user.has_permission?(perm) # rubocop:disable Naming/PredicatePrefix
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -3,27 +3,21 @@
|
|
|
3
3
|
module Verikloak
|
|
4
4
|
module Pundit
|
|
5
5
|
# Helpers expose convenient delegations to the policy `user`.
|
|
6
|
+
#
|
|
7
|
+
# @deprecated Use {Delegations} directly instead. This module will be removed in v1.0.0.
|
|
6
8
|
module Helpers
|
|
7
|
-
|
|
8
|
-
# @param role [String, Symbol]
|
|
9
|
-
# @return [Boolean]
|
|
10
|
-
def has_role?(role) = user.has_role?(role) # rubocop:disable Naming/PredicatePrefix
|
|
9
|
+
include Delegations
|
|
11
10
|
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# @
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# Check whether the user has a mapped permission.
|
|
24
|
-
# @param perm [String, Symbol]
|
|
25
|
-
# @return [Boolean]
|
|
26
|
-
def has_permission?(perm) = user.has_permission?(perm) # rubocop:disable Naming/PredicatePrefix
|
|
11
|
+
# Warn consumers when the deprecated helper module is included.
|
|
12
|
+
#
|
|
13
|
+
# @param base [Module] module or class including this helper
|
|
14
|
+
# @return [void]
|
|
15
|
+
def self.included(base)
|
|
16
|
+
warn '[DEPRECATED] Verikloak::Pundit::Helpers is deprecated. ' \
|
|
17
|
+
'Include Verikloak::Pundit::Delegations directly instead. ' \
|
|
18
|
+
'This will be removed in v1.0.0.'
|
|
19
|
+
super
|
|
20
|
+
end
|
|
27
21
|
end
|
|
28
22
|
end
|
|
29
23
|
end
|
|
@@ -3,34 +3,25 @@
|
|
|
3
3
|
module Verikloak
|
|
4
4
|
module Pundit
|
|
5
5
|
# Policy mixin to delegate common helpers to the `user` context.
|
|
6
|
+
#
|
|
7
|
+
# @deprecated Use {Delegations} directly instead. This module will be removed in v1.0.0.
|
|
6
8
|
module Policy
|
|
9
|
+
# Warn consumers when the deprecated policy mixin is included.
|
|
10
|
+
#
|
|
11
|
+
# @param base [Module] module or class including this policy mixin
|
|
12
|
+
# @return [void]
|
|
7
13
|
def self.included(base)
|
|
14
|
+
warn '[DEPRECATED] Verikloak::Pundit::Policy is deprecated. ' \
|
|
15
|
+
'Include Verikloak::Pundit::Delegations directly instead. ' \
|
|
16
|
+
'This will be removed in v1.0.0.'
|
|
8
17
|
base.extend(ClassMethods)
|
|
18
|
+
super
|
|
9
19
|
end
|
|
10
20
|
|
|
11
21
|
# Placeholder for future class-level helpers
|
|
12
22
|
module ClassMethods; end
|
|
13
23
|
|
|
14
|
-
|
|
15
|
-
# @param role [String, Symbol]
|
|
16
|
-
# @return [Boolean]
|
|
17
|
-
def has_role?(role) = user.has_role?(role) # rubocop:disable Naming/PredicatePrefix
|
|
18
|
-
|
|
19
|
-
# Check whether the user belongs to a group (alias to role).
|
|
20
|
-
# @param group [String, Symbol]
|
|
21
|
-
# @return [Boolean]
|
|
22
|
-
def in_group?(group) = user.in_group?(group)
|
|
23
|
-
|
|
24
|
-
# Check whether the user has a role for a specific resource client.
|
|
25
|
-
# @param client [String, Symbol]
|
|
26
|
-
# @param role [String, Symbol]
|
|
27
|
-
# @return [Boolean]
|
|
28
|
-
def resource_role?(client, role) = user.resource_role?(client, role)
|
|
29
|
-
|
|
30
|
-
# Check whether the user has a mapped permission.
|
|
31
|
-
# @param perm [String, Symbol]
|
|
32
|
-
# @return [Boolean]
|
|
33
|
-
def has_permission?(perm) = user.has_permission?(perm) # rubocop:disable Naming/PredicatePrefix
|
|
24
|
+
include Delegations
|
|
34
25
|
end
|
|
35
26
|
end
|
|
36
27
|
end
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'set'
|
|
4
|
+
|
|
3
5
|
module Verikloak
|
|
4
6
|
module Pundit
|
|
5
7
|
# Lightweight wrapper around Keycloak claims for Pundit policies.
|
|
6
8
|
class UserContext
|
|
9
|
+
# JWT claim keys used internally
|
|
10
|
+
CLAIM_SUB = 'sub'
|
|
11
|
+
CLAIM_EMAIL = 'email'
|
|
12
|
+
CLAIM_PREFERRED_USERNAME = 'preferred_username'
|
|
13
|
+
CLAIM_RESOURCE_ACCESS = 'resource_access'
|
|
14
|
+
CLAIM_ROLES = 'roles'
|
|
15
|
+
|
|
7
16
|
attr_reader :claims, :resource_client, :config
|
|
8
17
|
|
|
9
18
|
# Create a new user context from JWT claims.
|
|
@@ -13,27 +22,29 @@ module Verikloak
|
|
|
13
22
|
# @param config [Verikloak::Pundit::Configuration] configuration snapshot to use
|
|
14
23
|
def initialize(claims, resource_client: nil, config: nil)
|
|
15
24
|
@config = config || Verikloak::Pundit.config
|
|
16
|
-
@claims = claims
|
|
25
|
+
@claims = ClaimUtils.normalize(claims)
|
|
17
26
|
@resource_client = (resource_client || @config.resource_client).to_s
|
|
18
27
|
end
|
|
19
28
|
|
|
20
29
|
# Subject identifier from claims.
|
|
21
30
|
# @return [String, nil]
|
|
22
31
|
def sub
|
|
23
|
-
claims[
|
|
32
|
+
claims[CLAIM_SUB]
|
|
24
33
|
end
|
|
25
34
|
|
|
26
35
|
# Email or preferred username from claims.
|
|
27
36
|
# @return [String, nil]
|
|
28
37
|
def email
|
|
29
|
-
claims[
|
|
38
|
+
claims[CLAIM_EMAIL] || claims[CLAIM_PREFERRED_USERNAME]
|
|
30
39
|
end
|
|
31
40
|
|
|
32
41
|
# Realm-level roles from claims based on configuration path.
|
|
33
42
|
# @return [Array<String>]
|
|
34
43
|
def realm_roles
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
@realm_roles ||= begin
|
|
45
|
+
path = resolve_path(config.realm_roles_path)
|
|
46
|
+
Array(claims.dig(*path)).map(&:to_s).uniq.freeze
|
|
47
|
+
end
|
|
37
48
|
end
|
|
38
49
|
|
|
39
50
|
# Resource-level roles for a given client from claims based on configuration path.
|
|
@@ -42,8 +53,10 @@ module Verikloak
|
|
|
42
53
|
# @return [Array<String>]
|
|
43
54
|
def resource_roles(client = resource_client)
|
|
44
55
|
client = client.to_s
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
(@resource_roles_cache ||= {})[client] ||= begin
|
|
57
|
+
path = resolve_path(config.resource_roles_path, client: client)
|
|
58
|
+
Array(claims.dig(*path)).map(&:to_s).uniq.freeze
|
|
59
|
+
end
|
|
47
60
|
end
|
|
48
61
|
|
|
49
62
|
# Check whether the user has a realm role.
|
|
@@ -51,8 +64,7 @@ module Verikloak
|
|
|
51
64
|
# @param role [String, Symbol]
|
|
52
65
|
# @return [Boolean]
|
|
53
66
|
def has_role?(role) # rubocop:disable Naming/PredicatePrefix
|
|
54
|
-
|
|
55
|
-
realm_roles.include?(r)
|
|
67
|
+
realm_roles.include?(role.to_s)
|
|
56
68
|
end
|
|
57
69
|
|
|
58
70
|
# Alias to has_role? to align with group-based naming.
|
|
@@ -69,9 +81,7 @@ module Verikloak
|
|
|
69
81
|
# @param role [String, Symbol]
|
|
70
82
|
# @return [Boolean]
|
|
71
83
|
def resource_role?(client, role)
|
|
72
|
-
client
|
|
73
|
-
r = role.to_s
|
|
74
|
-
resource_roles(client).include?(r)
|
|
84
|
+
resource_roles(client).include?(role.to_s)
|
|
75
85
|
end
|
|
76
86
|
|
|
77
87
|
# Check whether the user has a mapped permission.
|
|
@@ -82,10 +92,7 @@ module Verikloak
|
|
|
82
92
|
# @param perm [String, Symbol] permission to check
|
|
83
93
|
# @return [Boolean]
|
|
84
94
|
def has_permission?(perm) # rubocop:disable Naming/PredicatePrefix
|
|
85
|
-
|
|
86
|
-
roles = realm_roles + resource_roles_scope
|
|
87
|
-
mapped = roles.map { |r| RoleMapper.map(r, config) }
|
|
88
|
-
mapped.map(&:to_sym).include?(pr)
|
|
95
|
+
permission_set.include?(normalize_to_symbol(perm))
|
|
89
96
|
end
|
|
90
97
|
|
|
91
98
|
# Build a user context from Rack env using configured claims key.
|
|
@@ -94,7 +101,7 @@ module Verikloak
|
|
|
94
101
|
# @return [UserContext]
|
|
95
102
|
def self.from_env(env)
|
|
96
103
|
config = Verikloak::Pundit.config
|
|
97
|
-
claims = env
|
|
104
|
+
claims = env&.fetch(config.env_claims_key, nil)
|
|
98
105
|
new(claims, config: config)
|
|
99
106
|
end
|
|
100
107
|
|
|
@@ -135,15 +142,18 @@ module Verikloak
|
|
|
135
142
|
# Collect resource roles from all clients under resource_access.
|
|
136
143
|
# @return [Array<String>]
|
|
137
144
|
def resource_roles_all_clients
|
|
138
|
-
|
|
139
|
-
|
|
145
|
+
@resource_roles_all_clients ||= begin
|
|
146
|
+
access = claims[CLAIM_RESOURCE_ACCESS]
|
|
147
|
+
if access.is_a?(Hash)
|
|
148
|
+
roles = access.each_with_object([]) do |(client_id, entry), acc|
|
|
149
|
+
next unless permission_client_allowed?(client_id)
|
|
140
150
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
151
|
+
acc.concat(Array(entry[CLAIM_ROLES]))
|
|
152
|
+
end
|
|
153
|
+
roles.map(&:to_s).uniq.freeze
|
|
154
|
+
else
|
|
155
|
+
[].freeze
|
|
156
|
+
end
|
|
147
157
|
end
|
|
148
158
|
end
|
|
149
159
|
|
|
@@ -157,6 +167,52 @@ module Verikloak
|
|
|
157
167
|
|
|
158
168
|
whitelist.include?(client_id.to_s)
|
|
159
169
|
end
|
|
170
|
+
|
|
171
|
+
# Cached permission lookup set combining realm and configured resource scopes.
|
|
172
|
+
# @return [Set<Symbol>]
|
|
173
|
+
def permission_set
|
|
174
|
+
@permission_set ||= build_permission_set.freeze
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Build the permission set from roles and role mappings.
|
|
178
|
+
# @return [Set<Symbol>]
|
|
179
|
+
def build_permission_set
|
|
180
|
+
roles = realm_roles + resource_roles_scope
|
|
181
|
+
permissions = Set.new
|
|
182
|
+
|
|
183
|
+
roles.each do |role|
|
|
184
|
+
mapped_permission = RoleMapper.map(role, config)
|
|
185
|
+
symbol_permission = normalize_to_symbol(mapped_permission)
|
|
186
|
+
permissions << symbol_permission if symbol_permission
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
permissions
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Normalize a value to a symbol, handling various types safely.
|
|
193
|
+
# @param value [Object] The value to convert to a symbol
|
|
194
|
+
# @return [Symbol, nil] The symbol representation, or nil if not convertible
|
|
195
|
+
def normalize_to_symbol(value)
|
|
196
|
+
case value
|
|
197
|
+
when Symbol
|
|
198
|
+
value
|
|
199
|
+
when String
|
|
200
|
+
return nil if value.empty?
|
|
201
|
+
|
|
202
|
+
value.to_sym
|
|
203
|
+
else
|
|
204
|
+
if value.respond_to?(:to_sym)
|
|
205
|
+
value.to_sym
|
|
206
|
+
elsif value.respond_to?(:to_s)
|
|
207
|
+
text = value.to_s
|
|
208
|
+
return nil if text.empty?
|
|
209
|
+
|
|
210
|
+
text.to_sym
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
rescue StandardError
|
|
214
|
+
nil
|
|
215
|
+
end
|
|
160
216
|
end
|
|
161
217
|
end
|
|
162
218
|
end
|
data/lib/verikloak/pundit.rb
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
require_relative 'pundit/version'
|
|
5
5
|
require_relative 'pundit/configuration'
|
|
6
6
|
require_relative 'pundit/role_mapper'
|
|
7
|
+
require_relative 'pundit/delegations'
|
|
8
|
+
require_relative 'pundit/claim_utils'
|
|
7
9
|
require_relative 'pundit/user_context'
|
|
8
10
|
require_relative 'pundit/helpers'
|
|
9
11
|
require_relative 'pundit/controller'
|
|
@@ -38,6 +40,15 @@ module Verikloak
|
|
|
38
40
|
end
|
|
39
41
|
end
|
|
40
42
|
|
|
43
|
+
# Reset configuration to defaults. Useful for test suites.
|
|
44
|
+
#
|
|
45
|
+
# @return [void]
|
|
46
|
+
def reset!
|
|
47
|
+
config_mutex.synchronize do
|
|
48
|
+
@config = nil
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
41
52
|
private
|
|
42
53
|
|
|
43
54
|
# Mutex protecting configuration reads/writes to maintain thread safety.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: verikloak-pundit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- taiyaky
|
|
@@ -49,7 +49,7 @@ dependencies:
|
|
|
49
49
|
requirements:
|
|
50
50
|
- - ">="
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
|
-
version: 0.
|
|
52
|
+
version: 0.2.0
|
|
53
53
|
- - "<"
|
|
54
54
|
- !ruby/object:Gem::Version
|
|
55
55
|
version: 1.0.0
|
|
@@ -59,7 +59,7 @@ dependencies:
|
|
|
59
59
|
requirements:
|
|
60
60
|
- - ">="
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: 0.
|
|
62
|
+
version: 0.2.0
|
|
63
63
|
- - "<"
|
|
64
64
|
- !ruby/object:Gem::Version
|
|
65
65
|
version: 1.0.0
|
|
@@ -77,8 +77,10 @@ files:
|
|
|
77
77
|
- lib/generators/verikloak/pundit/install/templates/initializer.rb
|
|
78
78
|
- lib/verikloak-pundit.rb
|
|
79
79
|
- lib/verikloak/pundit.rb
|
|
80
|
+
- lib/verikloak/pundit/claim_utils.rb
|
|
80
81
|
- lib/verikloak/pundit/configuration.rb
|
|
81
82
|
- lib/verikloak/pundit/controller.rb
|
|
83
|
+
- lib/verikloak/pundit/delegations.rb
|
|
82
84
|
- lib/verikloak/pundit/helpers.rb
|
|
83
85
|
- lib/verikloak/pundit/policy.rb
|
|
84
86
|
- lib/verikloak/pundit/railtie.rb
|
|
@@ -92,7 +94,7 @@ metadata:
|
|
|
92
94
|
source_code_uri: https://github.com/taiyaky/verikloak-pundit
|
|
93
95
|
changelog_uri: https://github.com/taiyaky/verikloak-pundit/blob/main/CHANGELOG.md
|
|
94
96
|
bug_tracker_uri: https://github.com/taiyaky/verikloak-pundit/issues
|
|
95
|
-
documentation_uri: https://rubydoc.info/gems/verikloak-pundit/0.2.
|
|
97
|
+
documentation_uri: https://rubydoc.info/gems/verikloak-pundit/0.2.2
|
|
96
98
|
rubygems_mfa_required: 'true'
|
|
97
99
|
rdoc_options: []
|
|
98
100
|
require_paths:
|