diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx
index 28c9b5b..309df30 100644
--- a/packages/app/src/App.tsx
+++ b/packages/app/src/App.tsx
@@ -22,12 +22,13 @@ import {
import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
import { UserSettingsPage } from '@backstage/plugin-user-settings';
-import { apis } from './apis';
+import {apis} from './apis';
+import {keycloakOIDCAuthApiRef} from "@internal/plugin-workflows"
import { entityPage } from './components/catalog/EntityPage';
import { searchPage } from './components/search/SearchPage';
import { Root } from './components/Root';
-import {AlertDisplay, OAuthRequestDialog, ProxiedSignInPage} from '@backstage/core-components';
+import {AlertDisplay, OAuthRequestDialog, SignInPage} from '@backstage/core-components';
import { createApp } from '@backstage/app-defaults';
import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
@@ -37,7 +38,19 @@ import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/
const app = createApp({
apis,
components: {
- SignInPage: (props) => ,
+ // SignInPage: (props) => ,
+ SignInPage: props => (
+
+ ),
},
bindRoutes({ bind }) {
bind(catalogPlugin.externalRoutes, {
diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts
index c89753a..206598e 100644
--- a/packages/app/src/apis.ts
+++ b/packages/app/src/apis.ts
@@ -4,11 +4,26 @@ import {
ScmAuth,
} from '@backstage/integration-react';
import {
- AnyApiFactory,
- configApiRef,
- createApiFactory,
+ AnyApiFactory,
+ ApiRef,
+ BackstageIdentityApi,
+ configApiRef,
+ createApiFactory,
+ createApiRef,
+ discoveryApiRef,
+ oauthRequestApiRef,
+ OpenIdConnectApi,
+ ProfileInfoApi,
+ SessionApi,
} from '@backstage/core-plugin-api';
+import {OAuth2} from "@backstage/core-app-api";
+import {keycloakOIDCAuthApiRef} from "@internal/plugin-workflows"
+// export const keycloakOIDCAuthApiRef: ApiRef<
+// OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
+// > = createApiRef({
+// id: 'auth.keycloak-oidc-provider',
+// });
export const apis: AnyApiFactory[] = [
createApiFactory({
api: scmIntegrationsApiRef,
@@ -16,4 +31,24 @@ export const apis: AnyApiFactory[] = [
factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi),
}),
ScmAuth.createDefaultApiFactory(),
+ createApiFactory({
+ api: keycloakOIDCAuthApiRef,
+ deps: {
+ discoveryApi: discoveryApiRef,
+ oauthRequestApi: oauthRequestApiRef,
+ configApi: configApiRef,
+ },
+ factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
+ OAuth2.create({
+ discoveryApi,
+ oauthRequestApi,
+ provider: {
+ id: 'keycloak-oidc',
+ title: 'Keycloak OIDC',
+ icon: () => null,
+ },
+ environment: configApi.getOptionalString('auth.environment'),
+ defaultScopes: ['openid', 'profile', 'email', 'groups'],
+ }),
+ }),
];
diff --git a/packages/backend/src/plugins/auth.ts b/packages/backend/src/plugins/auth.ts
index 9790887..4042c59 100644
--- a/packages/backend/src/plugins/auth.ts
+++ b/packages/backend/src/plugins/auth.ts
@@ -18,70 +18,91 @@ export default async function createPlugin(
tokenManager: env.tokenManager,
providerFactories: {
...defaultAuthProviderFactories,
- oauth2Proxy: providers.oauth2Proxy.create({
+ 'keycloak-oidc': providers.oidc.create({
signIn: {
- async resolver({ result }, ctx) {
- console.log(result)
- const name = result.getHeader('x-forwarded-preferred-username');
- if (!name) {
- throw new Error('Request did not contain a user');
- }
-
- try {
- // Attempts to sign in existing user
- const signedInUser = await ctx.signInWithCatalogUser({
- entityRef: { name },
- });
-
- return Promise.resolve(signedInUser);
- } catch (e) {
- // Create stub user
- const userEntityRef = stringifyEntityRef({
- kind: 'User',
- name: name,
- namespace: DEFAULT_NAMESPACE,
- });
- return ctx.issueToken({
- claims: {
- sub: userEntityRef,
- ent: [userEntityRef],
- },
- });
- }
+ resolver(info, ctx) {
+ const userRef = stringifyEntityRef({
+ kind: 'User',
+ name: info.result.userinfo.sub,
+ namespace: DEFAULT_NAMESPACE,
+ });
+ console.log(info.result.userinfo.groups)
+ return ctx.issueToken({
+ claims: {
+ sub: userRef, // The user's own identity
+ ent: [userRef], // A list of identities that the user claims ownership through
+ },
+ });
},
},
}),
- // This replaces the default GitHub auth provider with a customized one.
- // The `signIn` option enables sign-in for this provider, using the
- // identity resolution logic that's provided in the `resolver` callback.
- //
- // This particular resolver makes all users share a single "guest" identity.
- // It should only be used for testing and trying out Backstage.
- //
- // If you want to use a production ready resolver you can switch to
- // the one that is commented out below, it looks up a user entity in the
- // catalog using the GitHub username of the authenticated user.
- // That resolver requires you to have user entities populated in the catalog,
- // for example using https://backstage.io/docs/integrations/github/org
- //
- // There are other resolvers to choose from, and you can also create
- // your own, see the auth documentation for more details:
- //
- // https://backstage.io/docs/auth/identity-resolver
- // github: providers.github.create({
- // signIn: {
- // resolver(_, ctx) {
- // const userRef = 'user:default/guest'; // Must be a full entity reference
- // return ctx.issueToken({
- // claims: {
- // sub: userRef, // The user's own identity
- // ent: [userRef], // A list of identities that the user claims ownership through
- // },
- // });
- // },
- // // resolver: providers.github.resolvers.usernameMatchingUserEntityName(),
- // },
- // }),
},
+ // providerFactories: {
+ // ...defaultAuthProviderFactories,
+ // oauth2Proxy: providers.oauth2Proxy.create({
+ // signIn: {
+ // async resolver({ result }, ctx) {
+ // console.log(result)
+ // const name = result.getHeader('x-forwarded-preferred-username');
+ // if (!name) {
+ // throw new Error('Request did not contain a user');
+ // }
+ //
+ // try {
+ // // Attempts to sign in existing user
+ // const signedInUser = await ctx.signInWithCatalogUser({
+ // entityRef: { name },
+ // });
+ //
+ // return Promise.resolve(signedInUser);
+ // } catch (e) {
+ // // Create stub user
+ // const userEntityRef = stringifyEntityRef({
+ // kind: 'User',
+ // name: name,
+ // namespace: DEFAULT_NAMESPACE,
+ // });
+ // return ctx.issueToken({
+ // claims: {
+ // sub: userEntityRef,
+ // ent: [userEntityRef],
+ // },
+ // });
+ // }
+ // },
+ // },
+ // }),
+ // // This replaces the default GitHub auth provider with a customized one.
+ // // The `signIn` option enables sign-in for this provider, using the
+ // // identity resolution logic that's provided in the `resolver` callback.
+ // //
+ // // This particular resolver makes all users share a single "guest" identity.
+ // // It should only be used for testing and trying out Backstage.
+ // //
+ // // If you want to use a production ready resolver you can switch to
+ // // the one that is commented out below, it looks up a user entity in the
+ // // catalog using the GitHub username of the authenticated user.
+ // // That resolver requires you to have user entities populated in the catalog,
+ // // for example using https://backstage.io/docs/integrations/github/org
+ // //
+ // // There are other resolvers to choose from, and you can also create
+ // // your own, see the auth documentation for more details:
+ // //
+ // // https://backstage.io/docs/auth/identity-resolver
+ // // github: providers.github.create({
+ // // signIn: {
+ // // resolver(_, ctx) {
+ // // const userRef = 'user:default/guest'; // Must be a full entity reference
+ // // return ctx.issueToken({
+ // // claims: {
+ // // sub: userRef, // The user's own identity
+ // // ent: [userRef], // A list of identities that the user claims ownership through
+ // // },
+ // // });
+ // // },
+ // // // resolver: providers.github.resolvers.usernameMatchingUserEntityName(),
+ // // },
+ // // }),
+ // },
});
}
diff --git a/plugins/workflows/src/components/BlueprintComponent/FetchTFState.tsx b/plugins/workflows/src/components/BlueprintComponent/FetchTFState.tsx
index 05f5ef3..c90d2d6 100644
--- a/plugins/workflows/src/components/BlueprintComponent/FetchTFState.tsx
+++ b/plugins/workflows/src/components/BlueprintComponent/FetchTFState.tsx
@@ -5,8 +5,8 @@ import useAsync from 'react-use/lib/useAsync';
import {
DiscoveryApi,
- discoveryApiRef,
- useApi,
+ discoveryApiRef, OpenIdConnectApi, fetchApiRef,
+ useApi, FetchApi,
} from '@backstage/core-plugin-api';
// eslint-disable-next-line no-restricted-imports
import {gunzipSync} from "zlib";
@@ -22,8 +22,7 @@ import {
import DeleteIcon from "@material-ui/icons/Delete";
import ClearIcon from "@material-ui/icons/Clear";
import LinkOffRounded from "@material-ui/icons/LinkOffRounded";
-
-const token = "..---"
+import {keycloakOIDCAuthApiRef} from "../../plugin";
type TFState = {
terraform_version: string
@@ -75,9 +74,11 @@ export const TFTable = (props: TFTableProps) => {
export const FetchTFState = () => {
const apiRef = useApi(discoveryApiRef)
const entity = useEntity()
+ const oidcApi = useApi(keycloakOIDCAuthApiRef)
+ const fetchApi = useApi(fetchApiRef)
const secretName = `tfstate-default-${entity.entity.metadata.name}`
const { value, loading, error } = useAsync((): Promise => {
- return getTFState(secretName, "admin", apiRef)
+ return getTFState(secretName, "admin", apiRef, oidcApi, fetchApi)
})
if (loading) {
return
@@ -125,7 +126,8 @@ type payload = {
}
}
-async function getTFState(name: string, namespace: string, apiRef: DiscoveryApi): Promise {
+async function getTFState(name: string, namespace: string, apiRef: DiscoveryApi, oidcRef: OpenIdConnectApi, fetchRef: FetchApi ): Promise {
+ const token = await oidcRef.getIdToken()
const baseUrl = await apiRef.getBaseUrl("kubernetes")
const proxyUrl = `${baseUrl}/proxy`
return new Promise(async (resolve, reject) => {
@@ -133,7 +135,7 @@ async function getTFState(name: string, namespace: string, apiRef: DiscoveryApi)
method: 'GET',
headers: {
'X-Kubernetes-Cluster': "canoe-packaging",
- Authorization: `Bearer ${token}`,
+ 'Authorization': `Bearer ${token}`,
},
});
if (resp.ok) {
diff --git a/plugins/workflows/src/index.ts b/plugins/workflows/src/index.ts
index cca6659..b4097a8 100644
--- a/plugins/workflows/src/index.ts
+++ b/plugins/workflows/src/index.ts
@@ -1 +1,2 @@
-export { workflowsPlugin, EntityWorkflowsContent } from './plugin';
+
+export { workflowsPlugin, EntityWorkflowsContent, keycloakOIDCAuthApiRef } from './plugin';
diff --git a/plugins/workflows/src/plugin.ts b/plugins/workflows/src/plugin.ts
index 13a9b55..0d4552d 100644
--- a/plugins/workflows/src/plugin.ts
+++ b/plugins/workflows/src/plugin.ts
@@ -1,4 +1,10 @@
-import { createPlugin, createRoutableExtension } from '@backstage/core-plugin-api';
+import {
+ ApiRef, BackstageIdentityApi, createApiRef,
+ createPlugin,
+ createRoutableExtension,
+ OpenIdConnectApi,
+ ProfileInfoApi, SessionApi
+} from '@backstage/core-plugin-api';
import { rootCatalogWorkflowsRouteRef } from './routes';
@@ -17,3 +23,9 @@ export const EntityWorkflowsContent = workflowsPlugin.provide(
mountPoint: rootCatalogWorkflowsRouteRef,
}),
);
+
+export const keycloakOIDCAuthApiRef: ApiRef<
+ OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
+> = createApiRef({
+ id: 'auth.keycloak-oidc-provider',
+});
\ No newline at end of file