Skip to content

Commit

Permalink
A generic OpenID Connect implementation (#413)
Browse files Browse the repository at this point in the history
* Add ueberauth_oidc as dependency

* Update OIDC dependency

Todo: Figure out why the Hex.io one didn't work

* Begin OIDC implementation

* It.. actually works???

* Minor changes

* Change french so it hopefully fits better

* Update mix.lock

* Break everything, but shall continue on other machine

* Add OIDC environment variables to README

* Check for OIDC client ID before adding OpenID Worker

* Add fancy icon

* Remove comments

* Fix formatting

* Fix formatting... again.

* Change back to hex.io's ueberauth_oidc
  • Loading branch information
dynamyc010 authored Mar 3, 2024
1 parent d8e3a70 commit bfd259e
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 18 deletions.
41 changes: 23 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,24 +139,29 @@ Accent provides a default value for every required environment variable. This me

Various login providers are included in Accent using Ueberauth to abstract services.

| Variable | Default | Description |
| -------------------------- | -------------------- | --------------------------------------------------------------------------------------- |
| `DUMMY_LOGIN_ENABLED` | _none_ | If specified, the password-less authentication (with only the email) will be available. |
| `GITHUB_CLIENT_ID` | _none_ | |
| `GITHUB_CLIENT_SECRET` | _none_ | |
| `GITLAB_CLIENT_ID` | _none_ | |
| `GITLAB_CLIENT_SECRET` | _none_ | |
| `GITLAB_SITE_URL` | `https://gitlab.com` | |
| `GOOGLE_API_CLIENT_ID` | _none_ | |
| `GOOGLE_API_CLIENT_SECRET` | _none_ | |
| `SLACK_CLIENT_ID` | _none_ | |
| `SLACK_CLIENT_SECRET` | _none_ | |
| `SLACK_TEAM_ID` | _none_ | |
| `DISCORD_CLIENT_ID` | _none_ | |
| `DISCORD_CLIENT_SECRET` | _none_ | |
| `MICROSOFT_CLIENT_ID` | _none_ | |
| `MICROSOFT_CLIENT_SECRET` | _none_ | |
| `MICROSOFT_TENANT_ID` | _none_ | |
| Variable | Default | Description |
| -------------------------- | ---------------------- | --------------------------------------------------------------------------------------- |
| `DUMMY_LOGIN_ENABLED` | _none_ | If specified, the password-less authentication (with only the email) will be available. |
| `GITHUB_CLIENT_ID` | _none_ | |
| `GITHUB_CLIENT_SECRET` | _none_ | |
| `GITLAB_CLIENT_ID` | _none_ | |
| `GITLAB_CLIENT_SECRET` | _none_ | |
| `GITLAB_SITE_URL` | `https://gitlab.com` | |
| `GOOGLE_API_CLIENT_ID` | _none_ | |
| `GOOGLE_API_CLIENT_SECRET` | _none_ | |
| `SLACK_CLIENT_ID` | _none_ | |
| `SLACK_CLIENT_SECRET` | _none_ | |
| `SLACK_TEAM_ID` | _none_ | |
| `DISCORD_CLIENT_ID` | _none_ | |
| `DISCORD_CLIENT_SECRET` | _none_ | |
| `MICROSOFT_CLIENT_ID` | _none_ | |
| `MICROSOFT_CLIENT_SECRET` | _none_ | |
| `MICROSOFT_TENANT_ID` | _none_ | |
| `OIDC_CLIENT_ID` | _none_ | |
| `OIDC_CLIENT_SECRET` | _none_ | |
| `OIDC_DISCOVERY_URI` | _none_ | |
| `OIDC_UID_FIELD` | `sub` | |
| `OIDC_SCOPE` | `openid profile email` | |

### Email setup

Expand Down
17 changes: 17 additions & 0 deletions config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ providers =

providers = if get_env("AUTH0_CLIENT_ID"), do: [{:auth0, {Ueberauth.Strategy.Auth0, []}} | providers], else: providers

providers =
if get_env("OIDC_CLIENT_ID"),
do: [{:oidc, {Ueberauth.Strategy.OIDC, [default: [provider: :default_oidc, uid_field: :sub]]}} | providers],
else: providers

providers =
if get_env("DUMMY_LOGIN_ENABLED"),
do: [{:dummy, {Accent.Auth.Ueberauth.DummyStrategy, []}} | providers],
Expand Down Expand Up @@ -129,6 +134,18 @@ config :ueberauth, Ueberauth.Strategy.Microsoft.OAuth,
client_secret: get_env("MICROSOFT_CLIENT_SECRET"),
tenant_id: get_env("MICROSOFT_TENANT_ID")

config :ueberauth, Ueberauth.Strategy.OIDC,
default_oidc: [
fetch_userinfo: true,
uid_field: get_env("OIDC_UID_FIELD") || "sub",
client_id: get_env("OIDC_CLIENT_ID"),
client_secret: get_env("OIDC_CLIENT_SECRET"),
discovery_document_uri: get_env("OIDC_DISCOVERY_URI"),
redirect_uri: "#{static_uri}/auth/oidc/callback",
response_type: "code",
scope: get_env("OIDC_SCOPE") || "openid profile email"
]

config :accent, Accent.WebappView,
path: "priv/static/webapp/index.html",
sentry_dsn: get_env("WEBAPP_SENTRY_DSN") || "",
Expand Down
5 changes: 5 additions & 0 deletions lib/accent.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ defmodule Accent do
{Phoenix.PubSub, [name: Accent.PubSub, adapter: Phoenix.PubSub.PG2]}
]

children =
if Application.get_env(:ueberauth, Ueberauth.Strategy.OIDC)[:default_oidc][:client_id],
do: [{OpenIDConnect.Worker, Application.get_env(:ueberauth, Ueberauth.Strategy.OIDC)} | children],
else: children

if Application.get_env(:sentry, :dsn) do
{:ok, _} = Logger.add_backend(Sentry.LoggerBackend)
end
Expand Down
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ defmodule Accent.Mixfile do
{:ueberauth_github, "~> 0.7"},
{:ueberauth_discord, "~> 0.5"},
{:ueberauth_auth0, "~> 2.0"},
{:ueberauth_oidc, "~> 0.1.7"},

# Errors
{:sentry, "~> 7.0"},
Expand Down
2 changes: 2 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"nimble_pool": {:hex, :nimble_pool, "1.0.0", "5eb82705d138f4dd4423f69ceb19ac667b3b492ae570c9f5c900bb3d2f50a847", [:mix], [], "hexpm", "80be3b882d2d351882256087078e1b1952a28bf98d0a287be87e4a24a710b67a"},
"oauth2": {:hex, :oauth2, "2.1.0", "beb657f393814a3a7a8a15bd5e5776ecae341fd344df425342a3b6f1904c2989", [:mix], [{:tesla, "~> 1.5", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "8ac07f85b3307dd1acfeb0ec852f64161b22f57d0ce0c15e616a1dfc8ebe2b41"},
"oban": {:hex, :oban, "2.17.3", "ddfd5710aadcd550d2e174c8d73ce5f1865601418cf54a91775f20443fb832b7", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "452eada8bfe0d0fefd0740ab5fa8cf3ef6c375df0b4a3c3805d179022a04738a"},
"openid_connect": {:hex, :openid_connect, "0.2.2", "c05055363330deab39ffd89e609db6b37752f255a93802006d83b45596189c0b", [:mix], [{:httpoison, "~> 1.2", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "735769b6d592124b58edd0582554ce638524c0214cd783d8903d33357d74cc13"},
"p1_utils": {:hex, :p1_utils, "1.0.15", "731f76ae1f31f4554afb2ae629cb5589d53bd13efc72b11f5a7c3b1242f91046", [:rebar3], [], "hexpm", "1d308c3f37d7f770fb39abe3b86701b82d54414bc2499d9499edde3cb50bcf19"},
"parallel_stream": {:hex, :parallel_stream, "1.1.0", "f52f73eb344bc22de335992377413138405796e0d0ad99d995d9977ac29f1ca9", [:mix], [], "hexpm", "684fd19191aedfaf387bbabbeb8ff3c752f0220c8112eb907d797f4592d6e871"},
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
Expand Down Expand Up @@ -103,6 +104,7 @@
"ueberauth_github": {:hex, :ueberauth_github, "0.8.3", "1c478629b4c1dae446c68834b69194ad5cead3b6c67c913db6fdf64f37f0328f", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "ae0ab2879c32cfa51d7287a48219b262bfdab0b7ec6629f24160564247493cc6"},
"ueberauth_google": {:hex, :ueberauth_google, "0.12.1", "90cf49743588193334f7a00da252f92d90bfd178d766c0e4291361681fafec7d", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.10.0", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "7f7deacd679b2b66e3bffb68ecc77aa1b5396a0cbac2941815f253128e458c38"},
"ueberauth_microsoft": {:hex, :ueberauth_microsoft, "0.23.0", "5c78e02a83d821ee45f96216bb6140ba688cc79b8b26e7ff438e3abe24615e1d", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "0c08d98203e6d3069f30306f09a6cb55b95c2bda94d6f8e90f05bd442ee96b82"},
"ueberauth_oidc": {:git, "https://github.com/DefactoSoftware/ueberauth_oidc.git", "0e46efb1214d848256f2cdfa394b80448a06c9a4", []},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
"unsafe": {:hex, :unsafe, "1.0.2", "23c6be12f6c1605364801f4b47007c0c159497d0446ad378b5cf05f1855c0581", [:mix], [], "hexpm", "b485231683c3ab01a9cd44cb4a79f152c6f3bb87358439c6f68791b85c2df675"},
"vega_lite": {:hex, :vega_lite, "0.1.8", "7f6119126ecaf4bc2c1854084370d7091424f5cce4795fbac044eee9963f0752", [:mix], [{:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: false]}], "hexpm", "6c8a9271f850612dd8a90de8d1ebd433590ed07ffef76fc2397c240dc04d3fdc"},
Expand Down
5 changes: 5 additions & 0 deletions webapp/app/components/login-forms/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default class LoginForms extends Component<Args> {
discordUrl = `${config.API.AUTHENTICATION_PATH}/discord`;
microsoftUrl = `${config.API.AUTHENTICATION_PATH}/microsoft`;
auth0Url = `${config.API.AUTHENTICATION_PATH}/auth0`;
oidcUrl = `${config.API.AUTHENTICATION_PATH}/oidc`;

get version() {
return config.version === '__VERSION__' ? 'dev' : config.version;
Expand Down Expand Up @@ -62,6 +63,10 @@ export default class LoginForms extends Component<Args> {
return this.providerIds.includes('microsoft');
}

get oidcLoginEnabled() {
return this.providerIds.includes('oidc');
}

get dummyUrl() {
return `${config.API.AUTHENTICATION_PATH}/dummy/callback?email=${this.username}`;
}
Expand Down
1 change: 1 addition & 0 deletions webapp/app/locales/en-us.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"slack": "Login with Slack →",
"discord": "Login with Discord →",
"microsoft": "Login with Microsoft →",
"oidc": "Login with OpenID Connect →",
"dummy": "Enter an email and login →"
},
"dummy_login_form": {
Expand Down
1 change: 1 addition & 0 deletions webapp/app/locales/fr-ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"slack": "Se connecter avec Slack →",
"discord": "Se connecter avec Discord →",
"microsoft": "Se connecter avec Microsoft →",
"oidc": "Connectez-vous avec OIDC →",
"dummy": "Entrez un courriel et connectez-vous →"
},
"dummy_login_form": {
Expand Down
7 changes: 7 additions & 0 deletions webapp/app/styles/components/login-forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,13 @@ a.loginButton {
color: #03a5f0;
background: lighten(#03a5f0, 48%);
}

&.loginButton--oidc {
border-color: #f7931e;
text-shadow: none;
color: #f7931e;
background: lighten(#f7931e, 48%);
}
}

.loginButton-logo {
Expand Down
7 changes: 7 additions & 0 deletions webapp/app/templates/components/login-forms.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@
{{t 'components.login_forms.auth0'}}
</a>
{{/if}}

{{#if this.oidcLoginEnabled}}
<a href={{this.oidcUrl}} class='button button--filled' local-class='loginButton loginButton--oidc'>
<img src='assets/auth_providers/oidc.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.oidc'}}
</a>
{{/if}}
{{/if}}
</div>
</div>
Expand Down
Loading

0 comments on commit bfd259e

Please sign in to comment.