diff --git a/apps/ex_fleet_yards/lib/ex_fleet_yards/repo/account/oauth_client.ex b/apps/ex_fleet_yards/lib/ex_fleet_yards/repo/account/oauth_client.ex index 1b54780a..b3782422 100644 --- a/apps/ex_fleet_yards/lib/ex_fleet_yards/repo/account/oauth_client.ex +++ b/apps/ex_fleet_yards/lib/ex_fleet_yards/repo/account/oauth_client.ex @@ -20,7 +20,8 @@ defmodule ExFleetYards.Repo.Account.OauthClient do def create(user, %Boruta.Ecto.Client{id: id}), do: create(user, id) def create(%User{id: user_id}, client), do: create(user_id, client) - def create(user_id, %Ecto.Changeset{} = client_changeset) when is_binary(user_id) do + def create(user_id, %Ecto.Changeset{} = client_changeset) + when is_binary(user_id) or is_nil(user_id) do if client_changeset.valid? do Repo.transaction(fn -> with {:ok, client} <- Repo.insert(client_changeset), @@ -101,6 +102,7 @@ defmodule ExFleetYards.Repo.Account.OauthClient do id_token_signing_alg: "RS256", pkce: false } + def default_args, do: @default_args defp transform_client_args(args, true) do args = diff --git a/apps/ex_fleet_yards/priv/repo/migrations/20230730111440_no_user_for_oauth_client.exs b/apps/ex_fleet_yards/priv/repo/migrations/20230730111440_no_user_for_oauth_client.exs new file mode 100644 index 00000000..ae3d0c29 --- /dev/null +++ b/apps/ex_fleet_yards/priv/repo/migrations/20230730111440_no_user_for_oauth_client.exs @@ -0,0 +1,14 @@ +defmodule ExFleetYards.Repo.Migrations.NoUserForOauthClient do + use Ecto.Migration + + def up do + execute "ALTER TABLE oauth_user_clients DROP CONSTRAINT oauth_user_clients_user_id_fkey" + + alter table(:oauth_user_clients) do + modify :user_id, references(:users, type: :uuid, on_delete: :delete_all), null: true + end + end + + def down do + end +end diff --git a/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/api_spec.ex b/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/api_spec.ex index 7cc5b33d..12418b94 100644 --- a/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/api_spec.ex +++ b/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/api_spec.ex @@ -40,6 +40,10 @@ defmodule ExFleetYardsAuth.ApiSpec do authorizationUrl: Endpoint.url() <> ~p"/oauth/authorize", tokenUrl: Endpoint.url() <> ~p"/oauth/token", scopes: scope_list() + }, + implicit: %OAuthFlow{ + authorizationUrl: Endpoint.url() <> ~p"/oauth/authorize", + scopes: scope_list() } } } diff --git a/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/release/oauth_client.ex b/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/release/oauth_client.ex new file mode 100644 index 00000000..6c97858b --- /dev/null +++ b/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/release/oauth_client.ex @@ -0,0 +1,47 @@ +defmodule ExFleetYardsAuth.Release.OauthClient do + @moduledoc """ + Helper to create static Oauth Clients + """ + + alias ExFleetYards.Repo + alias ExFleetYardsAuth.Endpoint + use ExFleetYardsAuth, :verified_routes + + # Swagger ui + def swagger_ui_uuid, do: "52d96be7-8e29-412b-a9f2-05a532ff9708" + + def swagger_ui_callback_uri do + Endpoint.url() <> ~p"/api/oauth2-redirect.html" + end + + def get_or_create_swagger_client_id() do + id = swagger_ui_uuid() + import Ecto.Query + + Repo.exists?(from(c in Boruta.Ecto.Client, where: c.id == ^id)) + |> case do + true -> + id + + false -> + create_client(id, "Fleetyards Auth API", [swagger_ui_callback_uri()]) + end + end + + def create_client(id \\ nil, name, redirect_uris) do + id = if(is_nil(id), do: SecureRandom.uuid(), else: id) + + args = + Map.merge(Repo.Account.OauthClient.default_args(), %{ + id: id, + name: name, + authorize_scopes: true, + redirect_uris: redirect_uris + }) + + client_changeset = Boruta.Ecto.Client.create_changeset(%Boruta.Ecto.Client{}, args) + + {:ok, client} = Repo.Account.OauthClient.create(nil, client_changeset) + client.client.id + end +end diff --git a/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/router.ex b/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/router.ex index 5a366dda..6f6e9ed5 100644 --- a/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/router.ex +++ b/apps/ex_fleet_yards_auth/lib/ex_fleet_yards_auth/router.ex @@ -121,9 +121,13 @@ defmodule ExFleetYardsAuth.Router do get "/docs", SwaggerUI, path: "/api/v2/openapi", persist_authorization: true, - oauth: [appName: "Fleetyards API"] + oauth: [ + app_name: "Fleetyards Auth API", + client_id: ExFleetYardsAuth.Release.OauthClient.get_or_create_swagger_client_id(), + scopes: ["openid", "profile", "user", "user:security"] + ] - get "/oauth2-redirect.html", SwaggerUiOAuth2Redirect, [] + get "/oauth2-redirect.html", SwaggerUIOAuth2Redirect, [] end end