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

CWP, new security, and multi-tenancy #1993

Merged
merged 57 commits into from
Oct 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
e18d574
wip: security
Pavel910 Sep 4, 2021
f5a1917
wip: security
Pavel910 Sep 19, 2021
2193062
wip: security storage operations
Pavel910 Sep 28, 2021
5702aae
merge: pull next branch
Pavel910 Sep 28, 2021
14456c9
merge: pull next branch
Pavel910 Sep 28, 2021
d7647c2
wip: security tests
Pavel910 Sep 29, 2021
104e99b
wip: security framework and storage ops
Pavel910 Sep 29, 2021
4e5162f
wip: admin users application
Pavel910 Sep 30, 2021
630886f
wip: security and admin users
Pavel910 Oct 6, 2021
78e85f3
wip: finished migration
Pavel910 Oct 7, 2021
607600e
wip: finished single-tenant setup with Cognito
Pavel910 Oct 8, 2021
783a024
wip: polish admin users
Pavel910 Oct 8, 2021
524af30
wip: merge next
Pavel910 Oct 8, 2021
eda6d79
wip: update package versions
Pavel910 Oct 8, 2021
cdebd00
wip: merge next
Pavel910 Oct 8, 2021
a3fe5b3
wip: install the latest yarn
Pavel910 Oct 8, 2021
225c724
wip: improve cognito setup in React
Pavel910 Oct 10, 2021
a376f29
wip: add password validator factoy
Pavel910 Oct 10, 2021
7713872
wip: update TS configs
Pavel910 Oct 10, 2021
9ddac87
wip: update TS configs
Pavel910 Oct 10, 2021
0b6e1a8
wip: tenant switching
Pavel910 Oct 12, 2021
f30bbf0
feat: multi-tenancy
Pavel910 Oct 14, 2021
171a196
fix: don't run isInstalled queries if version is set in localStorage
Pavel910 Oct 16, 2021
f6ed105
merge: pull changes from next
Pavel910 Oct 18, 2021
779bedf
wip: generate tsconfigs and fix adio
Pavel910 Oct 18, 2021
acf17f7
feat: add hooks API to Form
Pavel910 Oct 18, 2021
b6bcefe
feat(cwp-template-aws): split template files for ddb and ddb+es
brunozoric Oct 20, 2021
83bcc3f
feat(cwp-template-aws): add storage ops to setup process
brunozoric Oct 20, 2021
5623c5f
fix(cwp-template-aws): common template path
brunozoric Oct 20, 2021
1272fa2
fix(cwp-template-aws): default storage operations parameter
brunozoric Oct 20, 2021
5ec4117
refactor(api-form-builder): remove all references to elasticsearch
brunozoric Oct 20, 2021
52d02da
chore: update Form types, licenses, tools
Pavel910 Oct 21, 2021
33e7726
wip: Okta multi-tenancy
Pavel910 Oct 21, 2021
bfa338e
refactor: replace SecurityIdentity class with a POJO and a TS interface
Pavel910 Oct 21, 2021
af75a07
chore: merge next and update package versions
Pavel910 Oct 22, 2021
a9c6949
fix: update FM tests with new tenancy/security
Pavel910 Oct 22, 2021
e2dc5c8
fix: update FB tests with new tenancy/security
Pavel910 Oct 22, 2021
f8df1e5
fix: update headless CMS tests
Pavel910 Oct 22, 2021
2fd7cd9
feat: split app setup into app (context) and graphql factories
Pavel910 Oct 22, 2021
05aba4f
fix(app-tenant-manager): polish the UI
Pavel910 Oct 24, 2021
0a7b773
wip: update tests with new security
Pavel910 Oct 24, 2021
a5c6a1a
fix: update all tests with new security
Pavel910 Oct 24, 2021
d79a557
fix: update deps and ts configs
Pavel910 Oct 24, 2021
0c3ff33
fix: add webinyVersion attribute
Pavel910 Oct 24, 2021
0e79eb0
fix: run prettier
Pavel910 Oct 25, 2021
d90cadc
fix: update cypress tests
Pavel910 Oct 25, 2021
f305fb9
chore: generate yarn.lock
Pavel910 Oct 25, 2021
f0e0eb4
merge: pull in the new CWP template
Pavel910 Oct 25, 2021
24aaeb8
fix: update CWP template
Pavel910 Oct 25, 2021
e7b6b37
chore: generate yarn.lock
Pavel910 Oct 25, 2021
af133b6
chore: update dependency name
Pavel910 Oct 26, 2021
8c656d2
chore: update dependency name
Pavel910 Oct 26, 2021
02c05ef
fix: add missing template option
Pavel910 Oct 26, 2021
bca57e5
fix: add missing template option
Pavel910 Oct 26, 2021
e39d903
Merge remote-tracking branch 'origin/merge/security-cwp' into merge/s…
Pavel910 Oct 26, 2021
2f8f6d5
chore: generate yarn.lock
Pavel910 Oct 26, 2021
642493c
fix: rely on WEBINY_MULTI_TENANCY environment variable
Pavel910 Oct 26, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/workflows/nextPush.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ jobs:
npx create-webiny-project@next test-project
--tag next --no-interactive
--assign-to-yarnrc '{"npmRegistryServer":"http://localhost:4873","unsafeHttpWhitelist":["localhost"]}'
--template-options '{"region":"eu-central-1"}'
--template-options '{"region":"eu-central-1","storageOperations":"ddb-es"}'

e2e-tests:
needs: [cache-keys, verdaccio-publish]
Expand Down Expand Up @@ -299,7 +299,7 @@ jobs:
npx create-webiny-project@next test-project
--tag next --no-interactive
--assign-to-yarnrc '{"npmRegistryServer":"http://localhost:4873","unsafeHttpWhitelist":["localhost"]}'
--template-options '{"region":"eu-central-1"}'
--template-options '{"region":"eu-central-1","storageOperations":"ddb-es"}'

- name: Cache project files
uses: actions/cache@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pullRequests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ jobs:
npx create-webiny-project@next test-project
--tag next --no-interactive
--assign-to-yarnrc '{"npmRegistryServer":"http://localhost:4873","unsafeHttpWhitelist":["localhost"]}'
--template-options '{"region":"eu-central-1"}'
--template-options '{"region":"eu-central-1","storageOperations":"ddb-es"}'

- name: Build "api" project application
working-directory: test-project
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/v5Push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ jobs:
npx create-webiny-project@next test-project
--tag next --no-interactive
--assign-to-yarnrc '{"npmRegistryServer":"http://localhost:4873","unsafeHttpWhitelist":["localhost"]}'
--template-options '{"region":"eu-central-1"}'
--template-options '{"region":"eu-central-1","storageOperations":"ddb-es"}'

e2e-tests:
needs: [cache-keys, verdaccio-publish]
Expand Down Expand Up @@ -306,7 +306,7 @@ jobs:
npx create-webiny-project@next test-project
--tag next --no-interactive
--assign-to-yarnrc '{"npmRegistryServer":"http://localhost:4873","unsafeHttpWhitelist":["localhost"]}'
--template-options '{"region":"eu-central-1"}'
--template-options '{"region":"eu-central-1","storageOperations":"ddb-es"}'

- name: Cache project files
uses: actions/cache@v2
Expand Down
328 changes: 164 additions & 164 deletions .yarn/releases/yarn-3.0.0.cjs → .yarn/releases/yarn-3.0.2.cjs
100755 → 100644

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ packageExtensions:
peerDependencies:
react-dom: ^16.14.0

yarnPath: .yarn/releases/yarn-3.0.0.cjs
yarnPath: .yarn/releases/yarn-3.0.2.cjs
9 changes: 7 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
MIT License
Copyright (c) Webiny Ltd.

Copyright (c) 2018 Webiny
Portions of this software are licensed as follows:

* All content that resides under the "enterprise/" directories of this repository, is licensed under the license defined in their respective "enterprise/LICENSE" file.
* All content that resides under the "packages/" sub-directories of this repository, is licensed under the license defined in their respective "packages/*/LICENSE" file.
* All third party components incorporated into the Webiny Software are licensed under the original license provided by the owner of the applicable component.
* Content outside of the above mentioned directories or restrictions above is available under the "MIT" license as defined below.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
9 changes: 5 additions & 4 deletions api/code/graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"watch": "yarn webiny run watch"
},
"dependencies": {
"@webiny/api-admin-users-cognito": "^5.16.0",
"@webiny/api-admin-users-cognito-so-ddb": "^5.16.0",
"@webiny/api-elasticsearch": "^5.16.0",
"@webiny/api-file-manager": "^5.16.0",
"@webiny/api-file-manager-ddb-es": "^5.16.0",
Expand All @@ -23,11 +25,10 @@
"@webiny/api-page-builder-so-ddb-es": "^5.16.0",
"@webiny/api-prerendering-service": "^5.16.0",
"@webiny/api-security": "^5.16.0",
"@webiny/api-security-admin-users": "^5.16.0",
"@webiny/api-security-admin-users-cognito": "^5.16.0",
"@webiny/api-security-admin-users-so-ddb": "^5.16.0",
"@webiny/api-security-cognito-authentication": "^5.16.0",
"@webiny/api-security-cognito": "^5.16.0",
"@webiny/api-security-so-ddb": "^5.16.0",
"@webiny/api-tenancy": "^5.16.0",
"@webiny/api-tenancy-so-ddb": "^5.16.0",
"@webiny/cli": "^5.16.0",
"@webiny/db-dynamodb": "^5.16.0",
"@webiny/handler": "^5.16.0",
Expand Down
15 changes: 4 additions & 11 deletions api/code/graphql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import graphqlPlugins from "@webiny/handler-graphql";
import i18nPlugins from "@webiny/api-i18n/graphql";
import i18nDynamoDbStorageOperations from "@webiny/api-i18n-ddb";
import i18nContentPlugins from "@webiny/api-i18n-content/plugins";
import adminUsersPlugins from "@webiny/api-security-admin-users";
import securityAdminUsersDynamoDbStorageOperations from "@webiny/api-security-admin-users-so-ddb";
import pageBuilderPlugins from "@webiny/api-page-builder/graphql";
import pageBuilderDynamoDbElasticsearchPlugins from "@webiny/api-page-builder-so-ddb-es";
import pageBuilderPrerenderingPlugins from "@webiny/api-page-builder/prerendering";
Expand All @@ -21,11 +19,11 @@ import fileManagerDynamoDbElasticStorageOperation from "@webiny/api-file-manager
import logsPlugins from "@webiny/handler-logs";
import fileManagerS3 from "@webiny/api-file-manager-s3";
import { createFormBuilder } from "@webiny/api-form-builder";
import securityPlugins from "./security";
import { createFormBuilderStorageOperations } from "@webiny/api-form-builder-so-ddb-es";
import headlessCmsPlugins from "@webiny/api-headless-cms/plugins";
import headlessCmsDynamoDbElasticStorageOperation from "@webiny/api-headless-cms-ddb-es";
import elasticsearchDataGzipCompression from "@webiny/api-elasticsearch/plugins/GzipCompression";
import { createFormBuilderStorageOperations } from "@webiny/api-form-builder-so-ddb-es";
import securityPlugins from "./security";

// Imports plugins created via scaffolding utilities.
import scaffoldsPlugins from "./plugins/scaffolds";
Expand All @@ -50,17 +48,14 @@ export const handler = createHandler({
elasticSearch(elasticsearchClient),
dbPlugins({
table: process.env.DB_TABLE,
driver: new DynamoDbDriver({
documentClient
})
driver: new DynamoDbDriver({ documentClient })
}),
securityPlugins(),
securityPlugins({ documentClient }),
i18nPlugins(),
i18nDynamoDbStorageOperations(),
i18nContentPlugins(),
fileManagerPlugins(),
fileManagerDynamoDbElasticStorageOperation(),
// Add File storage S3 plugin for API file manager.
fileManagerS3(),
prerenderingServicePlugins({
handlers: {
Expand All @@ -72,8 +67,6 @@ export const handler = createHandler({
}
}
}),
adminUsersPlugins(),
securityAdminUsersDynamoDbStorageOperations(),
pageBuilderPlugins(),
pageBuilderDynamoDbElasticsearchPlugins(),
pageBuilderPrerenderingPlugins(),
Expand Down
96 changes: 57 additions & 39 deletions api/code/graphql/src/security.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,75 @@
import tenancy from "@webiny/api-tenancy";
import security from "@webiny/api-security";
import personalAccessTokenAuthentication from "@webiny/api-security-admin-users/authentication/personalAccessToken";
import apiKeyAuthentication from "@webiny/api-security-admin-users/authentication/apiKey";
import userAuthorization from "@webiny/api-security-admin-users/authorization/user";
import apiKeyAuthorization from "@webiny/api-security-admin-users/authorization/apiKey";
import anonymousAuthorization from "@webiny/api-security-admin-users/authorization/anonymous";
import cognitoAuthentication from "@webiny/api-security-cognito-authentication";
import cognitoIdentityProvider from "@webiny/api-security-admin-users-cognito";
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 groupAuthorization from "@webiny/api-security/plugins/groupAuthorization";
import parentTenantGroupAuthorization from "@webiny/api-security/plugins/parentTenantGroupAuthorization";
import cognitoAuthentication from "@webiny/api-security-cognito";
import anonymousAuthorization from "@webiny/api-security/plugins/anonymousAuthorization";
import createAdminUsersApp from "@webiny/api-admin-users-cognito";
import { syncWithCognito } from "@webiny/api-admin-users-cognito/syncWithCognito";
import { createStorageOperations as createAdminUsersStorageOperations } from "@webiny/api-admin-users-cognito-so-ddb";

export default () => [
export default ({ documentClient }) => [
/**
* Security Tenancy API (context, users, groups, tenant links).
* This will setup the complete GraphQL schema to manage users, groups, access tokens,
* and provide you with a TenancyContext to access current Tenant data and DB operations.
* Create Tenancy app in the `context`.
*/
tenancy(),
createTenancyContext({
storageOperations: tenancyStorageOperations({ documentClient })
}),

/**
* Cognito IDP plugin (hooks for User CRUD methods).
* This plugin will perform CRUD operations on Cognito when you do something with the user
* via the UI or API. It's mostly to push changes to Cognito when they happen in your app.
*
* It also extends the GraphQL schema with things like "password", which we don't handle
* natively in our security, but Cognito will handle it for us.
* Expose tenancy GraphQL schema.
*/
cognitoIdentityProvider({
region: process.env.COGNITO_REGION,
userPoolId: process.env.COGNITO_USER_POOL_ID
createTenancyGraphQL(),

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

/**
* Adds a context plugin to process `security-authentication` plugins.
* NOTE: this has to be registered *after* the "tenancy" plugins
* as some of the authentication plugins rely on tenancy context.
* Expose security GraphQL schema.
*/
security(),
createSecurityGraphQL(),

/**
* Authentication plugin for Personal Access Tokens.
* PATs are directly linked to Users. We consider a token to be valid, if we manage to load
* a User who owns this particular token. The "identityType" is important, and it has to match
* the "identityType" configured in the authorization plugin later in this file.
* Create Admin Users app.
*/
personalAccessTokenAuthentication({ identityType: "admin" }),
createAdminUsersApp({
storageOperations: createAdminUsersStorageOperations({ documentClient })
}),

/**
* Authentication plugin for API Keys.
* Sync Admin Users with Cognito User Pool.
*/
syncWithCognito({
region: process.env.COGNITO_REGION,
userPoolId: process.env.COGNITO_USER_POOL_ID
}),

/**
* 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 the user.
* 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" }),

/**
* Cognito authentication plugin.
* This plugin will verify the JWT token against a provided User Pool.
* This plugin will verify the JWT token against the provided User Pool.
*/
cognitoAuthentication({
region: process.env.COGNITO_REGION,
Expand All @@ -69,11 +84,14 @@ export default () => [
apiKeyAuthorization({ identityType: "api-key" }),

/**
* Authorization plugin to load user permissions for requested tenant.
* The authorization will only be performed on identities whose "type" matches
* the provided "identityType".
* Authorization plugin to fetch permissions from a security group associated with the identity.
*/
groupAuthorization({ identityType: "admin" }),

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

/**
* Authorization plugin to load permissions for anonymous requests.
Expand Down
20 changes: 7 additions & 13 deletions api/code/graphql/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
{
"path": "../../../packages/api-security"
},
{
"path": "../../../packages/api-security-okta"
},
{
"path": "../../../packages/api-i18n-content"
},
Expand All @@ -36,13 +39,10 @@
"path": "../../../packages/api-tenancy"
},
{
"path": "../../../packages/api-security-admin-users"
},
{
"path": "../../../packages/api-security-admin-users-cognito"
"path": "../../../packages/api-admin-users-cognito"
},
{
"path": "../../../packages/api-security-admin-users-so-ddb"
"path": "../../../packages/api-admin-users-cognito-so-ddb"
},
{
"path": "../../../packages/api-headless-cms"
Expand Down Expand Up @@ -156,14 +156,8 @@
"@webiny/api-headless-cms": ["../../../packages/api-headless-cms/src"],
"@webiny/api-headless-cms-ddb-es/*": ["../../../packages/api-headless-cms-ddb-es/src/*"],
"@webiny/api-headless-cms-ddb-es": ["../../../packages/api-headless-cms-ddb-es/src"],
"@webiny/api-security-admin-users/*": ["../../../packages/api-security-admin-users/src/*"],
"@webiny/api-security-admin-users": ["../../../packages/api-security-admin-users/src"],
"@webiny/api-security-admin-users-cognito/*": [
"../../../packages/api-security-admin-users-cognito/src/*"
],
"@webiny/api-security-admin-users-cognito": [
"../../../packages/api-security-admin-users-cognito/src"
],
"@webiny/api-admin-users-cognito/*": ["../../../packages/api-admin-users-cognito/src/*"],
"@webiny/api-admin-users-cognito": ["../../../packages/api-admin-users-cognito/src"],
"@webiny/api-security-cognito-authentication": [
"../../../packages/api-security-cognito-authentication/src"
]
Expand Down
6 changes: 3 additions & 3 deletions api/code/headlessCMS/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
"@webiny/api-i18n-content": "^5.16.0",
"@webiny/api-i18n-ddb": "^5.16.0",
"@webiny/api-security": "^5.16.0",
"@webiny/api-security-admin-users": "^5.16.0",
"@webiny/api-security-admin-users-so-ddb": "^5.16.0",
"@webiny/api-security-cognito-authentication": "^5.16.0",
"@webiny/api-security-cognito": "^5.16.0",
"@webiny/api-security-so-ddb": "^5.16.0",
"@webiny/api-tenancy": "^5.16.0",
"@webiny/api-tenancy-so-ddb": "^5.16.0",
"@webiny/cli": "^5.16.0",
"@webiny/db-dynamodb": "^5.16.0",
"@webiny/handler": "^5.16.0",
Expand Down
16 changes: 7 additions & 9 deletions api/code/headlessCMS/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,34 @@ import headlessCmsPlugins from "@webiny/api-headless-cms/content";
import headlessCmsDynamoDbElasticStorageOperation from "@webiny/api-headless-cms-ddb-es";
import securityPlugins from "./security";
import logsPlugins from "@webiny/handler-logs";
import securityAdminUsersDynamoDbStorageOperations from "@webiny/api-security-admin-users-so-ddb";
import elasticsearchDataGzipCompression from "@webiny/api-elasticsearch/plugins/GzipCompression";

// Imports plugins created via scaffolding utilities.
import scaffoldsPlugins from "./plugins/scaffolds";

const debug = process.env.DEBUG === "true";

const documentClient = new DocumentClient({
convertEmptyValues: true,
region: process.env.AWS_REGION
});

export const handler = createHandler({
plugins: [
dynamoDbPlugins(),
logsPlugins(),
elasticSearch({ endpoint: `https://${process.env.ELASTIC_SEARCH_ENDPOINT}` }),
dbPlugins({
table: process.env.DB_TABLE,
driver: new DynamoDbDriver({
documentClient: new DocumentClient({
convertEmptyValues: true,
region: process.env.AWS_REGION
})
})
driver: new DynamoDbDriver({ documentClient })
}),
securityPlugins(),
securityPlugins({ documentClient }),
i18nPlugins(),
i18nDynamoDbStorageOperations(),
i18nContentPlugins(),
headlessCmsPlugins({ debug }),
headlessCmsDynamoDbElasticStorageOperation(),
scaffoldsPlugins(),
securityAdminUsersDynamoDbStorageOperations(),
elasticsearchDataGzipCompression()
],
http: { debug }
Expand Down