identizer 0.1.0 → 0.1.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 +4 -4
- data/CHANGELOG.md +13 -2
- data/lib/identizer/cli.rb +7 -2
- data/lib/identizer/configuration.rb +5 -4
- data/lib/identizer/handlers/base.rb +6 -11
- data/lib/identizer/handlers/oidc.rb +3 -3
- data/lib/identizer/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 35ee37820b54d6bbc2d8749adef4f8e464fdc579556019502998db7e75c6b12c
|
|
4
|
+
data.tar.gz: 3fdf1b5c9ef7f9ae6b17d9e817201e885810cf835a5eda89fca703ee716fa344
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 40372939cb3c487b517fc9ff87a0114e93537f5acdf02854f849ec68f42d30dd9ff34dac631060e91ba1abc60c6152d127b6b0b7ffaf30a7b82d1af9e772d213
|
|
7
|
+
data.tar.gz: bc9c93f7492f2947e01a6db13655795bae3557d4d5310c8824259842ef888745703a4dbc9247fd30add059c46d918a32d70789cce9be6f1735dd685ecbdaf043
|
data/CHANGELOG.md
CHANGED
|
@@ -6,10 +6,20 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.1.1] - 2026-07-21
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Token endpoints now read `code_verifier`, `grant_type`, `refresh_token` and
|
|
13
|
+
`client_id` from a JSON request body, not just form-encoded params. PKCE
|
|
14
|
+
exchanges and refresh-token grants sent as JSON (what the Auth0 SDKs do)
|
|
15
|
+
returned `invalid_grant`.
|
|
16
|
+
- `--password` and `--rs256` are no longer overridden by settings previously
|
|
17
|
+
saved from the web admin; an explicit flag now wins, as documented.
|
|
18
|
+
|
|
9
19
|
## [0.1.0] - 2026-06-27
|
|
10
20
|
|
|
11
21
|
First release. A local identity provider for developing and testing auth/SSO
|
|
12
|
-
integrations
|
|
22
|
+
integrations.
|
|
13
23
|
|
|
14
24
|
### OIDC / OAuth2
|
|
15
25
|
- Authorization-code flow with PKCE (S256/plain), refresh-token grant (rotated,
|
|
@@ -44,5 +54,6 @@ integrations, extracted and decoupled from the tap-v3 SSO emulator.
|
|
|
44
54
|
enforcement; registered JWT claims protected from directory-attribute forging.
|
|
45
55
|
- `nokogiri` (SAML) and `net-ldap` (LDAP) load lazily; `sqlite3` is optional.
|
|
46
56
|
|
|
47
|
-
[Unreleased]: https://github.com/alex-andreiev/identizer/compare/v0.1.
|
|
57
|
+
[Unreleased]: https://github.com/alex-andreiev/identizer/compare/v0.1.1...HEAD
|
|
58
|
+
[0.1.1]: https://github.com/alex-andreiev/identizer/compare/v0.1.0...v0.1.1
|
|
48
59
|
[0.1.0]: https://github.com/alex-andreiev/identizer/releases/tag/v0.1.0
|
data/lib/identizer/cli.rb
CHANGED
|
@@ -15,6 +15,7 @@ module Identizer
|
|
|
15
15
|
def initialize(argv)
|
|
16
16
|
@argv = argv
|
|
17
17
|
@demo = true
|
|
18
|
+
@explicit = [] # settings given as flags; they outrank the persisted ones
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def run
|
|
@@ -27,7 +28,7 @@ module Identizer
|
|
|
27
28
|
# starting the server. Separated out so it can be exercised in tests.
|
|
28
29
|
def configure(config = Identizer.configuration)
|
|
29
30
|
parser(config).parse!(@argv)
|
|
30
|
-
config.apply_persisted_settings! # web-admin saved password/signing
|
|
31
|
+
config.apply_persisted_settings!(except: @explicit) # web-admin saved password/signing
|
|
31
32
|
config.seed_identities = [DEMO_USER] if @demo && config.seed_identities.empty?
|
|
32
33
|
load_sqlite(config) if config.sqlite_path
|
|
33
34
|
config
|
|
@@ -69,11 +70,15 @@ module Identizer
|
|
|
69
70
|
opts.on("--tls-key PATH", "TLS private key (PEM)") { |value| config.tls_key_path = value }
|
|
70
71
|
opts.on("--password PASS", "Shared sign-in password (default 'password')") do |value|
|
|
71
72
|
config.shared_password = value
|
|
73
|
+
@explicit << :shared_password
|
|
72
74
|
end
|
|
73
75
|
opts.on("--sqlite PATH", "Use a SQLite-backed directory at PATH (needs the sqlite3 gem)") do |value|
|
|
74
76
|
config.sqlite_path = value
|
|
75
77
|
end
|
|
76
|
-
opts.on("--rs256", "Sign id_tokens with RS256 + publish JWKS")
|
|
78
|
+
opts.on("--rs256", "Sign id_tokens with RS256 + publish JWKS") do
|
|
79
|
+
config.signing = :rs256
|
|
80
|
+
@explicit << :signing
|
|
81
|
+
end
|
|
77
82
|
opts.on("--no-demo", "Don't seed the demo user on first run") { @demo = false }
|
|
78
83
|
opts.on("--quiet", "Don't log requests") { config.request_logging = false }
|
|
79
84
|
opts.on("--ldap-port PORT", Integer, "Also start an LDAP listener on PORT") { |value| config.ldap_port = value }
|
|
@@ -140,11 +140,12 @@ module Identizer
|
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
# Apply settings previously saved from the web admin (password, signing mode).
|
|
143
|
-
# Called at boot
|
|
144
|
-
|
|
143
|
+
# Called at boot. `except` names the settings given explicitly on the command
|
|
144
|
+
# line — those always win, so a saved value can never shadow a flag.
|
|
145
|
+
def apply_persisted_settings!(except: [])
|
|
145
146
|
data = JSON.parse(File.read(settings_path))
|
|
146
|
-
self.shared_password = data["shared_password"] if data["shared_password"]
|
|
147
|
-
self.signing = data["signing"].to_sym if data["signing"]
|
|
147
|
+
self.shared_password = data["shared_password"] if data["shared_password"] && !except.include?(:shared_password)
|
|
148
|
+
self.signing = data["signing"].to_sym if data["signing"] && !except.include?(:signing)
|
|
148
149
|
self
|
|
149
150
|
rescue StandardError
|
|
150
151
|
self
|
|
@@ -42,23 +42,18 @@ module Identizer
|
|
|
42
42
|
# Consume a one-time authorization code and enforce PKCE when a challenge
|
|
43
43
|
# was issued — uniformly, so a code can't be redeemed at a different token
|
|
44
44
|
# endpoint to skip the check. Returns the Authorization, or nil if the code
|
|
45
|
-
# is unknown or PKCE verification fails.
|
|
45
|
+
# is unknown or PKCE verification fails. Reads both the code and the
|
|
46
|
+
# verifier from the same merged view, so form- and JSON-encoded token
|
|
47
|
+
# requests behave identically (the Auth0 SDKs POST JSON).
|
|
46
48
|
def redeem_code(request)
|
|
47
|
-
|
|
49
|
+
params = merged_params(request)
|
|
50
|
+
authorization = consume(params["code"])
|
|
48
51
|
return nil if authorization.nil?
|
|
49
|
-
return nil unless authorization.pkce_valid?(
|
|
52
|
+
return nil unless authorization.pkce_valid?(params["code_verifier"])
|
|
50
53
|
|
|
51
54
|
authorization
|
|
52
55
|
end
|
|
53
56
|
|
|
54
|
-
def code_param(request)
|
|
55
|
-
if json_request?(request)
|
|
56
|
-
parse_json(request)["code"]
|
|
57
|
-
else
|
|
58
|
-
request.params["code"]
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
57
|
def bearer(request)
|
|
63
58
|
request.get_header("HTTP_AUTHORIZATION").to_s.sub(/\ABearer\s+/i, "")
|
|
64
59
|
end
|
|
@@ -6,7 +6,7 @@ module Identizer
|
|
|
6
6
|
# discovery and JWKS documents, and the end-session (logout) endpoint.
|
|
7
7
|
class Oidc < Base
|
|
8
8
|
def token(request)
|
|
9
|
-
case request
|
|
9
|
+
case merged_params(request)["grant_type"]
|
|
10
10
|
when "refresh_token" then refresh(request)
|
|
11
11
|
else authorization_code(request)
|
|
12
12
|
end
|
|
@@ -75,7 +75,7 @@ module Identizer
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def refresh(request)
|
|
78
|
-
authorization = refresh_tokens.take(request
|
|
78
|
+
authorization = refresh_tokens.take(merged_params(request)["refresh_token"]) # single-use, rotated
|
|
79
79
|
return json(400, { error: "invalid_grant" }) if authorization.nil?
|
|
80
80
|
|
|
81
81
|
issue(authorization)
|
|
@@ -106,7 +106,7 @@ module Identizer
|
|
|
106
106
|
def valid_client?(request)
|
|
107
107
|
return true if config.clients.empty?
|
|
108
108
|
|
|
109
|
-
config.clients.any? { |client| client[:client_id] == request
|
|
109
|
+
config.clients.any? { |client| client[:client_id] == merged_params(request)["client_id"] }
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
end
|
data/lib/identizer/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: identizer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Andreiev
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-07-21 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: jwt
|