Managing rights from collections

Prerequisites

Modules

Checkout branches

git checkout origin/osp-collections-configuration .
git checkout origin/osp-web-configuration .

Note

The complete example can be checkout from any onsphere stack

git checkout origin/example-insert-rights-from-collections .

Description

This example illustrates how to implement rights management on the frontend, enabling direct user rights management. This can be easily achieved by using a Collections along with the Enrich keycloak token.

We will create the following element to define and demonstrate the right application.

  • New rights and users.

  • A collection and dashboard to manage the rights.

  • A dashboard accessible by everyone.

  • A dashboard only accessible by the integrator.

Note

The example is only using the dashboard access to demonstrate the access management but this also apply the other element as well because we use the standard Authorization.

Warning

The configuration provided with this example might override existing configuration on the module rights and keycloak.

Steps

1. Define the rights and user

We will create the new following rights inside module.rights.

  • rights-management: Limit the access to the right management dashboard. The name is not fixed and can be chosen freely or merge with another exist rights.

  • dynamic-access: Right given dynamically. This is only an example and you can create as many as need to handle you use-case.

modules/rights/rights/module.rights

{
  "messagingConfiguration": {
    "clientId": "osp-rights",
    "host": "rabbit"
  },
  "groups": [
    {
      "name": "all",
      "description": "Access all value",
      "externalLink": [
        "data-access",
        "configuration-management"
      ]
    },
    {
      "name": "rights-management",
      "description": "Access the right management dashboard",
      "externalLink": [
        "rights-management"
      ]
    },
    {
      "name": "dynamic-access",
      "description": "Access define dynamicaly from a collection",
      "externalLink": []
    }
  ]
}

This is form the base to manage the rights from a collection.

1. Define the user and group

The group rights-management will be added to groups.keycloak and to the user supervisor to manage the dynamic rights. The user user1 and user2 will be also created and used to demonstrate the application of the rights.

modules/keycloak/keycloak-1/groups.keycloak

62        {
63          "attributes": {},
64          "clientRoles": {},
65          "name": "rights-management",
66          "path": "/internal/rights-management",
67          "realmRoles": [],
68          "subGroups": []
69        }

modules/keycloak/keycloak-1/users.keycloak

58    {
59      "enabled": true,
60      "groups": [
61        "/internal/data-access",
62        "/internal/user"
63      ],
64      "username": "user1",
65      "email": "user1@localhost",
66      "firstName": "user1",
67      "lastName": "user1",
68      "credentials": [
69        {
70          "type": "password",
71          "value": "onsphere",
72          "initial": true
73        }
74      ]
75    },
76    {
77      "enabled": true,
78      "groups": [
79        "/internal/data-access",
80        "/internal/user"
81      ],
82      "username": "user2",
83      "email": "user2@localhost",
84      "firstName": "user2",
85      "lastName": "user2",
86      "credentials": [
87        {
88          "type": "password",
89          "value": "onsphere",
90          "initial": true
91        }
92      ]
93    }

3. Create the collection to handle the rights

The rights will be store inside a collection named rights-management. This part will only be visible by the supervisor.

The rights are managed as a list.

root/rights/access.rights

{
    "moduleId": "modules.rights.rights",
    "write": {
        "override": [
            "rights-management"
        ]
    },
    "read": {
        "override": [
            "rights-management"
        ]
    }
}

root/rights/schema/schema.ospp

{
    "schema": {
        "type": "object",
        "properties": {
            "email": {
                "type": "string",
                "title": "User email"
            },
            "rights": {
                "type": "array",
                "uniqueItems": true,
                "items": {
                    "type": "string"
                },
                "title": "Rights list"
            }
        }
    },
    "filters": [
        {
            "id": "all",
            "name": "All"
        }
    ],
    "uniqueFields": ["email"]
}

root/rights/schema/schema.collections

{
    "moduleId": "modules.collections.collections-1",
    "collectionName": "management",
    "indexes": [
        {
            "name": "email",
            "index": {
                "email": 1
            },
            "unique": true
        },
        {
            "name": "rights",
            "index": {
                "rights": 1
            }
        }
    ],
    "filters": [
        {
            "id": "all",
            "query": {}
        }
    ],
    "noDuplicatesFields": [
        "rights"
    ]
}

root/rights/schema/schema.web

{
    "moduleId": "modules.web.web-1",
    "name": "Rights management",
    "views": [
        {
            "id": "1",
            "name": "Default",
            "reorderable": true,
            "isDefault": true,
            "sort": [
                {
                    "field": "email",
                    "direction": "desc"
                }
            ],
            "columns": [
                {
                    "name": "Email",
                    "field": "email",
                    "position": 0,
                    "render": "STRING"
                },
                {
                    "name": "Rights",
                    "field": "rights",
                    "position": 1,
                    "render": "TAGS"
                }
            ]
        }
    ]
}

root/rights/form/form.web

{
    "moduleId": [
        "modules.web.web-1"
    ],
    "name": "Gestion des droits",
    "description": "",
    "bindings": {},
    "rights": [],
    "schema": "root.rights.schema",
    "ui": {
        "type": "VerticalLayout",
        "elements": [
            {
                "type": "Control",
                "scope": "#/properties/email",
                "label": "Email"
            },
            {
                "type": "Control",
                "scope": "#/properties/rights",
                "label": "Rights"
            }
        ]
    },
    "submit": {
        "destination": "Request",
        "type": "Deferred"
    }
}

root/rights/editor/dashboard.web

{
    "moduleId": "modules.web.web-1",
    "title": "Rights editor",
    "description": "Edit the rights for the user",
    "tags": []
}

root/rights/editor/dashboard.view

 3    {
 4      "collectionTableWidgetSettings": {
 5        "defaultSchemas": [
 6          "root.rights.schema"
 7        ],
 8        "defaultView": "1",
 9        "defaultFilter": "all",
10        "includeSchemas": [
11          "root.rights.schema"
12        ],
13        "includeForms": [
14          "root.rights.form"
15        ],

4. Create a dashboard only accessible by dynamic-access

The following dashboard show the text Victory to the user able to access it.

root/limited/access.rights

{
    "moduleId": "modules.rights.rights",
    "write": {
        "override": [
            "dynamic-access"
        ]
    },
    "read": {
        "override": [
            "dynamic-access"
        ]
    }
}

root/limited/dashboard.web

{
    "moduleId": "modules.web.web-1",
    "title": "Limited dashboard",
    "description": "Accessible only by member of dynamic-access",
    "tags": []
}

root/limited/dashboard.view

 3    {
 4      "textWidgetSettings": {
 5        "text": "Victory"
 6      },
 7      "id": "vNFhL7oI",
 8      "type": "Text",
 9      "title": ""
10    }

5. Create the script to handle the rights from collection

We will create the authorization script that will be called when a user log in. It will search the collection for the user with it’s email and apply the rights found on top to the one define by the group membership.

modules/keycloak/keycloak-1/authorization.keycloak

{
  "sourceFile": "modules/keycloak/keycloak-1/authorization.js"
}

Note

The script is not required to be inside the same folder as the authorization.keycloak file.

modules/keycloak/keycloak-1/authorization.js

main();

function main() {
  if (!tokenRequest.email) {
    log.warn(
      "No email available for token [{}] and user [{}]",
      tokenRequest.tokenId,
      tokenRequest.userId
    );
    return false;
  }

  const filter = buildFilter(tokenRequest.email);
  const result = collections.getWithCustomFilter(
    "root.rights.schema",
    filter
  );

  if (!result.success) {
    log.warn(
      "Fail to get rights for user [{}] with error [{}]",
      tokenRequest.email,
      result.message
    );
    return false;
  }

  const rights = result.content?.rights;
  if (rights) {
    for (right of rights) {
      authorization.add(right);
    }
  }

  return true;
}

function buildFilter(email) {
  const filter = {
    email: email,
  };

  return JSON.stringify(filter);
}

5. Log in and explore the dashboard

When log in as user1 or user2, you will only be able to see the home dashboard.

../../_images/user-no-rights1.png

The user supervisor will only see the rights editor.

../../_images/supervisor-editor.png

6. Add rights to a user

As supervisor, we will add the rights dynamic-access to user1.

../../_images/add-user1-right.png

When log in with the user1 the available dashboard will change and it can access the limited one.

../../_images/user1-dynamic-access1.png