Skip to content

Commit

Permalink
feat(app-security): add idToken provider (#4168)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel910 authored Jun 13, 2024
1 parent 4eb0c2e commit 71e514d
Show file tree
Hide file tree
Showing 24 changed files with 261 additions and 149 deletions.
3 changes: 2 additions & 1 deletion apps/api/graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@
"src": [
"@webiny/api-tenant-manager",
"@webiny/api-theme-manager",
"@webiny/api-security-okta"
"@webiny/api-security-okta",
"@webiny/api-security-auth0"
]
}
}
Expand Down
108 changes: 108 additions & 0 deletions apps/api/graphql/src/security.auth0.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { DynamoDBDocument } from "@webiny/aws-sdk/client-dynamodb";
import { createTenancyContext, createTenancyGraphQL } from "@webiny/api-tenancy";
import { createStorageOperations as tenancyStorageOperations } from "@webiny/api-tenancy-so-ddb";
import { createSecurityContext, createSecurityGraphQL } from "@webiny/api-security";
import { createStorageOperations as securityStorageOperations } from "@webiny/api-security-so-ddb";
import { authenticateUsingHttpHeader } from "@webiny/api-security/plugins/authenticateUsingHttpHeader";
import apiKeyAuthentication from "@webiny/api-security/plugins/apiKeyAuthentication";
import apiKeyAuthorization from "@webiny/api-security/plugins/apiKeyAuthorization";
import { createAuth0 } from "@webiny/api-security-auth0";
import anonymousAuthorization from "@webiny/api-security/plugins/anonymousAuthorization";
import tenantLinkAuthorization from "@webiny/api-security/plugins/tenantLinkAuthorization";
import createAdminUsersApp from "@webiny/api-admin-users";
import { createStorageOperations as createAdminUsersStorageOperations } from "@webiny/api-admin-users-so-ddb";

export default ({ documentClient }: { documentClient: DynamoDBDocument }) => [
/**
* Create Tenancy app in the `context`.
*/
createTenancyContext({
storageOperations: tenancyStorageOperations({ documentClient })
}),

/**
* Expose tenancy GraphQL schema.
*/
createTenancyGraphQL(),

/**
* Create Security app in the `context`.
*/
createSecurityContext({
storageOperations: securityStorageOperations({ documentClient })
}),

/**
* Expose security GraphQL schema.
*/
createSecurityGraphQL({
async getDefaultTenant(context) {
return context.tenancy.getRootTenant();
}
}),

/**
* Create Admin Users app.
*/
createAdminUsersApp({
storageOperations: createAdminUsersStorageOperations({ documentClient })
}),

/**
* Perform authentication using the common "Authorization" HTTP header.
* This will fetch the value of the header, and execute the authentication process.
*/
authenticateUsingHttpHeader(),

/**
* API Key authenticator.
* API Keys are a standalone entity, and are not connected to users in any way.
* They identify a project, a 3rd party client, not a particular user.
* They are used for programmatic API access, CMS data import/export, etc.
*/
apiKeyAuthentication({ identityType: "api-key" }),

/**
* Configure Auth0 authentication and authorization.
*/
createAuth0({
/**
* `domain` is required for token verification.
*/
domain: String(process.env.AUTH0_DOMAIN),
/**
* Construct the identity object and map token claims to arbitrary identity properties.
*/
getIdentity({ token }) {
return {
id: token["sub"],
type: "admin",
displayName: token["name"],
group: token["webiny_group"]
};
}
}),

/**
* Authorization plugin to fetch permissions for a verified API key.
* The "identityType" must match the authentication plugin used to load the identity.
*/
apiKeyAuthorization({ identityType: "api-key" }),

/**
* Authorization plugin to fetch permissions from a security role or team associated with the identity.
*/
tenantLinkAuthorization({ identityType: "admin" }),

/**
* Authorization plugin to fetch permissions from the parent tenant.
*/
tenantLinkAuthorization({ identityType: "admin", parent: true }),

/**
* Authorization plugin to load permissions for anonymous requests.
* This allows you to control which API resources can be accessed publicly.
* The authorization is performed by loading permissions from the "anonymous" user group.
*/
anonymousAuthorization()
];
8 changes: 4 additions & 4 deletions packages/api-headless-cms-tasks/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
"extends": "../../tsconfig.build.json",
"include": ["src"],
"references": [
{ "path": "../api-headless-cms/tsconfig.build.json" },
{ "path": "../handler/tsconfig.build.json" },
{ "path": "../handler-aws/tsconfig.build.json" },
{ "path": "../tasks/tsconfig.build.json" },
{ "path": "../api/tsconfig.build.json" },
{ "path": "../api-admin-users/tsconfig.build.json" },
{ "path": "../api-headless-cms/tsconfig.build.json" },
{ "path": "../api-i18n/tsconfig.build.json" },
{ "path": "../api-security/tsconfig.build.json" },
{ "path": "../api-tenancy/tsconfig.build.json" },
{ "path": "../api-wcp/tsconfig.build.json" },
{ "path": "../handler-aws/tsconfig.build.json" },
{ "path": "../handler-graphql/tsconfig.build.json" },
{ "path": "../handler/tsconfig.build.json" },
{ "path": "../plugins/tsconfig.build.json" },
{ "path": "../tasks/tsconfig.build.json" },
{ "path": "../wcp/tsconfig.build.json" }
],
"compilerOptions": {
Expand Down
44 changes: 22 additions & 22 deletions packages/api-headless-cms-tasks/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
"extends": "../../tsconfig.json",
"include": ["src", "__tests__"],
"references": [
{ "path": "../api-headless-cms" },
{ "path": "../handler" },
{ "path": "../handler-aws" },
{ "path": "../tasks" },
{ "path": "../api" },
{ "path": "../api-admin-users" },
{ "path": "../api-headless-cms" },
{ "path": "../api-i18n" },
{ "path": "../api-security" },
{ "path": "../api-tenancy" },
{ "path": "../api-wcp" },
{ "path": "../handler" },
{ "path": "../handler-aws" },
{ "path": "../handler-graphql" },
{ "path": "../plugins" },
{ "path": "../tasks" },
{ "path": "../wcp" }
],
"compilerOptions": {
Expand All @@ -23,32 +23,32 @@
"paths": {
"~/*": ["./src/*"],
"~tests/*": ["./__tests__/*"],
"@webiny/api": ["../api/src"],
"@webiny/api-headless-cms/*": ["../api-headless-cms/src/*"],
"@webiny/api-headless-cms": ["../api-headless-cms/src"],
"@webiny/handler/*": ["../handler/src/*"],
"@webiny/handler": ["../handler/src"],
"@webiny/handler-aws/*": ["../handler-aws/src/*"],
"@webiny/handler-aws": ["../handler-aws/src"],
"@webiny/tasks/*": ["../tasks/src/*"],
"@webiny/tasks": ["../tasks/src"],
"@webiny/api/*": ["../api/src/*"],
"@webiny/api-admin-users": ["../api-admin-users/src"],
"@webiny/api": ["../api/src"],
"@webiny/api-admin-users/*": ["../api-admin-users/src/*"],
"@webiny/api-headless-cms": ["../api-headless-cms/src"],
"@webiny/api-headless-cms/*": ["../api-headless-cms/src/*"],
"@webiny/api-i18n": ["../api-i18n/src"],
"@webiny/api-admin-users": ["../api-admin-users/src"],
"@webiny/api-i18n/*": ["../api-i18n/src/*"],
"@webiny/api-security": ["../api-security/src"],
"@webiny/api-i18n": ["../api-i18n/src"],
"@webiny/api-security/*": ["../api-security/src/*"],
"@webiny/api-tenancy": ["../api-tenancy/src"],
"@webiny/api-security": ["../api-security/src"],
"@webiny/api-tenancy/*": ["../api-tenancy/src/*"],
"@webiny/api-wcp": ["../api-wcp/src"],
"@webiny/api-tenancy": ["../api-tenancy/src"],
"@webiny/api-wcp/*": ["../api-wcp/src/*"],
"@webiny/handler": ["../handler/src"],
"@webiny/handler-aws": ["../handler-aws/src"],
"@webiny/handler-aws/*": ["../handler-aws/src/*"],
"@webiny/handler-graphql": ["../handler-graphql/src"],
"@webiny/api-wcp": ["../api-wcp/src"],
"@webiny/handler-graphql/*": ["../handler-graphql/src/*"],
"@webiny/handler/*": ["../handler/src/*"],
"@webiny/plugins": ["../plugins/src"],
"@webiny/handler-graphql": ["../handler-graphql/src"],
"@webiny/plugins/*": ["../plugins/src/*"],
"@webiny/tasks": ["../tasks/src"],
"@webiny/tasks/*": ["../tasks/src/*"],
"@webiny/wcp": ["../wcp/src"],
"@webiny/wcp/*": ["../wcp/src/*"]
"@webiny/plugins": ["../plugins/src"],
"@webiny/wcp/*": ["../wcp/src/*"],
"@webiny/wcp": ["../wcp/src"]
},
"baseUrl": "."
}
Expand Down
4 changes: 2 additions & 2 deletions packages/api-serverless-cms/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
{ "path": "../api-aco/tsconfig.build.json" },
{ "path": "../api-file-manager/tsconfig.build.json" },
{ "path": "../api-form-builder/tsconfig.build.json" },
{ "path": "../handler-graphql/tsconfig.build.json" },
{ "path": "../api-headless-cms/tsconfig.build.json" },
{ "path": "../api-i18n/tsconfig.build.json" },
{ "path": "../api-i18n-content/tsconfig.build.json" },
Expand All @@ -15,7 +14,8 @@
{ "path": "../api-prerendering-service/tsconfig.build.json" },
{ "path": "../api-security/tsconfig.build.json" },
{ "path": "../api-tenancy/tsconfig.build.json" },
{ "path": "../handler-client/tsconfig.build.json" }
{ "path": "../handler-client/tsconfig.build.json" },
{ "path": "../handler-graphql/tsconfig.build.json" }
],
"compilerOptions": {
"rootDir": "./src",
Expand Down
10 changes: 5 additions & 5 deletions packages/api-serverless-cms/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
{ "path": "../api-aco" },
{ "path": "../api-file-manager" },
{ "path": "../api-form-builder" },
{ "path": "../handler-graphql" },
{ "path": "../api-headless-cms" },
{ "path": "../api-i18n" },
{ "path": "../api-i18n-content" },
Expand All @@ -15,7 +14,8 @@
{ "path": "../api-prerendering-service" },
{ "path": "../api-security" },
{ "path": "../api-tenancy" },
{ "path": "../handler-client" }
{ "path": "../handler-client" },
{ "path": "../handler-graphql" }
],
"compilerOptions": {
"rootDirs": ["./src", "./__tests__"],
Expand All @@ -32,8 +32,6 @@
"@webiny/api-file-manager": ["../api-file-manager/src"],
"@webiny/api-form-builder/*": ["../api-form-builder/src/*"],
"@webiny/api-form-builder": ["../api-form-builder/src"],
"@webiny/handler-graphql/*": ["../handler-graphql/src/*"],
"@webiny/handler-graphql": ["../handler-graphql/src"],
"@webiny/api-headless-cms/*": ["../api-headless-cms/src/*"],
"@webiny/api-headless-cms": ["../api-headless-cms/src"],
"@webiny/api-i18n/*": ["../api-i18n/src/*"],
Expand All @@ -51,7 +49,9 @@
"@webiny/api-tenancy/*": ["../api-tenancy/src/*"],
"@webiny/api-tenancy": ["../api-tenancy/src"],
"@webiny/handler-client/*": ["../handler-client/src/*"],
"@webiny/handler-client": ["../handler-client/src"]
"@webiny/handler-client": ["../handler-client/src"],
"@webiny/handler-graphql/*": ["../handler-graphql/src/*"],
"@webiny/handler-graphql": ["../handler-graphql/src"]
},
"baseUrl": "."
}
Expand Down
2 changes: 1 addition & 1 deletion packages/app-admin-auth0/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"license": "Webiny Enterprise",
"dependencies": {
"@apollo/react-hooks": "^3.1.5",
"@auth0/auth0-react": "^1.10.1",
"@auth0/auth0-react": "^2.2.4",
"@emotion/styled": "^11.10.6",
"@webiny/app": "0.0.0",
"@webiny/app-admin": "0.0.0",
Expand Down
7 changes: 6 additions & 1 deletion packages/app-admin-auth0/src/Auth0.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { LoginScreenRenderer, useTenancy, useTags } from "@webiny/app-serverless
import {
createAuthentication,
Auth0Options,
CreateAuthenticationConfig
CreateAuthenticationConfig,
OnLogout
} from "./createAuthentication";
import { UserMenuModule } from "~/modules/userMenu";
import { AppClientModule } from "~/modules/appClient";
Expand All @@ -16,6 +17,7 @@ interface AppClientIdLoaderProps {
auth0: Auth0Options;
rootAppClientId: string;
children: React.ReactNode;
onLogout?: OnLogout;
onError?: CreateAuthenticationConfig["onError"];
}

Expand All @@ -30,6 +32,7 @@ const GET_CLIENT_ID = gql`
const AppClientIdLoader = ({
auth0,
rootAppClientId,
onLogout,
onError,
children
}: AppClientIdLoaderProps) => {
Expand All @@ -50,6 +53,7 @@ const AppClientIdLoader = ({
if (tenantId === "root") {
console.info(`Configuring Auth0 with App Client Id "${rootAppClientId}"`);
authRef.current = createAuthentication({
onLogout,
onError,
auth0: {
...auth0,
Expand Down Expand Up @@ -114,6 +118,7 @@ const createLoginScreenPlugin = (params: Auth0Props) => {
export interface Auth0Props {
auth0: Auth0Options;
rootAppClientId: string;
onLogout?: OnLogout;
children?: React.ReactNode;
}

Expand Down
Loading

0 comments on commit 71e514d

Please sign in to comment.