Skip to content
This repository was archived by the owner on Apr 17, 2023. It is now read-only.

Commit 6dc1c42

Browse files
wtrockiEndamachi1990
authored
feat: Keycloak service as wrapper (#1508)
Co-authored-by: Enda <ephelan@redhat.com> Co-authored-by: Manyanda Chitimbo <manyanda.chitimbo@gmail.com>
1 parent c9da51f commit 6dc1c42

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+385
-666
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
id: authinto
3+
title: Authentication and authorization for Graphback
4+
sidebar_label: Introduction
5+
---
6+
7+
Graphback abstracts from the authentication mechanism.
8+
By default Graphback templates come without authentication, but it is easy to retrofit any existing authentication mechanism
9+
on top of Graphback.
10+
11+
With the `GraphbackCRUDService` abstraction developers can add any rules and implement various different authorization policies.
12+
Graphback developers recomend following libraries:
13+
14+
- [Passport.js](http://www.passportjs.org/) if you looking for in application authorization and authentication mechanisms.
15+
- [Keycloak](https://www.keycloak.org/) SSO - Standalone SSO server offering integration with various social OAuth logins and federating users.
16+
17+
Graphback provides out of the box support for Keycloak SSO thanks to @graphback/keycloak-authz that utilizes
18+
https://github.com/aerogear/keycloak-connect-graphql library

docs/authentication/keycloak.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
id: keycloak
3+
title: Out of the box Keycloak based authentication
4+
sidebar_label: Keycloak Auth
5+
---
6+
7+
## Graphback Keycloak Authz
8+
9+
Graphback Keycloak Authz enables [Keycloak](https://www.keycloak.org/) integration in [Graphback](https://graphback.dev) based applications. This enables you to declaratively add authorization capabilities like role based access on top of the CRUD model that is used within Graphback.
10+
11+
12+
This package is designed to work with [`keycloak-connect`](https://www.npmjs.com/package/keycloak-connect) and [`keycloak-connect-graphql`](https://www.npmjs.com/package/keycloak-connect-graphql). `keycloak-connect` is the official Keycloak middleware for Express applications. `keycloak-connect-graphql` provides deeper Keycloak integration into GraphQL servers.
13+
14+
> NOTE: This package is an early alpha and not officially supported by Graphback
15+
16+
## Getting Started
17+
18+
This module requires you to install the following dependencies into your application.
19+
20+
```bash
21+
npm install keycloak-connect
22+
npm install keycloak-connect-graphql
23+
```
24+
25+
Then follow the [Getting started instructions for `keycloak-connect-graphql`](https://github.com/aerogear/keycloak-connect-graphql#getting-started)
26+
27+
Once the getting started instructions are covered, you must create a configuration that defines the authorization rules for each model within your Graphback application.
28+
29+
Here is an example configuration.
30+
31+
```ts
32+
const authConfig = {
33+
Task: {
34+
create: {},
35+
read: {},
36+
update: { roles: ['admin'] },
37+
delete: { roles: ['admin'] },
38+
},
39+
Report: {
40+
create: { roles: ['admin'] },
41+
read: {},
42+
update: { roles: ['admin'] },
43+
delete: { roles: ['admin'] },
44+
},
45+
};
46+
```
47+
48+
With this configuration the following rules are in place.
49+
50+
- All users can create and read `Task` types but only admins can update and delete them.
51+
- Admin users can create, update and delete `Report` types, and all users can read them.
52+
53+
## Example with Graphback Runtime
54+
55+
During server initialization, use the `createKeycloakCRUDService` function to initialize the KeycloakCrudService instances for each model.
56+
57+
The following example shows just the necessary parts to set up the runtime services in Graphback.
58+
59+
```ts
60+
import { ApolloServer } from 'apollo-server-express'
61+
import { createKeycloakCRUDService } from '@graphback/keycloak-authz'
62+
import { KnexDbDataProvider } from '@graphback/runtime-knex'
63+
import { PubSub } from 'graphql-subscriptions'
64+
import * as Knex from 'knex'
65+
import { buildGraphbackAPI, createCRUDService } from 'graphback'
66+
67+
// the application model
68+
const model = `
69+
"""
70+
@model
71+
"""
72+
type Task {
73+
id: ID!
74+
title: String!
75+
description: String!
76+
}`
77+
78+
// the auth rules for the application
79+
const authConfig = {
80+
Task: {
81+
create: {},
82+
read: {},
83+
update: { roles: ["admin"] },
84+
delete: { roles: ["admin"] }
85+
}
86+
}
87+
88+
// set up the Knex database client
89+
const db = Knex({...})
90+
91+
// standard Graphback runtime setup
92+
const pubSub = new PubSub()
93+
94+
const keycloakService = createKeycloakCRUDService(authConfig, createCRUDService({
95+
pubSub: new PubSub()
96+
}));
97+
const { typeDefs, resolvers, contextCreator } = buildGraphbackAPI(modelDefs, {
98+
serviceCreator: keycloakService,
99+
dataProviderCreator: createKnexDbProvider(db)
100+
});
101+
102+
const server = new ApolloServer({
103+
typeDefs,
104+
resolvers,
105+
context: (context) => {
106+
return {
107+
...contextCreator(context),
108+
kauth: new KeycloakContext({ req: context.req })
109+
}
110+
}
111+
})
112+
```
113+
114+
The above example shows runtime set up using the KnexDbDataProvider, but other data providers such as the `MongoDBDataProvider` can also be passed.

docs/releases.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ becomes:
3636
"""
3737
```
3838

39+
### @graphback/runtime package is removed
40+
41+
Runtime package should no longer be used in top level API.
42+
All functionalities were moved to the @graphback/core package.
43+
44+
> NOTE: Users should never have runtime or core packages imported in their
45+
applications and interact with graphback package as aggregator
3946

4047
#### API code generation is no longer supported
4148

docs/subscriptions/introduction.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
id: subintro
3+
title: Live Updates for Graphback
4+
sidebar_label: Live Updates
5+
---
6+
7+
Graphback provides out of the box subscriptions support by providing one of the `PubSubEngines`
8+
from https://github.com/apollographql/graphql-subscriptions library.
9+
Thanks to that developers can connect to any publish subscribe mechanism they have available.
10+
Our templates target to be minimal and unopiniated are using `InMemoryPubSubEngine`
11+
12+
We recomend following engines:
13+
14+
- AMQ (MQTT) using https://github.com/aerogear/graphql-mqtt-subscriptions
15+
- Redis - using https://github.com/davidyaha/graphql-redis-subscriptions
16+
17+
## Subscriptions explained
18+
19+
Graphback provides subscriptions for every type of the operation that is happening on the server.
20+
This means that developers can explicitly subscribe to create, update and delete operations for particular resource.
21+
22+
Subscriptions can be also suppressed by developers by enabling or disabling subscription CRUD flags when initializing Graphback server
23+
24+
```js
25+
{
26+
...
27+
subCreate: true
28+
subUpdate: true
29+
subDelete: true
30+
}
31+
```
32+
33+
## Changing Subscription Topics
34+
35+
Some of the pub sub mechanism will require different format of the topic.
36+
Graphback CRUD services expose method that can be used to override how topics are build.
37+
For example for AMQ we can create extension of the CRUD service as follows
38+
39+
```ts
40+
export class AMQCRUDService extends CrudService {
41+
protected subscriptionTopicMapping(triggerType: GraphbackOperationType, objectName: string) {
42+
// Support AMQ topic creation format
43+
return `graphql/${objectName}_${triggerType}`
44+
}
45+
}
46+
```

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
"codegen-offix-workspace": "yarn workspace @graphback/codegen-offix",
5555
"codegen-client-workspace": "yarn workspace @graphback/codegen-client",
5656
"codegen-schema-workspace": "yarn workspace @graphback/codegen-schema",
57-
"runtime-workspace": "yarn workspace @graphback/runtime",
5857
"datasync-workspace": "yarn workspace @graphback/datasync",
5958
"runtime-knex-workspace": "yarn workspace @graphback/runtime-knex",
6059
"runtime-mongo-workspace": "yarn workspace @graphback/runtime-mongo",

packages/graphback-core/README.md

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,11 @@
1212

1313
## Graphback-Core
1414

15-
Codegen core package is an abstraction that provides common entry point to all graphback generators:
16-
- Client generator
17-
- Schema generator
18-
- Various resolver generators
19-
- Various Service layer generators
20-
- Various DBLayer generators
15+
Core package is an abstraction that provides common entry point to all graphback concepts:
2116

22-
`InputProcessor` abstraction provides seamless way for providing valid input for generators.
17+
- Plugins
18+
- Helpers for building https://graphqlcrud.org schema
19+
- GraphbackCRUDService abstraction
20+
- DataProvider abstraction
2321

24-
> Note: This package is not designed to be used directly.
25-
26-
27-
## Adding support for new inputs types
28-
29-
Graphback-Codegen-Input by default relies on GraphQL schema model as input.
30-
However it can support any type of inputs like json schema, database or OpenAPI definitions.
31-
32-
Developers can extend functionality by using `InputProcessor` abstraction.
33-
34-
## Generator config
35-
36-
Each individual type will contain individual config. Developers can pass global configuration that will be applied to every type
37-
38-
See `GraphbackCRUDGeneratorConfig` for more information.
39-
40-
Config can be modified directly in the schema by utilizing [`graphql-metadata`](graphql-metadata):
41-
42-
## Contributing
43-
44-
`./api` folder contains all types required for creating input processors
45-
`./graphql` folder contains implementation that builds GraphQL based processors
22+
> NOTE: This package is not designed to be used directly.

packages/graphback-core/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@
4343
"graphql-fields-list": "2.1.3",
4444
"graphql-metadata": "0.7.0",
4545
"pino": "6.3.2",
46-
"pluralize": "8.0.0"
46+
"pluralize": "8.0.0",
47+
"dataloader": "2.0.0",
48+
"graphql-subscriptions": "1.1.0"
4749
},
4850
"peerDependencies": {
4951
"graphql": "^14.0.0 || ^15.0.0"

packages/graphback-core/src/index.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ export * from './plugin/GraphbackGlobalConfig'
88
export * from './plugin/GraphbackCRUDGeneratorConfig';
99
export * from './plugin/ModelDefinition'
1010
export * from './plugin/getSelectedFieldsFromResolverInfo';
11-
export * from './utils/printSchemaWithDirectives';
12-
export * from './utils/metadataAnnotations';
1311
export * from './plugin/GraphbackCoreMetadata'
12+
1413
export * from './relationships/RelationshipMetadataBuilder';
1514
export * from './relationships/relationshipHelpers';
16-
export * from './runtime'
17-
export * from './db';
1815
export * from './annotations/DefaultValueAnnotation';
1916

17+
export * from './utils/printSchemaWithDirectives';
18+
export * from './utils/metadataAnnotations';
19+
export * from './utils/fieldTransformHelpers';
20+
21+
export * from './runtime';
22+
export * from './db';

packages/graphback-runtime/src/service/CRUDService.ts renamed to packages/graphback-core/src/runtime/CRUDService.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { GraphbackOperationType, upperCaseFirstChar, GraphbackDataProvider, GraphbackCRUDGeneratorConfig, GraphbackCRUDService, ResultList, GraphbackOrderBy, GraphbackPage, GraphbackContext } from "@graphback/core"
21
import * as DataLoader from "dataloader";
32
import { PubSubEngine } from 'graphql-subscriptions';
3+
import { GraphbackCRUDGeneratorConfig, GraphbackOperationType, upperCaseFirstChar } from '..';
4+
import { GraphbackCRUDService, GraphbackDataProvider, GraphbackContext, GraphbackOrderBy, GraphbackPage, ResultList } from '.';
45

56
/**
67
* Configurations necessary to create a CRUDService
File renamed without changes.

0 commit comments

Comments
 (0)