-
Notifications
You must be signed in to change notification settings - Fork 0
chore: move resources and auth classes into dedicated files #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
itsoyou
merged 8 commits into
main
from
syk/remove-some-bits-from-the-config-and-utils-junk-drawer
Aug 18, 2026
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
7d7e63c
chore: move resources and auth classes into dedicated files
itsoyou 754a582
chore: add tests for http_auth.py
itsoyou 1e33a76
chore: add coerce in dataclass config
itsoyou dc7562a
chore: contruct Auth with remaining mapping
itsoyou 482aaff
chore: remove coerce_http_auth
itsoyou addc042
chore: add logging context for auth config
itsoyou c2832bf
chore: add comment about keyError and indexError
itsoyou edaac4e
chore: update comment
itsoyou File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| import logging | ||
| from base64 import b64encode | ||
| from typing import TypeAlias | ||
|
|
||
| from pydantic import BaseModel, ConfigDict | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| class NoAuth(BaseModel): | ||
| model_config = ConfigDict(frozen=True, extra="forbid", strict=True) | ||
|
|
||
| def header_map(self) -> dict[bytes, list[bytes]]: | ||
| return {} | ||
|
|
||
|
|
||
| class BasicAuth(BaseModel): | ||
| model_config = ConfigDict(frozen=True, extra="forbid", strict=True) | ||
|
|
||
| username: str | ||
| password: str | ||
|
|
||
| def header_map(self) -> dict[bytes, list[bytes]]: | ||
| token = b64encode( | ||
| b":".join((self.username.encode("utf-8"), self.password.encode("utf-8"))) | ||
| ) | ||
| return {b"Authorization": [b"Basic " + token]} | ||
|
|
||
|
|
||
| class BearerAuth(BaseModel): | ||
| model_config = ConfigDict(frozen=True, extra="forbid", strict=True) | ||
|
|
||
| token: str | ||
|
|
||
| def header_map(self) -> dict[bytes, list[bytes]]: | ||
| return {b"Authorization": [b"Bearer " + self.token.encode("utf-8")]} | ||
|
|
||
|
|
||
| HttpAuth: TypeAlias = NoAuth | BasicAuth | BearerAuth | ||
|
|
||
|
|
||
| def parse_dict_auth(value: dict) -> HttpAuth: | ||
| auth_type = value.pop("type") | ||
|
jason-famedly marked this conversation as resolved.
jason-famedly marked this conversation as resolved.
|
||
| # Declaring the auth block without a 'type' parameter is an error and should raise | ||
| # the KeyError. If a user don't want to use authentication system, they should not | ||
| # include the auth block at all. | ||
| if auth_type is None: | ||
| return NoAuth() | ||
| if auth_type == "basic": | ||
| return BasicAuth(**value) | ||
| if auth_type == "bearer": | ||
| return BearerAuth(**value) | ||
| raise Exception(f"Unknown HttpAuth type '{auth_type}'") | ||
|
|
||
|
|
||
| def parse_list_auth(value: list) -> HttpAuth: | ||
| auth_type = value.pop(0) | ||
|
jason-famedly marked this conversation as resolved.
|
||
| # Declaring the auth block without a 'type' information is an error and should | ||
| # raise the IndexError. If a user don't want to use authentication system, they | ||
| # should not include the auth block at all. | ||
| if auth_type is None: | ||
| return NoAuth() | ||
| if auth_type == "basic": | ||
| if len(value) != 2: | ||
| raise Exception("BasicAuth expects username and password") | ||
| return BasicAuth(username=value[0], password=value[1]) | ||
| if auth_type == "bearer": | ||
| if len(value) != 1: | ||
| raise Exception("BearerAuth expects a single token") | ||
| return BearerAuth(token=value[0]) | ||
| raise Exception(f"Unknown HttpAuth type '{auth_type}'") | ||
|
|
||
|
|
||
| def parse_auth( | ||
| value: dict | list | HttpAuth, *, context: str | None = None | ||
| ) -> HttpAuth: | ||
| if isinstance(value, (NoAuth, BasicAuth, BearerAuth)): | ||
| return value | ||
| try: | ||
| if isinstance(value, dict): | ||
| return parse_dict_auth(value) | ||
| if isinstance(value, list): | ||
| return parse_list_auth(value) | ||
| raise Exception("HttpAuth parsing failed, expected list or dict") | ||
| except Exception as e: | ||
| if context: | ||
| logger.error("%s: HttpAuth configuration error: %s", context, e) | ||
| else: | ||
| logger.error("HttpAuth configuration error: %s", e) | ||
| raise e from e | ||
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import json | ||
| from urllib.parse import urljoin | ||
|
|
||
| from twisted.web import resource | ||
|
|
||
| from synapse_token_authenticator.config import ( | ||
| OIDCConfig, | ||
| ) | ||
|
|
||
|
|
||
| class LoginMetadataResource(resource.Resource): | ||
| def __init__(self, oidc_config: OIDCConfig): | ||
| self.issuer = oidc_config.issuer | ||
| self.metadata_url = urljoin( | ||
| oidc_config.issuer, "/.well-known/openid-configuration" | ||
| ) | ||
| self.organization_id = oidc_config.organization_id | ||
| self.project_id = oidc_config.project_id | ||
|
|
||
| def render_GET(self, request): | ||
| request.setHeader(b"content-type", b"application/json") | ||
| request.setHeader(b"access-control-allow-origin", b"*") | ||
| return json.dumps( | ||
| { | ||
| "issuer": self.issuer, | ||
| "issuer-metadata": self.metadata_url, | ||
| "organization-id": self.organization_id, | ||
| "project-id": self.project_id, | ||
| } | ||
| ).encode("utf-8") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import json | ||
|
|
||
| from twisted.web import resource | ||
|
|
||
|
|
||
| class MetadataResource(resource.Resource): | ||
| def __init__(self, resource: object): | ||
| self.resource = resource | ||
|
|
||
| def render_GET(self, request): | ||
| request.setHeader(b"content-type", b"application/json") | ||
| request.setHeader(b"access-control-allow-origin", b"*") | ||
| return json.dumps(self.resource).encode("utf-8") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| from jwcrypto.jwk import JWKSet | ||
| from twisted.web import resource | ||
|
|
||
|
|
||
| class PublicKeysResource(resource.Resource): | ||
| def __init__(self, keys: JWKSet): | ||
| self.keys = keys.export(private_keys=False).encode("utf-8") | ||
|
|
||
| def render_GET(self, request): | ||
| request.setHeader(b"content-type", b"application/json") | ||
| request.setHeader(b"access-control-allow-origin", b"*") | ||
| return self.keys |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.