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

PPF-522-Keycloak credentials #1248

Merged
merged 6 commits into from
Jul 10, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
use App\Domain\Organizations\Repositories\OrganizationRepository;
use App\Domain\Subscriptions\Repositories\SubscriptionRepository;
use App\Http\Controllers\Controller;
use App\Keycloak\Repositories\KeycloakClientRepository;
use App\ProjectAanvraag\ProjectAanvraagUrl;
use App\Router\TranslatedRoute;
use App\Search\Sapi3\SearchService;
Expand Down Expand Up @@ -72,6 +73,7 @@ public function __construct(
private readonly CouponRepository $couponRepository,
private readonly Auth0ClientRepository $auth0ClientRepository,
private readonly UiTiDv1ConsumerRepository $uitidV1ConsumerRepository,
private readonly KeycloakClientRepository $keycloakClientRepository,
private readonly KeyVisibilityUpgradeRepository $keyVisibilityUpgradeRepository,
private readonly SearchService $searchClient,
private readonly CurrentUser $currentUser
Expand All @@ -91,12 +93,14 @@ public function index(Request $request): Response

$auth0Clients = $this->auth0ClientRepository->getByIntegrationIds($integrationIds);
$uitidV1Consumers = $this->uitidV1ConsumerRepository->getByIntegrationIds($integrationIds);
$keycloakClients = $this->keycloakClientRepository->getByIntegrationIds($integrationIds);

return Inertia::render('Integrations/Index', [
'integrations' => $integrationsData->collection->map(fn (Integration $integration) => $integration->toArray()),
'credentials' => [
'auth0' => $auth0Clients,
'uitidV1' => $uitidV1Consumers,
'keycloak' => $keycloakClients,
],
'paginationInfo' => $integrationsData->paginationInfo,
]);
Expand Down
1 change: 1 addition & 0 deletions app/Http/Middleware/HandleInertiaRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public function share(Request $request): array
'sentryDsn' => config('sentry.dsn'),
'sentryEnabled' => config('app.sentry.enabled'),
'uitpasEnabled' => config('uitpas.enabled'),
'keycloakEnabled' => config('keycloak.enabled'),
],
'widgetConfig' => [
'url' => config('uitidwidget.url'),
Expand Down
2 changes: 1 addition & 1 deletion config/keycloak.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Auth0\SDK\Configuration\SdkConfiguration;

return [

'enabled' => env('KEYCLOAK_ENABLED', false),
'loginEnabled' => env('KEYCLOAK_LOGIN_ENABLED', false),
'creationEnabled' => env('KEYCLOAK_CREATION_ENABLED', false),
'login' => [
Expand Down
78 changes: 55 additions & 23 deletions resources/ts/Components/IntegrationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Alert } from "./Alert";
import { classNames } from "../utils/classNames";
import { usePolling } from "../hooks/usePolling";
import { ButtonSecondary } from "./ButtonSecondary";
import { usePageProps } from "../hooks/usePageProps";

type Props = Integration &
Credentials & {
Expand Down Expand Up @@ -67,39 +68,70 @@ export const IntegrationCard = ({
legacyProdConsumer,
testClient,
prodClient,
keycloakTestClient,
keycloakProdClient,
keyVisibility,
onEdit,
}: Props) => {
const { t } = useTranslation();
const { config } = usePageProps();
const keycloakEnabled = config.keycloakEnabled;

const integrationTypesInfo = useIntegrationTypesInfo();

const auth0TestClientWithLabels = [
{
label: "details.credentials.client_id",
value: testClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: testClient?.clientSecret,
},
];
const testClientWithLabels = keycloakEnabled
? [
{
label: "details.credentials.client_id",
value: keycloakTestClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: keycloakTestClient?.clientSecret,
},
]
: [
{
label: "details.credentials.client_id",
value: testClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: testClient?.clientSecret,
},
];

const auth0ProdClientWithLabels = [
{
label: "details.credentials.client_id",
value: prodClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: prodClient?.clientSecret,
},
];
const prodClientWithLabels = keycloakEnabled
? [
{
label: "details.credentials.client_id",
value: keycloakProdClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: keycloakProdClient?.clientSecret,
},
]
: [
{
label: "details.credentials.client_id",
value: prodClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: prodClient?.clientSecret,
},
];

const clientSecretLabel = t("details.credentials.client_secret");

const hasAnyCredentials = Boolean(
legacyTestConsumer || legacyProdConsumer || testClient || prodClient
legacyTestConsumer ||
legacyProdConsumer ||
testClient ||
prodClient ||
keycloakProdClient ||
keycloakProdClient
);

usePolling(!hasAnyCredentials, { only: ["credentials"] });
Expand All @@ -120,7 +152,7 @@ export const IntegrationCard = ({
</Heading>
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-2">
{auth0TestClientWithLabels.map((client) => (
{testClientWithLabels.map((client) => (
<div
key={`${client.label}-${client.value}`}
className="flex gap-1 max-md:flex-col max-md:items-start"
Expand Down Expand Up @@ -189,7 +221,7 @@ export const IntegrationCard = ({
)}
{status === IntegrationStatus.Active && (
<div className="flex flex-col gap-2">
{auth0ProdClientWithLabels.map((client) => (
{prodClientWithLabels.map((client) => (
<div
key={`${client.label}-${client.value}`}
className="flex gap-1 max-md:flex-col max-md:items-start"
Expand Down
27 changes: 22 additions & 5 deletions resources/ts/Components/Integrations/Detail/Credentials.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import { IntegrationType } from "../../../types/IntegrationType";
import { CredentialsWidgets } from "./CredentialsWidgets";
import type {
AuthClient,
KeycloakClient,
LegacyAuthConsumer,
} from "../../../types/Credentials";
import type { Integration } from "../../../types/Integration";
import { Alert } from "../../Alert";
import { useTranslation } from "react-i18next";
import { usePolling } from "../../../hooks/usePolling";
import { KeyVisibility } from "../../../types/KeyVisibility";
import { UiTiDv1Environment } from "../../../types/UiTiDv1Environment";
import { Auth0Tenant } from "../../../types/Auth0Tenant";
import { KeycloakEnvironment } from "../../../types/KeycloakEnvironment";

type Props = Integration & {
email: string;
Expand All @@ -23,6 +27,8 @@ export type Credentials = {
prodClient?: AuthClient;
legacyTestConsumer?: LegacyAuthConsumer;
legacyProdConsumer?: LegacyAuthConsumer;
keycloakTestClient?: KeycloakClient;
keycloakProdClient?: KeycloakClient;
};

export const Credentials = ({
Expand All @@ -35,6 +41,7 @@ export const Credentials = ({
keyVisibilityUpgrade,
legacyAuthConsumers,
authClients,
keycloakClients,
oldCredentialsExpirationDate,
}: Props) => {
const { t } = useTranslation();
Expand All @@ -47,15 +54,25 @@ export const Credentials = ({
const credentials = useMemo(
() => ({
legacyTestConsumer: legacyAuthConsumers.find(
(consumer) => consumer.environment === "test"
(consumer) => consumer.environment === UiTiDv1Environment.Testing
),
legacyProdConsumer: legacyAuthConsumers.find(
(consumer) => consumer.environment === "prod"
(consumer) => consumer.environment === UiTiDv1Environment.Production
),
testClient: authClients.find(
(client) => client.tenant === Auth0Tenant.Testing
),
prodClient: authClients.find(
(client) => client.tenant === Auth0Tenant.Production
),
keycloakTestClient: keycloakClients.find(
(client) => client.environment === KeycloakEnvironment.Testing
),
keycloakProdClient: keycloakClients.find(
(client) => client.environment === KeycloakEnvironment.Production
),
testClient: authClients.find((client) => client.tenant === "test"),
prodClient: authClients.find((client) => client.tenant === "prod"),
}),
[legacyAuthConsumers, authClients]
[legacyAuthConsumers, authClients, keycloakClients]
);

if (!hasAnyCredentials) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { KeyVisibility } from "../../../types/KeyVisibility";
import { router } from "@inertiajs/react";
import { Link } from "../../Link";
import { Alert } from "../../Alert";
import { usePageProps } from "../../../hooks/usePageProps";

type Props = Pick<
Integration,
Expand All @@ -27,6 +28,8 @@ type Props = Pick<
export const CredentialsAuthClients = ({
testClient,
prodClient,
keycloakTestClient,
keycloakProdClient,
id,
status,
email,
Expand All @@ -36,29 +39,54 @@ export const CredentialsAuthClients = ({
keyVisibilityUpgrade,
}: Props) => {
const { t } = useTranslation();
const { config } = usePageProps();
const keycloakEnabled = config.keycloakEnabled;

const isKeyVisibilityV1 = keyVisibility === KeyVisibility.v1;

const auth0TestClientWithLabels = [
{
label: "details.credentials.client_id",
value: testClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: testClient?.clientSecret,
},
];
const testClientWithLabels = keycloakEnabled
? [
{
label: "details.credentials.client_id",
value: keycloakTestClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: keycloakTestClient?.clientSecret,
},
]
: [
{
label: "details.credentials.client_id",
value: testClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: testClient?.clientSecret,
},
];

const auth0ProdClientWithLabels = [
{
label: "details.credentials.client_id",
value: prodClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: prodClient?.clientSecret,
},
];
const prodClientWithLabels = keycloakEnabled
? [
{
label: "details.credentials.client_id",
value: keycloakProdClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: keycloakProdClient?.clientSecret,
},
]
: [
{
label: "details.credentials.client_id",
value: prodClient?.clientId,
},
{
label: "details.credentials.client_secret",
value: prodClient?.clientSecret,
},
];

const clientSecretLabel = t("details.credentials.client_secret");

Expand Down Expand Up @@ -104,7 +132,7 @@ export const CredentialsAuthClients = ({
<Heading className="font-semibold flex min-w-[5rem]" level={4}>
{t("details.credentials.test")}
</Heading>
{auth0TestClientWithLabels.map((client) => (
{testClientWithLabels.map((client) => (
<div
key={`${client.label}-${client.value}`}
className="flex gap-1 max-md:flex-col max-md:items-start"
Expand All @@ -128,7 +156,7 @@ export const CredentialsAuthClients = ({
<StatusLight status={status} />
{status === IntegrationStatus.Active && (
<div className="flex flex-col gap-3">
{auth0ProdClientWithLabels.map((client) => (
{prodClientWithLabels.map((client) => (
<div
key={`${client.label}-${client.value}`}
className="flex gap-1 max-md:flex-col max-md:items-start"
Expand Down
13 changes: 12 additions & 1 deletion resources/ts/Pages/Integrations/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { UiTiDv1Environment } from "../../types/UiTiDv1Environment";
import type { Credentials } from "../../types/Credentials";
import type { Integration } from "../../types/Integration";
import { router } from "@inertiajs/react";
import { KeycloakEnvironment } from "../../types/KeycloakEnvironment";

type Props = {
integrations: Integration[];
Expand Down Expand Up @@ -72,9 +73,19 @@ const Index = ({ integrations, paginationInfo, credentials }: Props) => {
client.integrationId === integration.id &&
client.environment === UiTiDv1Environment.Production
),
keycloakTestClient: credentials.keycloak.find(
(client) =>
client.integrationId === integration.id &&
client.environment === KeycloakEnvironment.Testing
),
keycloakProdClient: credentials.keycloak.find(
(client) =>
client.integrationId === integration.id &&
client.environment === KeycloakEnvironment.Testing
),
},
})),
[integrations, credentials.auth0, credentials.uitidV1]
[integrations, credentials.auth0, credentials.uitidV1, credentials.keycloak]
);

const handleDeleteIntegration = () => {
Expand Down
9 changes: 9 additions & 0 deletions resources/ts/types/Credentials.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Auth0Tenant } from "./Auth0Tenant";
import type { KeycloakEnvironment } from "./KeycloakEnvironment";
import type { UiTiDv1Environment } from "./UiTiDv1Environment";

export type LegacyAuthConsumer = {
Expand All @@ -17,7 +18,15 @@ export type AuthClient = {
integrationId: string;
tenant: Auth0Tenant;
};
export type KeycloakClient = {
clientId: string;
clientSecret: string;
environment: KeycloakEnvironment;
id: string;
integrationId: string;
};
export type Credentials = {
auth0: AuthClient[];
uitidV1: LegacyAuthConsumer[];
keycloak: KeycloakClient[];
};
Loading
Loading