diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml new file mode 100644 index 0000000..352a0a9 --- /dev/null +++ b/.forgejo/workflows/build.yaml @@ -0,0 +1,93 @@ +on: + push: + workflow_dispatch: + inputs: + verbose: + description: "Verbose" + required: false + default: false + type: boolean + +jobs: + build: + runs-on: container + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v4 + with: + version: "0.5.16" + + - name: Install + run: uv sync + + - name: Run tests (API call) + run: .venv/bin/pytest -s tests/basic.py + + - name: Get version with git describe + id: version + run: | + echo "version=$(git describe)" >> $GITHUB_OUTPUT + echo "$VERSION" + + - name: Check if the container should be built + id: builder + env: + RUN: ${{ toJSON(inputs.build || !contains(steps.version.outputs.version, '-')) }} + run: | + echo "run=$RUN" >> $GITHUB_OUTPUT + echo "Run build: $RUN" + + - name: Set the version in pyproject.toml (workaround for uv not supporting dynamic version) + if: fromJSON(steps.builder.outputs.run) + env: + VERSION: ${{ steps.version.outputs.version }} + run: sed "s/0.0.0/$VERSION/" -i pyproject.toml + + - name: Workaround for bug of podman-login + if: fromJSON(steps.builder.outputs.run) + run: | + mkdir -p $HOME/.docker + echo "{ \"auths\": {} }" > $HOME/.docker/config.json + + - name: Log in to the container registry (with another workaround) + if: fromJSON(steps.builder.outputs.run) + uses: actions/podman-login@v1 + with: + registry: ${{ vars.REGISTRY }} + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + auth_file_path: /tmp/auth.json + + - name: Build the container image + if: fromJSON(steps.builder.outputs.run) + uses: actions/buildah-build@v1 + with: + image: oidc-fastapi-test + oci: true + labels: oidc-fastapi-test + tags: latest ${{ steps.version.outputs.version }} + containerfiles: | + ./Containerfile + + - name: Push the image to the registry + if: fromJSON(steps.builder.outputs.run) + uses: actions/push-to-registry@v2 + with: + registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" + image: oidc-fastapi-test + tags: latest ${{ steps.version.outputs.version }} + + - name: Build wheel + if: fromJSON(steps.builder.outputs.run) + run: uv build --wheel + + - name: Publish Python package (home) + if: fromJSON(steps.builder.outputs.run) + env: + LOCAL_PYPI_TOKEN: ${{ secrets.LOCAL_PYPI_TOKEN }} + run: uv publish --publish-url https://code.philo.ydns.eu/api/packages/philorg/pypi --token $LOCAL_PYPI_TOKEN + continue-on-error: true diff --git a/.forgejo/workflows/test.yaml b/.forgejo/workflows/test.yaml new file mode 100644 index 0000000..a56a9ce --- /dev/null +++ b/.forgejo/workflows/test.yaml @@ -0,0 +1,28 @@ +on: + push: + workflow_dispatch: + inputs: + verbose: + description: "Verbose" + required: false + default: false + type: boolean + +jobs: + test: + runs-on: container + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v4 + with: + version: "0.5.16" + + - name: Install + run: uv sync + + - name: Run tests (API call) + run: .venv/bin/pytest -s tests/basic.py diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml deleted file mode 100644 index 3af8132..0000000 --- a/.woodpecker/build.yaml +++ /dev/null @@ -1,63 +0,0 @@ -when: - - event: manual - - event: tag - -depends_on: - - test - -steps: - python_sync: - image: code.philo.ydns.eu/philorg/uv - volumes: - - uv-cache:/uv-cache - environment: - UV_CACHE_DIR: /uv-cache - UV_LINK_MODE: copy - commands: - - uv sync - - python_build: - image: code.philo.ydns.eu/philorg/uv - volumes: - - uv-cache:/uv-cache - environment: - UV_CACHE_DIR: /uv-cache - UV_LINK_MODE: copy - commands: - - uv build --wheel - - uv cache prune --ci - - python_publish: - image: code.philo.ydns.eu/philorg/uv - environment: - OWNER: philorg - REGISTRY_URL: https://code.philo.ydns.eu - REGISTRY_TOKEN: - from_secret: registry_token - commands: - - uv publish --publish-url $REGISTRY_URL/api/packages/$OWNER/pypi --token $REGISTRY_TOKEN dist/*.whl - failure: ignore - - container_build_publish: - image: quay.io/podman/stable:latest - # Caution: This image is built daily. It might fill up your image store quickly. - #pull: true - volumes: - - containers:/var/lib/containers - - uv:/root/.cache/uv - # Fill in the trusted checkbox in Woodpecker's settings as well - privileged: true - environment: - registry: code.philo.ydns.eu - org: philorg - container_name: oidc-fastapi-test - registry_token: - from_secret: registry_token - commands: - # Login at the registry - - podman login -u __token__ --password $registry_token $registry - # Build the container image - - podman build --volume=/var/lib/containers:/var/lib/containers --tag $registry/$org/$container_name:latest --tag $registry/$org/$container_name:$CI_COMMIT_TAG . - # Push the image - - podman push $registry/$org/$container_name:latest - - podman push $registry/$org/$container_name:$CI_COMMIT_TAG diff --git a/.woodpecker/test.yaml b/.woodpecker/test.yaml deleted file mode 100644 index d8816b2..0000000 --- a/.woodpecker/test.yaml +++ /dev/null @@ -1,21 +0,0 @@ -when: - - event: push - branch: main - - event: manual - - event: tag - -steps: - sync: - image: code.philo.ydns.eu/philorg/uv - volumes: - - uv-cache:/uv-cache - environment: - UV_CACHE_DIR: /uv-cache - UV_LINK_MODE: copy - commands: - - uv sync - - test: - image: code.philo.ydns.eu/philorg/uv - commands: - - .venv/bin/pytest -s tests/basic.py diff --git a/Containerfile b/Containerfile index 357cc84..2e3fd28 100644 --- a/Containerfile +++ b/Containerfile @@ -1,7 +1,6 @@ -FROM docker.io/library/python:3.13-slim +FROM docker.io/library/python:alpine COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/ -COPY --from=docker.io/python:3.13 /usr/bin/git /usr/local/bin/git COPY . /app diff --git a/README.md b/README.md index c7f8741..9e00474 100644 --- a/README.md +++ b/README.md @@ -52,59 +52,31 @@ given by the OIDC providers. For example: ```yaml -secret_key: AVeryWellKeptSecret -debug_token: no -show_token: yes -log: yes - -auth: +oidc: + secret_key: "ASecretNoOneKnows" + show_session_details: yes providers: - id: auth0 name: Okta / Auth0 - url: https:// - public_key_url: https:///pem - client_id: - client_secret: client_secret_generated_by_auth0 - hint: A hint for test credentials + url: "https://" + client_id: "" + client_secret: "client_secret_generated_by_auth0" + hint: "A hint for test credentials" - id: keycloak name: Keycloak at somewhere - url: https:// - info_url: https://philo.ydns.eu/auth/realms/test - account_url_template: /account - client_id: - client_secret: - hint: A hint for test credentials - code_challenge_method: S256 - resource_provider_scopes: - - get:time - - get:bs - resource_providers: - - id: - name: A third party resource provider - base_url: https://some.example.com/ - verify_ssl: yes - resources: - - name: Public RS2 - resource_name: public - url: resource/public - - name: BS RS2 - resource_name: bs - url: resource/bs - - name: Time RS2 - resource_name: time - url: resource/time + url: "https://" + account_url_template: "/account" + client_id: "" + client_secret: "client_secret_generated_by_keycloak" + hint: "User: foo, password: foofoo" - id: codeberg - disabled: no name: Codeberg - url: https://codeberg.org - account_url_template: /user/settings - client_id: - client_secret: client_secret_generated_by_codeberg - info_url: https://codeberg.org/login/oauth/keys - session_key: sub - skip_verify_signature: no + url: "https://codeberg.org" + account_url_template: "/user/settings" + client_id: "" + client_secret: "client_secret_generated_by_codeberg" resources: - name: List of repos id: repos @@ -127,5 +99,3 @@ with the setting file in the current working directory: ```sh podman run -p 8000:80 --env OIDC_TEST_CONFIG_FILE=/app/settings.yaml --mount type=bind,source=settings.yaml,destination=/app/settings.yaml code.philo.ydns.eu/philorg/oidc-fastapi-test:latest ``` - -[![status-badge](https://code.philo.ydns.eu/woodpecker/api/badges/22/status.svg)](https://code.philo.ydns.eu/woodpecker/repos/22) diff --git a/pyproject.toml b/pyproject.toml index c44e9f3..b1e6504 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "oidc-fastapi-test" -#version = "0.0.0" -dynamic = ["version"] +version = "0.0.0" +# dynamic = ["version"] description = "Add your description here" readme = "README.md" requires-python = ">=3.13" @@ -24,21 +24,14 @@ dependencies = [ oidc-test = "oidc_test.main:main" [dependency-groups] -dev = ["dunamai>=1.23.0", "ipdb>=0.13.13", "pytest>=8.3.4"] +dev = ["ipdb>=0.13.13", "pytest>=8.3.4"] [build-system] -requires = ["hatchling", "uv-dynamic-versioning"] +requires = ["hatchling"] build-backend = "hatchling.build" -[tool.hatch.version] -source = "uv-dynamic-versioning" - [tool.hatch.build.targets.wheel] packages = ["src/oidc_test"] -package = true - -[tool.uv-dynamic-versioning] -style = "semver" [tool.uv] package = true diff --git a/src/oidc_test/__init__.py b/src/oidc_test/__init__.py index f154022..e69de29 100644 --- a/src/oidc_test/__init__.py +++ b/src/oidc_test/__init__.py @@ -1,11 +0,0 @@ -import importlib.metadata - -try: - from dunamai import Version, Style - - __version__ = Version.from_git().serialize(style=Style.SemVer, dirty=True) -except (ImportError, RuntimeError): - # __name__ could be used if the package name is the same - # as the directory - not the case here - # __version__ = importlib.metadata.version(__name__) - __version__ = importlib.metadata.version("oidc-fastapi-test") diff --git a/src/oidc_test/auth/provider.py b/src/oidc_test/auth/provider.py index ce288a6..c614805 100644 --- a/src/oidc_test/auth/provider.py +++ b/src/oidc_test/auth/provider.py @@ -61,34 +61,28 @@ class Provider(AuthProviderSettings): if self.info_url is not None: try: provider_info = await client.get(self.info_url) - except Exception as err: - logger.debug("Provider_info: cannot connect") - logger.exception(err) + except Exception: raise NoPublicKey try: self.info = provider_info.json() except JSONDecodeError: - logger.debug("Provider_info: cannot decode json response") raise NoPublicKey if "public_key" in self.info: # For Keycloak try: public_key = str(self.info["public_key"]) except KeyError: - logger.debug("Provider_info: cannot get public_key") raise NoPublicKey elif "keys" in self.info: # For Forgejo/Gitea try: public_key = str(self.info["keys"][0]["n"]) except KeyError: - logger.debug("Provider_info: cannot get key 0.n") raise NoPublicKey if self.public_key_url is not None: resp = await client.get(self.public_key_url) public_key = resp.text if public_key is None: - logger.debug("Provider_info: cannot determine public key") raise NoPublicKey self.public_key = "\n".join( ["-----BEGIN PUBLIC KEY-----", public_key, "-----END PUBLIC KEY-----"] diff --git a/src/oidc_test/main.py b/src/oidc_test/main.py index e882cda..e5238c8 100644 --- a/src/oidc_test/main.py +++ b/src/oidc_test/main.py @@ -29,7 +29,6 @@ from authlib.oauth2.rfc6749 import OAuth2Token # from fastapi.security import OpenIdConnect # from pkce import generate_code_verifier, generate_pkce_pair -from oidc_test import __version__ from oidc_test.registry import registry from oidc_test.auth.provider import NoPublicKey, Provider from oidc_test.auth.utils import ( @@ -109,7 +108,6 @@ async def home( "show_token": settings.show_token, "user": user, "now": datetime.now(), - "__version__": __version__, } if provider is None or token is None: context["providers"] = providers diff --git a/src/oidc_test/static/styles.css b/src/oidc_test/static/styles.css index 1e8dc03..2baa748 100644 --- a/src/oidc_test/static/styles.css +++ b/src/oidc_test/static/styles.css @@ -21,12 +21,6 @@ hr { .hidden { display: none; } -.version { - position: absolute; - font-size: 75%; - top: 0.3em; - right: 0.3em; -} .center { text-align: center; } diff --git a/src/oidc_test/templates/base.html b/src/oidc_test/templates/base.html index 157e26f..4cb56f5 100644 --- a/src/oidc_test/templates/base.html +++ b/src/oidc_test/templates/base.html @@ -5,7 +5,6 @@ -
v. {{ __version__}}

OIDC-test - FastAPI client

{% block content %} {% endblock %} diff --git a/src/oidc_test/templates/home.html b/src/oidc_test/templates/home.html index 167616f..b4460ee 100644 --- a/src/oidc_test/templates/home.html +++ b/src/oidc_test/templates/home.html @@ -93,13 +93,13 @@ {% for resource in auth_provider.resources %} {% if resource.default_resource_id %} {% else %} -