Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Commit

Permalink
Merge pull request #140 from contember/mail-templates
Browse files Browse the repository at this point in the history
tenant docs improvements
  • Loading branch information
jonasnobile authored Oct 10, 2023
2 parents cacf452 + 5dcd6a8 commit 880432c
Show file tree
Hide file tree
Showing 13 changed files with 432 additions and 233 deletions.
4 changes: 2 additions & 2 deletions docs/intro/graphql.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ The Tenant API facilitates user logins and registrations, membership management,
<DocsCard header="How Tenant API works" href="/reference/engine/tenant/overview">
<p>Basic explanation of Tenant API functionality.</p>
</DocsCard>
<DocsCard header="Managing users" href="/reference/engine/tenant/users">
<p>Manage users in your project over Tenant API.</p>
<DocsCard header="Managing users" href="/reference/engine/tenant/invites">
<p>Invite users to your projects.</p>
</DocsCard>
<DocsCard header="Memberships" href="/reference/engine/tenant/memberships">
<p>Explaining relationship between users and projects.</p>
Expand Down
106 changes: 1 addition & 105 deletions docs/reference/engine/schema/acl.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,112 +151,8 @@ Each variable must be exported from schema definition using `export const ...`

## Tenant permissions

Here, you can also setup [Tenant API] permissions for a role. It is done under the `tenant` field of the role.
See [tenant permissions](./tenant-acl.md)

### Invite permissions

By setting `invite` to `true` you can allow a user to invite other users. Keep in mind, you also need to set appropriate [manage permissions](#manage-permissions) for the role.

There is also `unmanagedInvite` flag, which allows you to invite users using `unmanagedInvite` mutation.

#### Example: enabling invite

```typescript
const editorRole = {
// ...
tenant: {
invite: true,
},
}
```

### Manage permissions

Defines which other roles and their variables a user can manage. First you define a role, which you want to manage as a object key:

```typescript
const editorRole = {
// ...
tenant: {
manage: {
editor: {
// ...
},
},
},
}
```

With this, you would be able to manage users with the role `editor`, but not their variables.

To allow managing all variable, just pass `variables: true`,

```typescript
const editorRole = {
// ...
tenant: {
manage: {
editor: {
variables: true,
},
},
},
}
```

To granularly define which variables a user can manage, you can pass an object with variable names as keys and either `true` or source variable name as a value.

```typescript
const editorRole = {
// ...
tenant: {
manage: {
editor: {
variables: {
language: true,
site: 'assignable_site',
},
},
},
},
}
```

This would allow a user manage `editor` role and assign any value to `language` variable. For `site` variable, user can only assign values from his own `assignable_site` source variable.


## System API permissions

You can also set some flags affecting system API.

### [History API](/reference/engine/content/event-log.md)

By setting `history` flag under `system` section to `true` you can allow a user to access the history API.

```typescript
const editorRole = {
// ...
system: {
history: true,
}
}
```
:::caution
Allowing history API access will allow user to access all the data in history API, ignoring entity rules.
:::

### Migrations

Allow a role to run [migrations](migrations.md). Project admin (and superadmin) can always run migrations. Also, there is a default `deployer` role with this and only permission.

```typescript
const editorRole = {
// ...
system: {
migrations: true,
}
}
```

### Assume identity

Expand Down
87 changes: 87 additions & 0 deletions docs/reference/engine/schema/tenant-acl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: Tenant Permissions
---

The Tenant permissions feature in Contember allows you to fine-tune control over various actions and roles. These permissions are specified under the `tenant` field when you define a role.

## <span className="version">Engine 1.3+</span> Invite Permissions

The `invite` permission controls the ability to invite other users to a project. You can use either a simple boolean value or a more advanced [membership match rule](#understanding-membership-match-rules) object. If `invite` is set to `true`, the existing rules under `manage` will apply.

#### Example: Simple Invite Permission

```typescript
export const editorRole = acl.createRole('editor', {
tenant: {
invite: true,
},
});
```

:::note
Before Engine 1.3, the `invite` and `unmanagedInvite` allowed only a boolean value.
:::

### <span className="version">Engine 1.3+</span> Unmanaged Invite Permissions

Similar to `invite`, the `unmanagedInvite` field can accept a boolean value or a [membership match rule](#understanding-membership-match-rules) object. This permission allows you to use the `unmanagedInvite` mutation.

### <span className="version">Engine 1.3+</span> View Permissions

The `view` field enables you to specify which roles and their associated variables a user can view.

#### Example: View Permissions

```typescript
export const editorRole = acl.createRole('editor', {
tenant: {
view: {
editor: {
variables: {
language: true,
},
},
},
},
});
```

### Manage Permissions

The `manage` field helps you specify the roles and their variables that a user can manage.

#### Example: Manage Permissions

```typescript
export const editorRole = acl.createRole('editor', {
tenant: {
manage: {
editor: {
variables: true,
},
},
},
});
```

## Understanding membership match rules

The membership match rules is an object that enables you to define more granular rules for managing memberships, roles, and variables. It comes into play when you set values for `invite`, `unmanagedInvite`, `view`, and `manage` fields in the `tenant` permissions.

This rule allows you to:

- Define which roles can be managed
- Specify what variables within those roles can be managed

For example, if you only want to allow a user to manage the `editor` role and assign any value to the `language` variable but restrict values for the `site` variable, your rule would look like this:

```typescript
{
editor: {
variables: {
language: true,
site: 'assignable_site',
},
},
}
```
94 changes: 77 additions & 17 deletions docs/reference/engine/tenant/api-keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@
title: API keys management
---

For applications, where you don't identify and authenticate individual users, you can use an API key. These API keys are in fact an identity (without a person) with permanent access token. So you can later manage memberships of users and API keys using the same API.
API keys serve as a way to authenticate applications where individual user identification and authentication are not required. They function as permanent access tokens.

## Create API key
## Create an API Key for a Project

You can create a project-specific API key using the GraphQL API:

### Using GraphQL API
```graphql
mutation {
createApiKey(
projectSlug: "my-blog",
description: "Some user friendly description of the key"
description: "User-friendly description of the key",
memberships: [{role: "editor", variables: [{name: "language", values: ["cs"]}]}]
) {
ok
error {
code
}
result {
result {
apiKey {
id
token
Expand All @@ -31,27 +32,86 @@ mutation {
}
```

This mutations returns 3 identifiers, which might be relevant for you:
- API key ID: using this ID you can later call a `disableApiKey` and invalidate this API key
- identity ID: which you use to modify API key [memberships and permissions](memberships.md)
- token: which is a bearer token, which you use to authenticate all GraphQL requests
This returns three identifiers:

- **API Key ID**: Used for disabling this API key later.
- **Identity ID**: Used to modify the API key's memberships and permissions.
- **Token**: A bearer token used for authenticating your GraphQL requests.

### Using CLI

There is also an interactive CLI command for creating an API key. Run
## Create Global API Key

```graphql
mutation {
createGlobalApiKey(
description: "Global API key description",
roles: ["super_admin", "monitor"]
) {
ok
error {
code
}
result {
apiKey {
id
token
identity {
id
}
}
}
}
}
```
npm run contember tenant:create-api-key
```
and follow the instructions

## Disable API key
This also returns three identifiers similar to creating a project-specific API key.

### Custom Token Generation

Both `createApiKey` and `createGlobalApiKey` support the optional `tokenHash` parameter. If you provide a SHA-256 hash of the token you wish to use, the API will not generate a new token, and the `token` field in the response will be empty. This allows you more control over token management but requires you to securely generate and store the original token yourself.

You need an API key ID to disable it. Do not confuse this id with identity id!
## Add Global Roles to an Identity

```graphql
mutation {
disableApiKey(id: "fb6658f3-a000-4448-ac9e-0688f1afa3d7") {
addGlobalIdentityRoles(
identityId: "some-identity-id",
roles: ["super_admin", "monitor"]
) {
ok
error {
code
}
}
}
```

## Remove Global Roles from an Identity

```graphql
mutation {
removeGlobalIdentityRoles(
identityId: "some-identity-id",
roles: ["monitor"]
) {
ok
error {
code
}
}
}
```



## Disable API Key

```graphql
mutation {
disableApiKey(id: "some-api-key-id") {
ok
}
}
```

Use the API Key ID to disable the API key. Do not confuse this with the Identity ID.
47 changes: 47 additions & 0 deletions docs/reference/engine/tenant/invites.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: User invitations
---

The `invite` mutation provides a way to add a new member to a specified project within the system.

#### Example: sending and invitation

```graphql
mutation {
invite(
email: "[email protected]",
projectSlug: "my-blog",
memberships: [
{
role: "editor",
variables: [{name: "language", values: ["en}]
}
],
options: {
mailVariant: "en_us", # Optional
method: RESET_PASSWORD # Recommended
}
) {
ok
error {
code
}
}
}
```
### Invite permissions
By default, users with the global roles `super_admin` and `project_admin`, along with project-level `admin`, are authorized to issue invitations. However, you can extend this capability to other user roles by configuring [Tenant ACL permissions](/reference/engine/schema/acl.md#tenant-permissions).
### Existing vs new users
If the specified email address already corresponds to a user in the system, that user will simply be added to the designated project. If the user does not yet exist, a new account will be created, and login instructions will be sent to the provided email address.
### Password handling
By default, the invitation process auto-generates a password and sends it via email. However, it's recommended to set the invite method to `RESET_PASSWORD`. This way, a reset token is sent instead of a generated password. Ensure your [mail templates](./mail-templates.md) are appropriately configured to include the password setup link. Note that the default method will transition to `RESET_PASSWORD` in future updates.
### Customizing Email Templates
You can specify a preferred email template variant by setting the `mailVariant` option, as outlined in the [mail templates](./mail-templates.md) section.
Loading

0 comments on commit 880432c

Please sign in to comment.