Metadata-Version: 2.1
Name: discourse-sso-oidc-bridge-consideratio
Version: 0.1.4
Summary: A Flask app, wrapping a single OpenID Connect issuer with a Discourse SSO provider interface.
Home-page: UNKNOWN
Author: Erik Sundell
Author-email: erik.i.sundell@gmail.com
License: Apache License, Version 2.0
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Description-Content-Type: text/markdown
Requires-Dist: alabaster (==0.7.12)
Requires-Dist: asn1crypto (==0.24.0)
Requires-Dist: beaker (==1.10.1)
Requires-Dist: certifi (==2018.11.29)
Requires-Dist: cffi (==1.12.1)
Requires-Dist: chardet (==3.0.4)
Requires-Dist: click (==7.0)
Requires-Dist: cryptography (==2.5)
Requires-Dist: flask-pyoidc (==2.0.0)
Requires-Dist: flask (==1.0.2)
Requires-Dist: future (==0.17.1)
Requires-Dist: healthcheck (==1.3.3)
Requires-Dist: idna (==2.8)
Requires-Dist: itsdangerous (==1.1.0)
Requires-Dist: jinja2 (==2.10)
Requires-Dist: mako (==1.0.7)
Requires-Dist: markupsafe (==1.1.1)
Requires-Dist: oic (==0.12)
Requires-Dist: pycparser (==2.19)
Requires-Dist: pycryptodomex (==3.7.3)
Requires-Dist: pyjwkest (==1.4.0)
Requires-Dist: pyopenssl (==19.0.0)
Requires-Dist: requests (==2.21.0)
Requires-Dist: six (==1.12.0)
Requires-Dist: urllib3 (==1.24.1)
Requires-Dist: werkzeug (==0.14.1)

# Discourse SSO OIDC Bridge - A Python PyPI package

This Python package contains a Flask application that when deployed can be used
as and endpoint for Discourse when setting up it's SSO. It will then be able to
wrap a OIDC provider and avoid various [limitations](https://meta.discourse.org/t/sso-vs-oauth2-difference/76543/11)
of not being setup as a Discourse SSO provider.

This repo was made standing on the shoulders giants who made most of the initial
work. Thank you [__@fmarco76__](https://github.com/fmarco76) and [__@stevenmirabito__](https://github.com/stevenmirabito)!

- https://github.com/fmarco76/DiscourseSSO
- https://github.com/ComputerScienceHouse/DiscourseOIDC

I also did some refinements thanks to [__@greut__](https://github.com/greut) this [Medium article](https://medium.com/@greut/building-a-python-package-a-docker-image-using-pipenv-233d8793b6cc).

## Installation

Note that this is only a Flask application, you must use `gunicorn` or another
WSGI compatible webserver to host it and setup TLS etc.

> __WARNING__: Not yet tested with Discourse to function, but I'm working on it!

```sh
# NOTE: Currently onnly on PyPI's test servers
pip install --upgrade discourse-sso-oidc-bridge-consideratio
```

## Bridge Configuration

This is the common configuration that, [default.py](discourse-sso-oidc-bridge/default.py).

| __Config / ENV name__     | __Description__ |
|---------------------------|-|
| `SERVER_NAME`             | The domain where you host this app, example: `"discourse-sso.example.com"`. Note that `https://` will be assumed. |
| `SECRET_KEY`              | A secret for Flask, just generate one with `openssl rand -hex 32`. |
| `OIDC_ISSUER`             | An URL to the OIDC issuer. To verify you get this right you can try appending `/.well-known/openid-configuration` to it and see if you get various JSON details rather than a 404. |
| `OIDC_CLIENT_ID`          | A preregistered `client_id` on your OIDC issuer. |
| `OIDC_CLIENT_SECRET`      | The provided secret for the the preregistered `OIDC_CLIENT_ID`. |
| `OIDC_SCOPE`              | Comma seperated OIDC scopes, defaults to `"openid,profile"`. |
| `DISCOURSE_URL`           | The URL of your Discourse deployment, example `"https://discourse.example.com"`. |
| `DISCOURSE_SECRET_KEY`    | A shared secret between the bridge and Discourse, generate one with `openssl rand -hex 32`. |
| `USERINFO_SSO_MAP`        | Valid JSON object in a string mapping OIDC userinfo attribute names to to Discourse SSO attribute names. |
| `DEFAULT_SSO_ATTRIBUTES`  | Valid JSON object in a string mapping Discourse SSO attributes to default values. By default `sub` is mapped to `external_id` and `preferred_username` to `username`. |
| `CONFIG_LOCATION`         | The path to a Python file to be loaded as config where `OIDC_ISSUER` etc. could be set. |

## OIDC Provider Configuration

You must have a `client_id` and `client_secret` from your OIDC issuer. The
issuer must also accept redirecting back to `<bridge_url>/redirect_uri`, which
for example could be `https://discourse-sso.example.com/redirect_uri`.

## Development Notes

### To make changes and test them

1. Clone the repo

2. Install `pipenv` using `pip`.

    ```sh
    pip install pipenv
    ```

3. Setup a virtual development environment

    ```sh
    pipenv install --dev

    # Optionally enter the environment
    pipenv shell
    ```

4. Run tests

    ```sh
    pipenv run pytest
    ```

### Build and upload a PyPI release

1. Test, build and upload the package

    ```sh
    # Make sure you are up to date with what you have declared to require
    pipenv install --dev

    # Update changelog, fix requirements, etc.
    pipenv lock -r > requirements.txt

    # Run tests
    pipenv run pytest

    # Commit and tag to influence the PyPI version
    # PBR will look for the latest tag and then append development
    # versions based on your git commits since the latest tag.
    git add .
    git commit


    TAG=$(pipenv run python -c 'from pbr.version import VersionInfo; print(VersionInfo("discourse_sso_oidc_bridge").version_string())')
    git tag -a $TAG -m "Release $TAG"

    # Build the package
    pipenv run python setup.py bdist_wheel

    # Upload the package to PyPI
    pipenv run twine upload --skip-existing --username consideratio dist/*
    ```

2. Build, run, and push a Docker image

    ```sh
    docker build -t consideratio/discourse-sso-oidc-bridge:$TAG .
    docker run --rm -p 8080:8080 consideratio/discourse-sso-oidc-bridge:$TAG
    docker push consideratio/discourse-sso-oidc-bridge:$TAG
    ```

## Deployment notes

I have deployed this using a simpler not published Helm chart. I'm happy to open source this as well for a complete solution. But to avoid overworking something that few has interest for it in I'd appreciate if you showed interest in this by emailing me or opening an issue or similar.



