authproto 0.3.0.beta2 → 0.3.0.beta3
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 +19 -0
- data/README.md +108 -5
- data/examples/confidential_client/README.md +10 -0
- data/examples/confidential_client/app.rb +8 -7
- data/examples/confidential_client/scripts/generate_keys.rb +1 -1
- data/examples/minisky_console/Gemfile.lock +2 -2
- data/examples/minisky_console/README.md +20 -1
- data/examples/minisky_console/localhost.rb +5 -3
- data/examples/minisky_console/production.rb +9 -3
- data/lib/authproto/client.rb +73 -90
- data/lib/authproto/configuration.rb +37 -16
- data/lib/authproto/dpop/client.rb +105 -40
- data/lib/authproto/dpop/{key_manager.rb → key_set.rb} +54 -120
- data/lib/authproto/dpop/nonce_manager.rb +33 -20
- data/lib/authproto/dpop/proof_generator.rb +17 -32
- data/lib/authproto/dpop.rb +19 -0
- data/lib/authproto/http_helpers.rb +85 -0
- data/lib/authproto/metadata/authorization_server.rb +12 -6
- data/lib/authproto/metadata/client_metadata.rb +18 -5
- data/lib/authproto/metadata/resource_server.rb +4 -2
- data/lib/authproto/minisky.rb +36 -34
- data/lib/authproto/par/client.rb +22 -73
- data/lib/authproto/par/client_assertion.rb +47 -16
- data/lib/authproto/par/request.rb +4 -8
- data/lib/authproto/par.rb +2 -1
- data/lib/authproto/serialization/session.rb +31 -13
- data/lib/authproto/serialization/token_set.rb +1 -2
- data/lib/authproto/state/session.rb +66 -6
- data/lib/authproto/state/session_manager.rb +95 -21
- data/lib/authproto/state/token_set.rb +16 -16
- data/lib/authproto/state.rb +1 -1
- data/lib/authproto/storage/key_builder.rb +3 -11
- data/lib/authproto/storage/memory.rb +8 -2
- data/lib/authproto/token/refresh.rb +26 -59
- data/lib/authproto/validated_uri.rb +23 -0
- data/lib/authproto/version.rb +1 -1
- data/lib/authproto.rb +0 -1
- data/sig/authproto/client.rbs +5 -7
- data/sig/authproto/dependencies.rbs +2 -0
- data/sig/authproto/dpop/client.rbs +11 -4
- data/sig/authproto/dpop/{key_manager.rbs → key_set.rbs} +9 -11
- data/sig/authproto/dpop/nonce_manager.rbs +4 -4
- data/sig/authproto/dpop/proof_generator.rbs +5 -10
- data/sig/authproto/dpop.rbs +6 -0
- data/sig/authproto/http_helpers.rbs +7 -0
- data/sig/authproto/localhost_server.rbs +1 -1
- data/sig/authproto/metadata/authorization_server.rbs +1 -0
- data/sig/authproto/metadata/client_metadata.rbs +2 -1
- data/sig/authproto/metadata/resource_server.rbs +1 -0
- data/sig/authproto/minisky_oauth.rbs +5 -2
- data/sig/authproto/par/client.rbs +4 -8
- data/sig/authproto/par/client_assertion.rbs +4 -0
- data/sig/authproto/par/request.rbs +0 -9
- data/sig/authproto/state/session.rbs +10 -3
- data/sig/authproto/state/session_manager.rbs +8 -3
- data/sig/authproto/state/token_set.rbs +1 -2
- data/sig/authproto/storage/key_builder.rbs +1 -2
- data/sig/authproto/token/refresh.rbs +3 -4
- data/sig/authproto.rbs +5 -2
- metadata +14 -19
- data/.rspec +0 -1
- data/.rubocop.yml +0 -31
- data/.tm_properties +0 -1
- data/.yardopts +0 -5
- data/AGENTS.md +0 -80
- data/Rakefile +0 -8
- data/examples/confidential_client/.gitignore +0 -6
- data/examples/minisky_console/.gitignore +0 -2
- data/lib/authproto/serialization/dpop_key.rb +0 -38
- data/misc/yard_attributes.rb +0 -34
- data/sig/authproto/serialization/dpop_key.rbs +0 -14
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
module AuthProto
|
|
2
2
|
module DPoP
|
|
3
|
-
class
|
|
3
|
+
class KeySet
|
|
4
4
|
class KeyError < AuthProto::Error
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
CURVE: String
|
|
8
|
-
|
|
9
|
-
attr_reader keypair: JOSE::JWK
|
|
8
|
+
attr_reader key: JOSE::JWK
|
|
10
9
|
|
|
11
|
-
def initialize: (?JOSE::JWK?
|
|
12
|
-
def generate_keypair: () -> JOSE::JWK
|
|
10
|
+
def initialize: (?JOSE::JWK? key) -> void
|
|
13
11
|
def public_jwk: () -> json_object
|
|
14
|
-
def sign: (String data) -> JOSE::SignedBinary
|
|
15
12
|
def sign_segments: (Hash[String | Symbol, untyped] header, Hash[String | Symbol, untyped] payload) -> JOSE::SignedBinary
|
|
16
|
-
def
|
|
17
|
-
def
|
|
18
|
-
def to_jwk: (?include_private: bool) -> JOSE::Map
|
|
19
|
-
def self.from_jwk: (json_object | JOSE::Map jwk) -> KeyManager
|
|
13
|
+
def private_jwk: () -> json_object
|
|
14
|
+
def self.from_jwk: (json_object | JOSE::Map jwk) -> KeySet
|
|
20
15
|
|
|
21
16
|
private
|
|
22
|
-
def
|
|
17
|
+
def generate_keypair: () -> JOSE::JWK
|
|
18
|
+
def sign: (String data) -> JOSE::SignedBinary
|
|
19
|
+
def deep_stringify_keys: (untyped obj) -> untyped
|
|
20
|
+
def verify: (String signed_jws) -> bool
|
|
23
21
|
def validate_keypair: () -> void
|
|
24
22
|
end
|
|
25
23
|
end
|
|
@@ -7,13 +7,13 @@ module AuthProto
|
|
|
7
7
|
class NonceError < AuthProto::Error
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
DEFAULT_TTL: Integer
|
|
11
10
|
def initialize: (?ttl: Integer?) -> void
|
|
12
|
-
def update: (nonce: String, server_url: String) -> void
|
|
13
|
-
def get: (String
|
|
14
|
-
def clear: (String
|
|
11
|
+
def update: (nonce: String, server_url: String, session_id: String) -> void
|
|
12
|
+
def get: (server_url: String, session_id: String) -> String?
|
|
13
|
+
def clear: (server_url: String, session_id: String) -> bool
|
|
15
14
|
|
|
16
15
|
private
|
|
16
|
+
def validate_session_id: (String session_id) -> void
|
|
17
17
|
def normalize_server_url: (String url) -> String
|
|
18
18
|
def validate_inputs: (String nonce, String server_url) -> void
|
|
19
19
|
def validate_server_url: (String server_url) -> void
|
|
@@ -1,35 +1,30 @@
|
|
|
1
1
|
module AuthProto
|
|
2
2
|
module DPoP
|
|
3
3
|
class ProofGenerator
|
|
4
|
-
@key_manager: AuthProto::DPoP::KeyManager
|
|
5
|
-
|
|
6
4
|
class ProofError < AuthProto::Error
|
|
7
5
|
end
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def initialize: (AuthProto::DPoP::KeyManager key_manager) -> void
|
|
7
|
+
def initialize: () -> void
|
|
12
8
|
|
|
13
9
|
def generate: (
|
|
10
|
+
key_set: KeySet,
|
|
14
11
|
method: String,
|
|
15
12
|
uri: String,
|
|
16
13
|
?nonce: String?,
|
|
17
|
-
?access_token: String
|
|
18
|
-
?ath: bool?
|
|
14
|
+
?access_token: String?
|
|
19
15
|
) -> JOSE::SignedBinary
|
|
20
16
|
|
|
21
17
|
private
|
|
22
18
|
|
|
23
19
|
def validate_inputs: (String method, String uri) -> void
|
|
24
20
|
|
|
25
|
-
def build_header: () -> { typ: "dpop+jwt", alg: "ES256", jwk: Hash[String, untyped] }
|
|
21
|
+
def build_header: (KeySet key_set) -> { typ: "dpop+jwt", alg: "ES256", jwk: Hash[String, untyped] }
|
|
26
22
|
|
|
27
23
|
def build_payload: (
|
|
28
24
|
method: String,
|
|
29
25
|
uri: String,
|
|
30
26
|
?nonce: String?,
|
|
31
|
-
?access_token: String
|
|
32
|
-
?include_ath: bool?
|
|
27
|
+
?access_token: String?
|
|
33
28
|
) -> Hash[String, untyped]
|
|
34
29
|
|
|
35
30
|
def normalize_uri: (String uri) -> String
|
|
@@ -2,6 +2,7 @@ module AuthProto
|
|
|
2
2
|
module Metadata
|
|
3
3
|
# Handles and validates AT Protocol OAuth client metadata.
|
|
4
4
|
class ClientMetadata
|
|
5
|
+
extend HTTPHelpers
|
|
5
6
|
AUTH_METHOD_PRIVATE_KEY_JWT: String
|
|
6
7
|
AUTH_METHOD_NONE: String
|
|
7
8
|
SCOPE_PATTERN: Regexp
|
|
@@ -55,7 +56,7 @@ module AuthProto
|
|
|
55
56
|
|
|
56
57
|
def self.from_url: (String url) -> ClientMetadata
|
|
57
58
|
|
|
58
|
-
def self.from_localhost_url: (String url) -> ClientMetadata
|
|
59
|
+
private def self.from_localhost_url: (String url) -> ClientMetadata
|
|
59
60
|
|
|
60
61
|
def confidential?: () -> bool
|
|
61
62
|
|
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
# Additional methods mixed in from Minisky::Requests belong to the minisky gem.
|
|
3
3
|
class Minisky
|
|
4
4
|
class OAuthClient
|
|
5
|
+
include AuthProto::HTTPHelpers
|
|
5
6
|
MAX_NONCE_RETRIES: Integer
|
|
6
7
|
attr_reader host: String
|
|
7
8
|
attr_reader oauth_client: AuthProto::Client
|
|
8
9
|
attr_reader session_id: String?
|
|
9
10
|
|
|
10
|
-
def initialize: (String host, client_id: String, redirect_uri: String, ?metadata: AuthProto::json_object?, ?
|
|
11
|
+
def initialize: (String host, client_id: String, redirect_uri: String, ?metadata: AuthProto::json_object?, ?signing_key: (AuthProto::json_object | JOSE::JWK)?, ?session_id: String?) -> void
|
|
11
12
|
def config: () -> nil
|
|
12
13
|
def authorize: (?handle: String?, ?pds: String?, ?scope: String) -> AuthProto::authorization_result
|
|
13
|
-
def handle_callback: (
|
|
14
|
+
def handle_callback: (
|
|
15
|
+
code: String, state: String, iss: String, expected_session_id: String
|
|
16
|
+
) -> AuthProto::callback_result
|
|
14
17
|
def get_request: (String | URI::HTTP method, ?Hash[untyped, untyped]? params, ?auth: bool, ?headers: Hash[String, String]?) -> untyped
|
|
15
18
|
def post_request: (String | URI::HTTP method, ?untyped data, ?auth: bool, ?headers: Hash[String, String]?, ?params: Hash[untyped, untyped]?) -> untyped
|
|
16
19
|
def log_in: (*untyped args) -> bot
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
module AuthProto
|
|
2
2
|
module PAR
|
|
3
3
|
class Client
|
|
4
|
+
include HTTPHelpers
|
|
4
5
|
attr_reader authorization_server: Metadata::AuthorizationServer
|
|
5
6
|
attr_reader par_endpoint: String
|
|
6
7
|
attr_reader dpop_client: DPoP::Client
|
|
7
8
|
|
|
8
9
|
def initialize: (authorization_server: Metadata::AuthorizationServer, dpop_client: DPoP::Client) -> void
|
|
9
|
-
def submit: (Request request) -> Response
|
|
10
|
-
def extract_nonce: (http_response response) -> String
|
|
10
|
+
def submit: (Request request, session: State::Session) -> Response
|
|
11
11
|
def build_authorization_url: (request_uri: String, client_id: String) -> String
|
|
12
12
|
|
|
13
13
|
private
|
|
14
|
-
def make_request: (Request request) -> http_response
|
|
15
|
-
def build_headers: (Request request, String dpop_proof) -> Hash[String, String]
|
|
16
|
-
def requires_nonce?: (http_response response) -> bool
|
|
17
|
-
def store_nonce: (String nonce) -> void
|
|
18
|
-
def server_origin: () -> String
|
|
14
|
+
def make_request: (Request request, session: State::Session) -> http_response
|
|
19
15
|
def handle_error_response: (http_response response) -> bot
|
|
20
|
-
def
|
|
16
|
+
def handle_success_response: (http_response response) -> Response
|
|
21
17
|
end
|
|
22
18
|
end
|
|
23
19
|
end
|
|
@@ -3,9 +3,13 @@ module AuthProto
|
|
|
3
3
|
class ClientAssertion
|
|
4
4
|
class Error < AuthProto::Error
|
|
5
5
|
end
|
|
6
|
+
ALGORITHM: String
|
|
6
7
|
attr_reader signing_key: JOSE::JWK
|
|
7
8
|
def initialize: (client_id: String, signing_key: (json_object | JOSE::JWK)) -> void
|
|
8
9
|
def generate_jwt: (audience: String, ?lifetime: Integer) -> String
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
def validate_signing_key: ((json_object | JOSE::JWK) signing_key) -> JOSE::JWK
|
|
9
13
|
end
|
|
10
14
|
end
|
|
11
15
|
end
|
|
@@ -8,7 +8,6 @@ module AuthProto
|
|
|
8
8
|
@scope: String
|
|
9
9
|
@login_hint: String?
|
|
10
10
|
@nonce: String?
|
|
11
|
-
@dpop_proof: String?
|
|
12
11
|
@client_assertion: ClientAssertion?
|
|
13
12
|
|
|
14
13
|
class Configuration
|
|
@@ -19,7 +18,6 @@ module AuthProto
|
|
|
19
18
|
attr_accessor scope: String?
|
|
20
19
|
attr_accessor login_hint: String?
|
|
21
20
|
attr_accessor nonce: String?
|
|
22
|
-
attr_accessor dpop_proof: String?
|
|
23
21
|
attr_accessor client_assertion: ClientAssertion?
|
|
24
22
|
end
|
|
25
23
|
|
|
@@ -30,7 +28,6 @@ module AuthProto
|
|
|
30
28
|
attr_reader scope: String
|
|
31
29
|
attr_reader login_hint: String?
|
|
32
30
|
attr_reader nonce: String?
|
|
33
|
-
attr_reader dpop_proof: String?
|
|
34
31
|
attr_reader client_assertion: ClientAssertion?
|
|
35
32
|
|
|
36
33
|
def self.build: () { (Configuration) -> untyped } -> Request
|
|
@@ -43,16 +40,10 @@ module AuthProto
|
|
|
43
40
|
|
|
44
41
|
def build_params: (audience: String?) -> Hash[String, String]
|
|
45
42
|
|
|
46
|
-
def add_optional_params: (Hash[String, String] params) -> void
|
|
47
|
-
|
|
48
|
-
def add_client_auth_params: (Hash[String, String] params) -> void
|
|
49
|
-
|
|
50
43
|
def validate_request: () -> void
|
|
51
44
|
|
|
52
45
|
def validate_required_params: () -> void
|
|
53
46
|
|
|
54
|
-
def validate_scope: () -> void
|
|
55
|
-
|
|
56
47
|
def validate_client_auth: () -> void
|
|
57
48
|
end
|
|
58
49
|
end
|
|
@@ -4,8 +4,12 @@ module AuthProto
|
|
|
4
4
|
include MonitorMixin
|
|
5
5
|
|
|
6
6
|
attr_reader session_id: String
|
|
7
|
-
attr_reader state_token: String
|
|
7
|
+
attr_reader state_token: String?
|
|
8
|
+
attr_reader authorization_expires_at: Time?
|
|
8
9
|
attr_reader client_id: String
|
|
10
|
+
attr_reader dpop_key: DPoP::KeySet
|
|
11
|
+
attr_reader signing_key_id: String?
|
|
12
|
+
attr_reader signing_key_thumbprint: String?
|
|
9
13
|
attr_reader scope: String
|
|
10
14
|
attr_reader pkce_verifier: String
|
|
11
15
|
attr_reader pkce_challenge: String
|
|
@@ -13,12 +17,15 @@ module AuthProto
|
|
|
13
17
|
attr_reader did: String?
|
|
14
18
|
attr_reader tokens: TokenSet?
|
|
15
19
|
|
|
16
|
-
def initialize: (client_id: String, scope: String, ?auth_server: Metadata::AuthorizationServer?, ?did: String?) -> void
|
|
20
|
+
def initialize: (client_id: String, scope: String, ?auth_server: Metadata::AuthorizationServer?, ?did: String?, ?signing_key_id: String?, ?signing_key_thumbprint: String?, ?dpop_key: DPoP::KeySet, ?authorization_expires_at: Time?) -> void
|
|
21
|
+
def clear_state_token: () -> nil
|
|
17
22
|
def authorization_server=: (Metadata::AuthorizationServer server) -> Metadata::AuthorizationServer
|
|
18
23
|
def did=: (String did) -> String
|
|
19
24
|
def tokens=: (TokenSet tokens) -> String
|
|
20
25
|
def session_data: () -> AuthProto::session_data?
|
|
21
|
-
def
|
|
26
|
+
def pending?: () -> bool
|
|
27
|
+
def tokens_valid?: () -> bool
|
|
28
|
+
alias authorized? tokens_valid?
|
|
22
29
|
def renewable?: () -> bool
|
|
23
30
|
end
|
|
24
31
|
end
|
|
@@ -2,14 +2,19 @@ module AuthProto
|
|
|
2
2
|
module State
|
|
3
3
|
class SessionManager
|
|
4
4
|
@serializer: Serialization::Session
|
|
5
|
+
@supported_signing_keys: Hash[String, String]
|
|
5
6
|
|
|
6
|
-
def initialize: () -> void
|
|
7
|
-
def create_session: (client_id: String, scope: String, ?auth_server: Metadata::AuthorizationServer?, ?did: String?) -> Session
|
|
7
|
+
def initialize: (?supported_signing_keys: Hash[String, String]) -> void
|
|
8
|
+
def create_session: (client_id: String, scope: String, ?auth_server: Metadata::AuthorizationServer?, ?did: String?, ?signing_key_id: String?) -> Session
|
|
8
9
|
def update_session: (Session session) -> Session
|
|
10
|
+
def complete_authorization: (Session session) -> Session
|
|
9
11
|
def get_session: (String session_id) -> Session?
|
|
10
|
-
def
|
|
12
|
+
def get_session_by_state_token: (String? state) -> Session?
|
|
11
13
|
def delete_session: (String session_id) -> void
|
|
12
14
|
def cleanup_expired: () -> void
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
def session_ttl: (Session session) -> Integer?
|
|
13
18
|
end
|
|
14
19
|
end
|
|
15
20
|
end
|
|
@@ -3,14 +3,13 @@ module AuthProto
|
|
|
3
3
|
class TokenSet
|
|
4
4
|
@access_token: String
|
|
5
5
|
@refresh_token: String?
|
|
6
|
-
@token_type: String
|
|
7
6
|
@scope: String
|
|
8
7
|
@sub: String
|
|
9
8
|
@expires_at: Time
|
|
10
9
|
|
|
11
10
|
attr_reader access_token: String
|
|
12
11
|
attr_reader refresh_token: String?
|
|
13
|
-
|
|
12
|
+
def token_type: () -> "DPoP"
|
|
14
13
|
attr_reader scope: String
|
|
15
14
|
attr_reader expires_at: Time
|
|
16
15
|
attr_reader sub: String
|
|
@@ -5,8 +5,7 @@ module AuthProto
|
|
|
5
5
|
NAMESPACE_PREFIX: String
|
|
6
6
|
def self.session_key: (String id) -> String
|
|
7
7
|
def self.state_key: (String token) -> String
|
|
8
|
-
def self.nonce_key: (String server_url) -> String
|
|
9
|
-
def self.dpop_key: (String client_id) -> String
|
|
8
|
+
def self.nonce_key: (String session_id, String server_url) -> String
|
|
10
9
|
def self.lock_key: (String namespace, String id) -> String
|
|
11
10
|
|
|
12
11
|
private
|
|
@@ -17,6 +17,7 @@ module AuthProto
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
class Refresh
|
|
20
|
+
include HTTPHelpers
|
|
20
21
|
include MonitorMixin
|
|
21
22
|
MAX_RETRIES: Integer
|
|
22
23
|
BASE_DELAY: Integer
|
|
@@ -26,7 +27,7 @@ module AuthProto
|
|
|
26
27
|
attr_reader auth_server: Metadata::AuthorizationServer
|
|
27
28
|
attr_reader client_metadata: Metadata::ClientMetadata
|
|
28
29
|
|
|
29
|
-
def initialize: (session: State::Session, dpop_client: DPoP::Client, auth_server: Metadata::AuthorizationServer, client_metadata: Metadata::ClientMetadata, ?
|
|
30
|
+
def initialize: (session: State::Session, dpop_client: DPoP::Client, auth_server: Metadata::AuthorizationServer, client_metadata: Metadata::ClientMetadata, ?client_assertion: PAR::ClientAssertion?) -> void
|
|
30
31
|
def perform_refresh: () -> State::TokenSet
|
|
31
32
|
|
|
32
33
|
private
|
|
@@ -34,12 +35,10 @@ module AuthProto
|
|
|
34
35
|
def calculate_delay: () -> Float
|
|
35
36
|
def request_token_refresh: () -> State::TokenSet
|
|
36
37
|
def make_token_request: (State::Session session) -> http_response
|
|
37
|
-
def requires_dpop_nonce?: (http_response response) -> bool
|
|
38
|
-
def extract_dpop_nonce: (http_response response) -> String
|
|
39
38
|
def add_client_authentication: (Hash[Symbol, untyped] body) -> void
|
|
40
39
|
def handle_refresh_response: (http_response response) -> State::TokenSet
|
|
41
40
|
def process_successful_response: (http_response response) -> State::TokenSet
|
|
42
|
-
def
|
|
41
|
+
def handle_error_response: (http_response response) -> bot
|
|
43
42
|
def handle_rate_limit_response: (http_response response) -> bot
|
|
44
43
|
def validate_refresh_response: (json_object data) -> void
|
|
45
44
|
end
|
data/sig/authproto.rbs
CHANGED
|
@@ -34,16 +34,19 @@ module AuthProto
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
class Configuration
|
|
37
|
-
attr_accessor
|
|
37
|
+
attr_accessor client_assertion_lifetime: Integer
|
|
38
38
|
attr_accessor dpop_nonce_lifetime: Integer
|
|
39
|
-
attr_accessor encryption: untyped
|
|
40
39
|
attr_accessor http_client: _HTTPClient?
|
|
41
40
|
attr_accessor logger: Logger
|
|
41
|
+
attr_accessor pending_session_ttl: Integer
|
|
42
42
|
attr_accessor storage: Storage::Interface
|
|
43
43
|
def initialize: () -> void
|
|
44
44
|
def validate: () -> true
|
|
45
45
|
|
|
46
46
|
private
|
|
47
|
+
def validate_client_assertion_lifetime: () -> void
|
|
48
|
+
def validate_dpop_nonce_lifetime: () -> void
|
|
49
|
+
def validate_pending_session_ttl: () -> void
|
|
47
50
|
def validate_storage: () -> void
|
|
48
51
|
def validate_http_client: () -> void
|
|
49
52
|
end
|
metadata
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: authproto
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.0.
|
|
4
|
+
version: 0.3.0.beta3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Josh Huckabee
|
|
8
8
|
- Kuba Suder
|
|
9
|
-
bindir:
|
|
9
|
+
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
@@ -55,21 +55,16 @@ dependencies:
|
|
|
55
55
|
description: A Ruby library for implementing AT Protocol OAuth flows, including DPoP,
|
|
56
56
|
PAR, and dynamic client registration. Supports both client and server-side implementations
|
|
57
57
|
with comprehensive security features.
|
|
58
|
+
email:
|
|
59
|
+
- jakub.suder@gmail.com
|
|
58
60
|
executables: []
|
|
59
61
|
extensions: []
|
|
60
62
|
extra_rdoc_files: []
|
|
61
63
|
files:
|
|
62
|
-
- ".rspec"
|
|
63
|
-
- ".rubocop.yml"
|
|
64
|
-
- ".tm_properties"
|
|
65
|
-
- ".yardopts"
|
|
66
|
-
- AGENTS.md
|
|
67
64
|
- CHANGELOG.md
|
|
68
65
|
- MIT-LICENSE.txt
|
|
69
66
|
- README.md
|
|
70
|
-
- Rakefile
|
|
71
67
|
- SECURITY.md
|
|
72
|
-
- examples/confidential_client/.gitignore
|
|
73
68
|
- examples/confidential_client/Gemfile
|
|
74
69
|
- examples/confidential_client/Gemfile.lock
|
|
75
70
|
- examples/confidential_client/README.md
|
|
@@ -83,7 +78,6 @@ files:
|
|
|
83
78
|
- examples/confidential_client/views/authorized.erb
|
|
84
79
|
- examples/confidential_client/views/index.erb
|
|
85
80
|
- examples/confidential_client/views/layout.erb
|
|
86
|
-
- examples/minisky_console/.gitignore
|
|
87
81
|
- examples/minisky_console/Gemfile
|
|
88
82
|
- examples/minisky_console/Gemfile.lock
|
|
89
83
|
- examples/minisky_console/README.md
|
|
@@ -95,14 +89,16 @@ files:
|
|
|
95
89
|
- lib/authproto.rb
|
|
96
90
|
- lib/authproto/client.rb
|
|
97
91
|
- lib/authproto/configuration.rb
|
|
92
|
+
- lib/authproto/dpop.rb
|
|
98
93
|
- lib/authproto/dpop/client.rb
|
|
99
|
-
- lib/authproto/dpop/
|
|
94
|
+
- lib/authproto/dpop/key_set.rb
|
|
100
95
|
- lib/authproto/dpop/nonce_manager.rb
|
|
101
96
|
- lib/authproto/dpop/proof_generator.rb
|
|
102
97
|
- lib/authproto/dpop/stored_nonce.rb
|
|
103
98
|
- lib/authproto/encryption.rb
|
|
104
99
|
- lib/authproto/errors.rb
|
|
105
100
|
- lib/authproto/http_client.rb
|
|
101
|
+
- lib/authproto/http_helpers.rb
|
|
106
102
|
- lib/authproto/insecure_http_client.rb
|
|
107
103
|
- lib/authproto/localhost_server.rb
|
|
108
104
|
- lib/authproto/metadata.rb
|
|
@@ -117,7 +113,6 @@ files:
|
|
|
117
113
|
- lib/authproto/par/response.rb
|
|
118
114
|
- lib/authproto/pkce.rb
|
|
119
115
|
- lib/authproto/serialization/base.rb
|
|
120
|
-
- lib/authproto/serialization/dpop_key.rb
|
|
121
116
|
- lib/authproto/serialization/session.rb
|
|
122
117
|
- lib/authproto/serialization/stored_nonce.rb
|
|
123
118
|
- lib/authproto/serialization/token_set.rb
|
|
@@ -133,17 +128,18 @@ files:
|
|
|
133
128
|
- lib/authproto/token/refresh.rb
|
|
134
129
|
- lib/authproto/validated_uri.rb
|
|
135
130
|
- lib/authproto/version.rb
|
|
136
|
-
- misc/yard_attributes.rb
|
|
137
131
|
- sig/authproto.rbs
|
|
138
132
|
- sig/authproto/client.rbs
|
|
139
133
|
- sig/authproto/dependencies.rbs
|
|
134
|
+
- sig/authproto/dpop.rbs
|
|
140
135
|
- sig/authproto/dpop/client.rbs
|
|
141
|
-
- sig/authproto/dpop/
|
|
136
|
+
- sig/authproto/dpop/key_set.rbs
|
|
142
137
|
- sig/authproto/dpop/nonce_manager.rbs
|
|
143
138
|
- sig/authproto/dpop/proof_generator.rbs
|
|
144
139
|
- sig/authproto/dpop/stored_nonce.rbs
|
|
145
140
|
- sig/authproto/encryption.rbs
|
|
146
141
|
- sig/authproto/http_client.rbs
|
|
142
|
+
- sig/authproto/http_helpers.rbs
|
|
147
143
|
- sig/authproto/insecure_http_client.rbs
|
|
148
144
|
- sig/authproto/localhost_server.rbs
|
|
149
145
|
- sig/authproto/metadata/authorization_server.rbs
|
|
@@ -157,7 +153,6 @@ files:
|
|
|
157
153
|
- sig/authproto/par/response.rbs
|
|
158
154
|
- sig/authproto/pkce.rbs
|
|
159
155
|
- sig/authproto/serialization/base.rbs
|
|
160
|
-
- sig/authproto/serialization/dpop_key.rbs
|
|
161
156
|
- sig/authproto/serialization/session.rbs
|
|
162
157
|
- sig/authproto/serialization/stored_nonce.rbs
|
|
163
158
|
- sig/authproto/serialization/token_set.rbs
|
|
@@ -174,13 +169,13 @@ files:
|
|
|
174
169
|
- sig/authproto/token/refresh.rbs
|
|
175
170
|
- sig/authproto/validated_uri.rbs
|
|
176
171
|
- sig/authproto/version.rbs
|
|
177
|
-
homepage: https://
|
|
172
|
+
homepage: https://tangled.org/mackuba.eu/authproto
|
|
178
173
|
licenses:
|
|
179
174
|
- MIT
|
|
180
175
|
metadata:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
176
|
+
bug_tracker_uri: https://tangled.org/mackuba.eu/authproto/issues
|
|
177
|
+
changelog_uri: https://tangled.org/mackuba.eu/authproto/blob/master/CHANGELOG.md
|
|
178
|
+
source_code_uri: https://tangled.org/mackuba.eu/authproto
|
|
184
179
|
rubygems_mfa_required: 'true'
|
|
185
180
|
rdoc_options: []
|
|
186
181
|
require_paths:
|
data/.rspec
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
--require spec_helper
|
data/.rubocop.yml
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
AllCops:
|
|
2
|
-
NewCops: enable
|
|
3
|
-
SuggestExtensions: false
|
|
4
|
-
TargetRubyVersion: 3.2
|
|
5
|
-
|
|
6
|
-
Metrics/BlockLength:
|
|
7
|
-
Enabled: false
|
|
8
|
-
|
|
9
|
-
Metrics/ClassLength:
|
|
10
|
-
Enabled: false
|
|
11
|
-
|
|
12
|
-
Metrics/ModuleLength:
|
|
13
|
-
Enabled: false
|
|
14
|
-
|
|
15
|
-
Metrics/MethodLength:
|
|
16
|
-
Enabled: false
|
|
17
|
-
|
|
18
|
-
Metrics/AbcSize:
|
|
19
|
-
Enabled: false
|
|
20
|
-
|
|
21
|
-
Metrics/PerceivedComplexity:
|
|
22
|
-
Enabled: false
|
|
23
|
-
|
|
24
|
-
Metrics/CyclomaticComplexity:
|
|
25
|
-
Enabled: false
|
|
26
|
-
|
|
27
|
-
Style/StringLiterals:
|
|
28
|
-
EnforcedStyle: double_quotes
|
|
29
|
-
|
|
30
|
-
Style/StringLiteralsInInterpolation:
|
|
31
|
-
EnforcedStyle: double_quotes
|
data/.tm_properties
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
excludeInFolderSearch = "{$excludeInFolderSearch,coverage,doc}"
|
data/.yardopts
DELETED
data/AGENTS.md
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
### Ruby code:
|
|
2
|
-
|
|
3
|
-
- always add `# frozen_string_literal: true` at the beginning of Ruby files (both library and tests)
|
|
4
|
-
- keep `require`s and `require_relative`s organized in separate blocks, ordered alphabetically in each:
|
|
5
|
-
|
|
6
|
-
```
|
|
7
|
-
require 'ipaddr'
|
|
8
|
-
require 'socket'
|
|
9
|
-
require 'timeout'
|
|
10
|
-
require 'uri'
|
|
11
|
-
|
|
12
|
-
require_relative 'client_metadata'
|
|
13
|
-
require_relative 'validated_uri'
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
- wrap lines longer than 120 characters
|
|
17
|
-
- for multi-line `if ... end` / `unless ... end` blocks, keep one empty line above/below separating them from the rest of the code in the method, unless it's at the beginning/end of the method, e.g.:
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
def validate_grant_types(grant_types)
|
|
21
|
-
unless grant_types.include?('authorization_code')
|
|
22
|
-
raise InvalidClientMetadata, "grant_types must include authorization_code"
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
valid_types = %w[authorization_code refresh_token]
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
- prefer single-quote strings for strings containing identifiers without spaces, like `'code'`, `'access_token'`, and for `require`s
|
|
29
|
-
- prefer double-quote strings for strings containing messages with spaces meant to be shown to the user, e.g. `puts "grant_types must include authorization_code"`
|
|
30
|
-
|
|
31
|
-
### Unit tests:
|
|
32
|
-
|
|
33
|
-
- use the classic RSpec `foo.should be_...` matcher style instead of `expect()`
|
|
34
|
-
- except for calling matchers on blocks as in `expect { ... }.to(not) raise_error...`
|
|
35
|
-
- use the classic `it "should do this"` naming for test cases instead of `it "does this"`
|
|
36
|
-
- use raw `describe` instead of `RSpec.describe` at the top level
|
|
37
|
-
|
|
38
|
-
### Documentation:
|
|
39
|
-
|
|
40
|
-
- use YARD with Markdown formatting
|
|
41
|
-
- for class comments, keep one empty # line at the beginning and end, and one empty line above and below that, like:
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
#
|
|
46
|
-
# OAuth client implementation class.
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
class ...
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
- for method comments, leave one empty line above, no empty # starting line, and one empty # trailing line that is immediately followed by the method definition, like:
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
# Reads tokens for a session with a currently valid access token.
|
|
57
|
-
#
|
|
58
|
-
# @param session_id [String] session identifier
|
|
59
|
-
# @return [Hash{Symbol => String, Integer, nil}, nil] token details, or `nil` for missing/unauthorized sessions
|
|
60
|
-
#
|
|
61
|
-
def get_tokens(session_id)
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
- for properties, and also for one-liner classes like error types, use a compact style like:
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
# Identifier of the session associated with the failure, if known.
|
|
69
|
-
# @return [String, nil]
|
|
70
|
-
attr_reader :session_id
|
|
71
|
-
|
|
72
|
-
# Error raised when token operations fail
|
|
73
|
-
class TokenError < Error; end
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
### Running code:
|
|
79
|
-
|
|
80
|
-
- make sure you don't use the ancient system Ruby 2.6, but a version supported by the library (my installation uses `asdf`)
|
data/Rakefile
DELETED