add comments
Signed-off-by: Aramis <sennyeyaramis@gmail.com> Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>
This commit is contained in:
@@ -27,6 +27,12 @@ import {
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
export const providers = [
|
||||
{
|
||||
id: 'guest-auth-provider',
|
||||
title: 'Guest',
|
||||
message: 'Sign in as a guest',
|
||||
apiRef: guestAuthApiRef,
|
||||
},
|
||||
{
|
||||
id: 'google-auth-provider',
|
||||
title: 'Google',
|
||||
@@ -75,10 +81,4 @@ export const providers = [
|
||||
message: 'Sign In using Bitbucket Server',
|
||||
apiRef: bitbucketServerAuthApiRef,
|
||||
},
|
||||
{
|
||||
id: 'guest-auth-provider',
|
||||
title: 'Guest',
|
||||
message: 'Sign in as a guest',
|
||||
apiRef: guestAuthApiRef,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -41,7 +41,7 @@ const DEFAULT_PROVIDER = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements a guest auth flow.
|
||||
* Implements a guest auth flow. Heavily based on SAML flow with added support for refreshing the token.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
|
||||
import { DirectAuthConnector } from './DirectAuthConnector';
|
||||
|
||||
/**
|
||||
* Add support for refreshing direct tokens. Used for guest authentication.
|
||||
*/
|
||||
export class RefreshingDirectAuthConnector<
|
||||
DirectAuthResponse,
|
||||
> extends DirectAuthConnector<DirectAuthResponse> {
|
||||
/**
|
||||
* Pulled from DefaultAuthConnector and adapted for use with DirectAuthConnector.
|
||||
*/
|
||||
async refreshSession(): Promise<any> {
|
||||
const res = await fetch(
|
||||
`${await this.buildUrl('/refresh')}&optional=true`,
|
||||
|
||||
@@ -21,17 +21,21 @@ import type {
|
||||
SignInResolver,
|
||||
} from '@backstage/plugin-auth-node';
|
||||
import { createGuestAuthRouteHandlers } from './createGuestAuthRouteHandlers';
|
||||
import { GuestInfo } from './types';
|
||||
import { guestResolver } from './resolvers';
|
||||
|
||||
const defaultTransform: ProfileTransform<{}> = async () => {
|
||||
return {
|
||||
profile: {
|
||||
displayName: 'Guest',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export function createGuestAuthProviderFactory(options?: {
|
||||
profileTransform?: ProfileTransform<GuestInfo>;
|
||||
signInResolver?: SignInResolver<GuestInfo>;
|
||||
signInResolverFactories?: Record<
|
||||
string,
|
||||
SignInResolverFactory<GuestInfo, unknown>
|
||||
>;
|
||||
profileTransform?: ProfileTransform<{}>;
|
||||
signInResolver?: SignInResolver<{}>;
|
||||
signInResolverFactories?: Record<string, SignInResolverFactory<{}, unknown>>;
|
||||
}): AuthProviderFactory {
|
||||
return ctx => {
|
||||
const signInResolver = options?.signInResolver ?? guestResolver();
|
||||
@@ -41,6 +45,7 @@ export function createGuestAuthProviderFactory(options?: {
|
||||
`No sign-in resolver configured for guest auth provider '${ctx.providerId}'`,
|
||||
);
|
||||
}
|
||||
const profileTransform = options?.profileTransform ?? defaultTransform;
|
||||
|
||||
return createGuestAuthRouteHandlers({
|
||||
signInResolver,
|
||||
@@ -48,7 +53,7 @@ export function createGuestAuthProviderFactory(options?: {
|
||||
appUrl: ctx.appUrl,
|
||||
config: ctx.config,
|
||||
resolverContext: ctx.resolverContext,
|
||||
profileTransform: options?.profileTransform,
|
||||
profileTransform,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
prepareBackstageIdentityResponse,
|
||||
sendWebMessageResponse,
|
||||
} from '@backstage/plugin-auth-node';
|
||||
import { GuestInfo } from './types';
|
||||
|
||||
/** @public */
|
||||
export interface GuestAuthRouteHandlersOptions {
|
||||
@@ -33,77 +32,61 @@ export interface GuestAuthRouteHandlersOptions {
|
||||
baseUrl: string;
|
||||
appUrl: string;
|
||||
resolverContext: AuthResolverContext;
|
||||
signInResolver: SignInResolver<GuestInfo>;
|
||||
profileTransform?: ProfileTransform<GuestInfo>;
|
||||
signInResolver: SignInResolver<{}>;
|
||||
profileTransform: ProfileTransform<{}>;
|
||||
}
|
||||
|
||||
const DEFAULT_RESULT: GuestInfo = { name: 'Guest' };
|
||||
|
||||
/** @public */
|
||||
export function createGuestAuthRouteHandlers(
|
||||
options: GuestAuthRouteHandlersOptions,
|
||||
): AuthProviderRouteHandlers {
|
||||
const { resolverContext, signInResolver, appUrl } = options;
|
||||
const { resolverContext, signInResolver, appUrl, profileTransform } = options;
|
||||
|
||||
const createGuestSession = async (): Promise<ClientAuthResponse<{}>> => {
|
||||
const { profile } = await profileTransform({}, resolverContext);
|
||||
|
||||
const identity = await signInResolver(
|
||||
{ profile, result: {} },
|
||||
resolverContext,
|
||||
);
|
||||
|
||||
const defaultTransform: ProfileTransform<GuestInfo> = async result => {
|
||||
return {
|
||||
profile: {
|
||||
displayName: result.name,
|
||||
},
|
||||
profile,
|
||||
providerInfo: {},
|
||||
backstageIdentity: prepareBackstageIdentityResponse(identity),
|
||||
};
|
||||
};
|
||||
|
||||
const profileTransform = options.profileTransform ?? defaultTransform;
|
||||
return {
|
||||
async start(_, res): Promise<void> {
|
||||
// We are the auth provider for guests, skip this step.
|
||||
res.redirect('handler/frame');
|
||||
},
|
||||
|
||||
/**
|
||||
* This is where we create the token for the guest user. You can override the
|
||||
* entityRef for the guest user with `signInResolver`.
|
||||
*/
|
||||
async frameHandler(_, res): Promise<void> {
|
||||
const { profile } = await profileTransform(
|
||||
DEFAULT_RESULT,
|
||||
resolverContext,
|
||||
);
|
||||
const response: ClientAuthResponse<GuestInfo> = {
|
||||
profile,
|
||||
providerInfo: DEFAULT_RESULT,
|
||||
};
|
||||
if (signInResolver) {
|
||||
const identity = await signInResolver(
|
||||
{ profile, result: DEFAULT_RESULT },
|
||||
resolverContext,
|
||||
);
|
||||
response.backstageIdentity = prepareBackstageIdentityResponse(identity);
|
||||
}
|
||||
const session = await createGuestSession();
|
||||
// post message back to popup if successful
|
||||
sendWebMessageResponse(res, appUrl, {
|
||||
type: 'authorization_response',
|
||||
response,
|
||||
response: session,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Support refreshing the guest user's token. This should just improve the experience of
|
||||
* browsing while in guest mode.
|
||||
*/
|
||||
async refresh(this: never, _: Request, res: Response): Promise<void> {
|
||||
const { profile } = await profileTransform(
|
||||
DEFAULT_RESULT,
|
||||
resolverContext,
|
||||
);
|
||||
|
||||
const identity = await signInResolver(
|
||||
{ profile, result: DEFAULT_RESULT },
|
||||
resolverContext,
|
||||
);
|
||||
|
||||
const response: ClientAuthResponse<{}> = {
|
||||
profile,
|
||||
providerInfo: DEFAULT_RESULT,
|
||||
backstageIdentity: prepareBackstageIdentityResponse(identity),
|
||||
};
|
||||
|
||||
res.status(200).json(response);
|
||||
const session = await createGuestSession();
|
||||
res.status(200).json(session);
|
||||
},
|
||||
|
||||
async logout(_, res) {
|
||||
// If we don't send a response or it gets cached into a 204, the page will hang.
|
||||
res.end();
|
||||
},
|
||||
};
|
||||
|
||||
@@ -21,5 +21,4 @@
|
||||
*/
|
||||
|
||||
export { createGuestAuthProviderFactory } from './createGuestAuthFactory';
|
||||
export type { GuestInfo } from './types';
|
||||
export { authModuleGuestProvider as default } from './module';
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
import { stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { createSignInResolverFactory } from '@backstage/plugin-auth-node';
|
||||
|
||||
/**
|
||||
* Provide a default implementation of the user to resolve to. By default, this
|
||||
* is `user:default/guest`. We will attempt to get that user if they're in the
|
||||
* catalog. If that user doesn't exist in the catalog, we will still create a
|
||||
* token for them so they can keep viewing.
|
||||
*/
|
||||
export const guestResolver = createSignInResolverFactory({
|
||||
create() {
|
||||
return async (_, ctx) => {
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
|
||||
import { ProfileTransform } from '@backstage/plugin-auth-node';
|
||||
|
||||
export type GuestInfo = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export interface GuestAuthenticator {
|
||||
defaultProfileTransform: ProfileTransform<GuestInfo>;
|
||||
defaultProfileTransform: ProfileTransform<{}>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user