Skip to content
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

refactor: use master branch of OpenIDConnect #28

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: CI

on:
push:
pull_request:

jobs:
asdf:
name: ASDF
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4
# cache the ASDF directory, using the values from .tool-versions
- name: ASDF cache
uses: actions/cache@v3
with:
path: ~/.asdf
key: ${{ runner.os }}-asdf-v2-${{ hashFiles('.tool-versions') }}
id: asdf-cache
# only run `asdf install` if we didn't hit the cache
- uses: asdf-vm/actions/install@v2
if: steps.asdf-cache.outputs.cache-hit != 'true'

build:
name: Build Elixir
runs-on: ubuntu-22.04
needs: asdf
steps:
- uses: actions/checkout@v4
- name: ASDF cache
uses: actions/cache@v3
with:
path: ~/.asdf
key: ${{ runner.os }}-asdf-v2-${{ hashFiles('.tool-versions') }}
id: asdf-cache
- uses: mbta/actions/reshim-asdf@v1
- name: Restore dependencies cache
id: deps-cache
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: |
mix local.rebar --force
mix local.hex --force
mix deps.get

elixir:
name: Test Elixir
runs-on: ubuntu-22.04
needs: build
steps:
- uses: actions/checkout@v4
- name: ASDF cache
uses: actions/cache@v3
with:
path: ~/.asdf
key: ${{ runner.os }}-asdf-v2-${{ hashFiles('.tool-versions') }}
id: asdf-cache
- uses: mbta/actions/reshim-asdf@v1
- name: Restore dependencies cache
id: deps-cache
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: |
mix local.rebar --force
mix local.hex --force
- name: Compile (warnings as errors)
run: mix compile --force --warnings-as-errors
- name: Check formatting
run: mix format --check-formatted
- name: Run tests
run: mix test --cover
- name: Run Credo
run: mix credo --strict
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
elixir 1.13.4-otp-24
erlang 24.3.4.14
91 changes: 34 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Has optional support for `/userinfo` endpoints, and has the option to get a user

```elixir
def deps do
[{:ueberauth_oidc, git: "https://github.com/DefactoSoftware/ueberauth_oidc.git"}]
[{:ueberauth_oidc, github: "mbta/ueberauth_oidc"}]
end
```

Expand All @@ -28,46 +28,44 @@ Has optional support for `/userinfo` endpoints, and has the option to get a user

## Configuration

1. Add OIDC to your Ueberauth configuration:
1. Add OIDC to your Ueberauth configuration.
See [OpenIDConnect](https://github.com/DockYard/openid_connect/blob/master/README.md) and [Ueberauth](https://hexdocs.pm/ueberauth/readme.html#configuring-providers)
for a list of supported options.

```elixir
config :ueberauth, Ueberauth,
providers: [
oidc: { Ueberauth.Strategy.OIDC, [
default: [
# required, set to default provider you want to use
provider: :default_oidc,

# optional
uid_field: :sub
],

# optional override for each provider
google: [uid_field: :email],
...
] }
oidc: { Ueberauth.Strategy.OIDC,
discovery_document_uri: "https://oidc.example/.well-known/openid-configuration",
client_id: "client_id",
client_secret: "123456789",
response_type: "code",
scope: "openid profile email",
# optional
callback_path: "/auth/oidc/callback",
fetch_userinfo: true, # true/false
userinfo_uid_field: "upn", # only include if getting the user_id from userinfo
uid_field: "sub" # only include if getting the user_id from the claims,
request_params: %{} # additional parameters for the initial request
request_uri: "https://oidc-override/request" # override the initial request URI
}
]
```

1. Update your provider configuration.
See [OpenIDConnect](https://hexdocs.pm/openid_connect/readme.html)
for a list of supported options.
You can also split the configuration into compile- and run-time settings:

```elixir
config :ueberauth, Ueberauth,
providers: [
oidc: { Ueberauth.Strategy.OIDC,
discovery_document_uri: "https://oidc.example/.well-known/openid-configuration",
client_id: "client_id"
}
]

config :ueberauth, Ueberauth.Strategy.OIDC,
# one or more providers
default_oidc: [
fetch_userinfo: true, # true/false
userinfo_uid_field: "upn", # only include if getting the user_id from userinfo
uid_field: "sub" # only include if getting the user_id from the claims
discovery_document_uri: "https://oidc.example/.well-known/openid-configuration",
client_id: "client_id",
client_secret: "123456789",
redirect_uri: "https://your.url/auth/oidc/callback",
response_type: "code",
scope: "openid profile email"
],
...
oidc: [
client_secret: System.fetch_env!("OIDC_CLIENT_SECRET")
]
```

## Usage
Expand Down Expand Up @@ -96,44 +94,23 @@ for a list of supported options.
1. Your controller needs to implement callbacks to deal with `Ueberauth.Auth`
and `Ueberauth.Failure` responses. For an example implementation see the
[Ueberauth Example](https://github.com/ueberauth/ueberauth_example) application.
Note that the `Ueberauth.Strategy.Info` struct stored in `Ueberauth.Auth`
will be empty. Use the information in `Ueberauth.Auth.Credentials` and
`Ueberauth.Strategy.Extra` instead:

- `Ueberauth.Auth.Credentials` contains the `access_token` and related fields

- The `other` map in `Ueberauth.Auth.Credentials` contains `provider` and `user_info`
- The `other` map in `Ueberauth.Auth.Credentials` contains `id_token`

- `Ueberauth.Strategy.Extra` contains the raw claims, tokens and opts

1. Add `OpenIDConnect.Worker` with a provider list during application startup:

```elixir
def start(_type, _args) do
...
children = [
...,
{OpenIDConnect.Worker, Application.get_env(:ueberauth, Ueberauth.Strategy.OIDC)},
...
]
...
Supervisor.start_link(children, opts)
end
```
- `Ueberauth.Strategy.Extra` contains the raw claims, userinfo, and tokens

## Calling

Depending on the configured url, you can initialize the request through:

/auth/oidc

To use another provider instead of the configured default, add the `oidc_provider` option:

/auth/oidc?oidc_provider=google

## License

Please see [LICENSE](https://github.com/DefactoSoftware/ueberauth_oidc/blob/master/LICENSE)
for licensing details.

Loosely based on [rng2/ueberauth_oidc](https://github.com/rng2/ueberauth_oidc).
Based on:
- [rng2/ueberauth_oidc](https://github.com/rng2/ueberauth_oidc)
31 changes: 1 addition & 30 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -1,30 +1 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
# file won't be loaded nor affect the parent project. For this reason,
# if you want to provide default values for your application for
# 3rd-party users, it should be done in your "mix.exs" file.

# You can configure your application as:
#
# config :ueberauth_oidc, key: :value
#
# and access this configuration in your application as:
#
# Application.get_env(:ueberauth_oidc, :key)
#
# You can also configure a 3rd-party app:
#
# config :logger, level: :info
#

# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
# by uncommenting the line below and defining dev.exs, test.exs and such.
# Configuration from the imported file will override the ones defined
# here (which is why it is important to import them last).
#
# import_config "#{Mix.env}.exs"
import Config
Loading