Setup your configuration to gain access to collections rights

Prerequisites

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

Description

The goal of this example is to define and display how to interact with collections rights predefined collections. We will go through the creation of the different collections/schemas and create additional entities like scripts to demonstrate common usages linked to collections rights.

Note

The complete configuration for this example is available on the branch osp-collections-rights-configuration.

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

Steps

1. Setup module collections configuration

First, we need to inform the module collection we want to enable collections rights. For this example, we enable the three levels of rights,

modules/collections/collections-1/module.collections

{
  "messagingConfiguration": {
    "clientId": "osp-collections-1",
    "host": "rabbit"
  },
  "mongoDbConfigurationEntity": {
    "serverUrl": "mongodb://modules_mongodb_osp-mongo-1"
  },
  "historyIndexes": [ 
    {
      "name" : "collectionId",
      "index" : {"collectionId" : 1}
    }, 
    {
      "name" : "schemaId",
      "index" : {"schemaId" : 1}
    }, 
    {
      "name" : "modified_by",
      "index" : {"modified_by" : 1}
    }, 
    {
      "name" : "modified_at",
      "index" : {"modified_at" : 1}
    }, 
    {
      "name" : "operation",
      "index" : {"operation" : 1}
    }, 
    {
      "name" : "diffs",
      "index" : {"diffs" : 1}
    } 
  ],
  "counterIndexes": [
    {
      "name": "schemaId",
      "index": {
        "schemaId": 1
      },
      "sparse": false
    },
    {
      "name": "counter",
      "index": {
        "counter": 1
      },
      "sparse": false
    }
  ],
  "useUserPreferences": true,
  "useCollectionsRights": true,
  "useCollectionsProfilesRights": true,
  "useCollectionsServicesRights": true
}

2. Define user rights collection

To create a valid user rights collection, start by defining a valid schema. The schema validator can be found under the schemas section. As well as a valid schema, type USERS_RIGHTS must be specified.

root/collections/users-rights/schema.ospp

{
    "schema": {
        "type": "object",
        "properties": {
            "username": { "type": "string" },
            "profiles": { 
                "type": "array",
                "items": {"type": "string"}
            },
            "forms": { 
                "type": "array",
                "items": {"type": "string"}
            },
            "collections": { 
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "schemaId" : {"type": "string"},
                        "canCreate" : {"type": "boolean"},
                        "canRead" : {"type": "boolean"},
                        "canUpdate" : {"type": "boolean"},
                        "canDelete" : {"type": "boolean"},
                        "accessibleElements" : {
                            "type": "array",
                            "items": {"type": "string"}
                        },
                        "accessibleProperties" : {
                            "type": "array",
                            "items": {"type": "string"}
                        },
                        "filters" : {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "field": {"type": "string"},
                                    "operation": {"type": "string"},
                                    "content": {}
                                }
                            }
                        }
                    }
                }
            }
        },
        "required": ["username"]
    },
    "filters": [
        {
            "id": "all",
            "name": "Tous"
        }
    ],
    "type": "USERS_RIGHTS"
}

Then, create the schema.collections with the additional info required to fully define the collection.

root/collections/users-rights/schema.collections

{
    "moduleId": "modules.collections.collections-1",
    "collectionName": "users_rights",
    "indexes": [
        {
            "name": "username",
            "index": "{'username': 1}"
        }
    ],
    "filters": [
        {
            "id": "all",
            "query": "{}"
        }
    ]
}

With only this collection set up, we could already set the rights for a specific user. To do so, you can create a script (either Js or Lua script) and insert elements with root/collections/users-rights/schema.collections as the targeted schema ItemId. Otherwise, you can use the CollectionTable widget to display and edit the content of the collection.

Before setting up either of these options, we will define the profiles rights collection first, since we need this collection to set up each user profiles.

3. Define profiles rights collection

To create a valid profiles rights collection, start by defining a valid schema. The schema validator can be found under the schemas section. As well as a valid schema, type PROFILES_RIGHTS must be specified.

root/collections/profiles-rights/schema.ospp

{
    "schema": {
        "type": "object",
        "properties": {
            "profile": { "type": "string" },
            "forms": { 
                "type": "array",
                "items": {"type": "string"}
            },
            "collections": { 
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "schemaId" : {"type": "string"},
                        "canCreate" : {"type": "boolean"},
                        "canRead" : {"type": "boolean"},
                        "canUpdate" : {"type": "boolean"},
                        "canDelete" : {"type": "boolean"},
                        "accessibleElements" : {
                            "type": "array",
                            "items": {"type": "string"}
                        },
                        "accessibleProperties" : {
                            "type": "array",
                            "items": {"type": "string"}
                        },
                        "filters" : {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "field": {"type": "string"},
                                    "operation": {"type": "string"},
                                    "content": {}
                                }
                            }
                        }
                    }
                }
            }
        },
        "required": ["profile"]
    },
    "filters": [
        {
            "id": "all",
            "name": "Tous"
        }
    ],
    "type": "PROFILES_RIGHTS"
}

Then, create the schema.collections with the additional info required to fully define the collection.

root/collections/profiles-rights/schema.collections

{
    "moduleId": "modules.collections.collections-1",
    "collectionName": "profiles_rights",
    "indexes": [
        {
            "name": "profile",
            "index": "{'profile': 1}"
        }
    ],
    "filters": [
        {
            "id": "all",
            "query": "{}"
        }
    ]
}

We can now add entries to the profiles collections, creating rights to a given profile which can be linked to an user rights.

4. Create dashboards to interact with these collections

Now, we will define dashboards with CollectionTable widgets, one linked to the user rights and the other to the profile rights collection. For each of these table, we need a Form to allow us to create and edit entries of the collections and a schema.web to define the CollectionTable columns.

Profiles dashboard

First, we start with the profiles, since we need this collection to set users rights.

We start by defining the form with the necessary components. We need at least the profile name, the collections rights and the forms rights. Two specific components exists to set collections or forms rights. We use a component of type CollectionsRights to set collections rights and a component of type FormsRightsSelect for forms rights.

root/collections/profiles-rights/form/form.web

{
    "moduleId": [
      "modules.web.web-1"
    ],
    "name": "Formulaires - Droits profils",
    "description": "",
    "bindings": {},
    "rights": [],
    "schema": "root.collections.profiles-rights",
    "ui": {
      "type": "VerticalLayout",
      "elements": [
        {
          "type": "Control",
          "scope": "#/properties/profile",
          "label": "Nom du profil"
        },
        {
          "type": "Group",
          "label": "Droits collections",
          "elements": [
            {
              "type": "CollectionsRights",
              "scope": "#/properties/collections",
              "label": ""
            }
          ]
        },
        {
          "type": "Group",
          "label": "Droits formulaires",
          "elements": [
            {
              "type": "FormsRightsSelect",
              "scope": "#/properties/forms",
              "label": ""
            }
          ]
        }
      ]
    },
    "initialValue": {
    },
    "submit": {
      "destination": "Request",
      "type": "Deferred"
    }
  }

Then, we create a schema.web for this collection and define at least one view configuration.

root/collections/profiles-rights/schema.web

{
    "moduleId": "modules.web.web-1",
    "name": "Droits profils",
    "displayedProperty": "profile",
    "views": [
        {
            "id": "base",
            "name": "Basique",
            "reorderable": true,
            "isDefault": true,
            "sort": [
                {
                    "field": "profile",
                    "direction": "asc"
                }
            ],
            "columns": [
                {
                    "name": "Profil",
                    "field": "profile",
                    "position": 0
                }
            ]
        }
    ]
}

Finally, we can create a dashboard with a simple CollectionTable linked to this form and to profiles rights schema.

root/collections/profiles-rights/dashboard/dashboard.view

{
    "configuration": [
        {
            "type": "CollectionTable",
            "id": "D2H2STZ3",
            "title": "",
            "options": {
                "userPreference": "LOCAL_STORAGE"
            },
            "collectionTableWidgetSettings": {
                "defaultSchema": "root.collections.profiles-rights",
                "defaultView": "base",
                "defaultFilter": "all",
                "includeSchemas": [
                    "root.collections.profiles-rights"
                ],
                "disableDisplayTypes": [],
                "defaultDisplayType": "table",
                "disableFormPicker": false,
                "disableFormCreate": false,
                "disableFormEdit": false,
                "pageSize": 50,
                "pageSizes": [
                    50,
                    100,
                    200
                ],
                "resizeMode": "widget",
                "disableToolbarTableRefresh": false,
                "disableSchemaUpdate": false,
                "disableViewUpdate": false,
                "disableFilterUpdate": false,
                "disableToolbar": false,
                "disableToolbarMenu": false,
                "disableSidePanel": false,
                "disableToolbarExport": false,
                "disableToolbarColumnShowHide": false,
                "disableToolbarFilterShowHide": false,
                "disableToolbarSummaryShowHide": false,
                "disableToolbarSearch": false,
                "disableToolbarColumnChooser": false,
                "disableToolbarClearFilter": false,
                "submitSettings": {
                    "disableSubmit": false,
                    "disableApply": false,
                    "disableSaveFeedback": false,
                    "submitText": "Sauvegarder et quitter",
                    "applyText": "Sauvegarder"
                }
            }
        }
    ],
    "layout": {
        "lg": [
            {
                "w": 12,
                "h": 6,
                "x": 0,
                "y": 0,
                "i": "D2H2STZ3",
                "minH": 0
            }
        ]
    },
    "breakpoints": {
        "lg": 1200,
        "md": 996,
        "sm": 768,
        "xs": 480,
        "xxs": 0
    },
    "cols": {
        "lg": 12,
        "md": 10,
        "sm": 6,
        "xs": 4,
        "xxs": 2
    },
    "rowHeight": 150
}

You should now have a dashboard allowing you to create profiles rights. The form should look something like this:

../../_images/collections-rights-profiles-form.png

Users dashboard

Like for profiles, we start by defining a Form. Mandatory components are username, profiles, collections rights and forms rights. As for the profiles form, we use a component of type CollectionsRights to set collections rights and a component of type FormsRightsSelect for forms rights. For the profiles, the component Collection offers a selector with values from a specified collection.

root/collections/users-rights/form/form.web

{
    "moduleId": [
      "modules.web.web-1"
    ],
    "name": "Formulaires - Droits utilisateurs",
    "description": "",
    "bindings": {},
    "rights": [],
    "schema": "root.collections.users-rights",
    "ui": {
      "type": "VerticalLayout",
      "elements": [
        {
          "type": "Group",
          "label": "Utilisateur",
          "elements": [
            {
              "type": "HorizontalLayout",
              "elements": [
                {
                  "type": "Control",
                  "scope": "#/properties/username",
                  "label": "Nom d'utilisateur"
                },
                {
                  "type": "Collection",
                  "scope": "#/properties/profiles",
                  "label": "Profils",
                  "options": {
                    "multi": true,
                    "schema": "root.collections.profiles-rights",
                    "format": "${profile}",
                    "getId": true,
                    "dependsOn": [],
                    "sorts": [
                      {"field": "profile", "operation": "ASC"}
                    ]
                  }
                }
              ]
            }
          ]
        },
        {
          "type": "Group",
          "label": "Droits collections",
          "elements": [
            {
              "type": "CollectionsRights",
              "scope": "#/properties/collections",
              "label": ""
            }
          ]
        },
        {
          "type": "Group",
          "label": "Droits formulaires",
          "elements": [
            {
              "type": "FormsRightsSelect",
              "scope": "#/properties/forms",
              "label": ""
            }
          ]
        }
      ]
    },
    "initialValue": {
    },
    "submit": {
      "destination": "Request",
      "type": "Immediate"
    }
  }

Then, we create a schema.web for this collection and define at least one view configuration.

root/collections/users-rights/schema.web

{
    "moduleId": "modules.web.web-1",
    "name": "Droits utilisateurs",
    "displayedProperty": "username",
    "views": [
        {
            "id": "base",
            "name": "Basique",
            "reorderable": true,
            "isDefault": true,
            "sort": [
                {
                    "field": "username",
                    "direction": "asc"
                }
            ],
            "columns": [
                {
                    "name": "Utilisateur",
                    "field": "username",
                    "position": 0
                }
            ]
        }
    ]
}

Finally, we can create a dashboard with a simple CollectionTable linked to this form and to user rights schema.

root/collections/users-rights/dashboard/dashboard.view

{
    "configuration": [
        {
            "type": "CollectionTable",
            "id": "D2H2STZ3",
            "title": "",
            "options": {
                "userPreference": "LOCAL_STORAGE"
            },
            "collectionTableWidgetSettings": {
                "defaultSchema": "root.collections.users-rights",
                "defaultView": "base",
                "defaultFilter": "all",
                "includeSchemas": [
                    "root.collections.users-rights"
                ],
                "disableDisplayTypes": [],
                "defaultDisplayType": "table",
                "disableFormPicker": false,
                "disableFormCreate": false,
                "disableFormEdit": false,
                "pageSize": 50,
                "pageSizes": [
                    50,
                    100,
                    200
                ],
                "resizeMode": "widget",
                "disableToolbarTableRefresh": false,
                "disableSchemaUpdate": false,
                "disableViewUpdate": false,
                "disableFilterUpdate": false,
                "disableToolbar": false,
                "disableToolbarMenu": false,
                "disableSidePanel": false,
                "disableToolbarExport": false,
                "disableToolbarColumnShowHide": false,
                "disableToolbarFilterShowHide": false,
                "disableToolbarSummaryShowHide": false,
                "disableToolbarSearch": false,
                "disableToolbarColumnChooser": false,
                "disableToolbarClearFilter": false,
                "submitSettings": {
                    "disableSubmit": false,
                    "disableApply": false,
                    "disableSaveFeedback": false,
                    "submitText": "Sauvegarder et quitter",
                    "applyText": "Sauvegarder"
                }
            }
        }
    ],
    "layout": {
        "lg": [
            {
                "w": 12,
                "h": 6,
                "x": 0,
                "y": 0,
                "i": "D2H2STZ3",
                "minH": 0
            }
        ]
    },
    "breakpoints": {
        "lg": 1200,
        "md": 996,
        "sm": 768,
        "xs": 480,
        "xxs": 0
    },
    "cols": {
        "lg": 12,
        "md": 10,
        "sm": 6,
        "xs": 4,
        "xxs": 2
    },
    "rowHeight": 150
}

You should now have a dashboard allowing you to create users rights. The form should look something like this:

../../_images/collections-rights-users-form.png

We have now a way to define rights for specific users and for profiles. In the next step, we will continue by creating and configure the services collection.

5. Define services collection

To create a valid services collection, start by defining a valid schema. The schema validator can be found under the schemas section. As well as a valid schema, type SERVICES must be specified.

root/collections/services/schema.ospp

{
    "schema": {
        "type": "object",
        "properties": {
            "name": {
                "type": "string"
            },
            "ref": {
                "type": "string"
            },
            "serviceType": {
                "type": "string"
            },
            "collections": {
                 "type": "array",
                 "items": {
                     "type": "object",
                     "properties": {
                         "schemaId" : {"type": "string"},
                         "canCreate" : {"type": "boolean"},
                         "canRead" : {"type": "boolean"},
                         "canUpdate" : {"type": "boolean"},
                         "canDelete" : {"type": "boolean"},
                         "accessibleElements" : {
                             "type": "array",
                             "items": {"type": "string"}
                         },
                         "accessibleProperties" : {
                             "type": "array",
                             "items": {"type": "string"}
                         },
                         "filters" : {
                             "type": "array",
                             "items": {
                                "type": "object",
                                "properties": {
                                    "field": {"type": "string"},
                                    "operation": {"type": "string"},
                                    "content": {}
                                }
                             }
                         }
                     }
                 }
             },
            "schedules": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "openDay": {
                            "type": "number"
                        },
                        "closeDay": {
                            "type": "number"
                        },
                        "openTime": {
                            "type": "string"
                        },
                        "closeTime": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "openDay",
                        "closeDay",
                        "openTime",
                        "closeTime"
                    ]
                }
            },
            "mandatory": {
                "type": "boolean"
            },
            "activeUsers": {
                "type": "array",
                "items": {
                    "type": "string"
                }
            },
            "profiles": {
                "type": "array",
                "items": {
                    "type": "string"
                }
            },
            "tasks": {
                "type": "string"
            }
        },
        "required": [
            "name",
            "collections",
            "schedules",
            "activeUsers"
        ]
    },
    "filters": [
        {
            "id": "all",
            "name": "Tous"
        }
    ],
    "type": "SERVICES"
}

Then, create the schema.collections with the additional info required to fully define the collection.

root/collections/services/schema.collections

{
    "moduleId": "modules.collections.collections-1",
    "collectionName": "services_rights",
    "indexes": [
        {
            "name": "name",
            "index": "{'name': 1}"
        }
    ],
    "filters": [
        {
            "id": "all",
            "query": "{}"
        }
    ]
}

As for users and profiles collections, we must now set up a dashboard to interact with this collection.

6. Create dashboards to interact with services rights collections

We start by defining the Form we will use to create/edit this collection entries. Most important parts of a service are the list of active users, the profiles list and the rights this services give to the active users. Collections rights are handled by a CollectionsRights components and active users are not present in the form. We will set up a menu with actions allowing a user to enter and leave a service. For the profiles, we use the component Collection as like for the user rights form.

root/collections/services/form/form.web

{
    "moduleId": [
      "modules.web.web-1"
    ],
    "name": "Gestion des services",
    "description": "",
    "bindings": {},
    "rights": [],
    "schema": "root.collections.services",
    "ui": {
      "type": "VerticalLayout",
      "elements": [
        {
          "type": "Group",
          "label": "Information générales",
          "elements": [
            {
              "type": "HorizontalLayout",
              "elements": [
                {
                  "type": "Control",
                  "scope": "#/properties/name",
                  "label": "Nom du service"
                },
                {
                  "type": "Control",
                  "scope": "#/properties/ref",
                  "label": "Référence"
                }
              ]
            }
          ]
        },
        {
          "type": "Group",
          "label": "Droits affectés à ce service",
          "elements": [
            {
              "type": "CollectionsRights",
              "scope": "#/properties/collections",
              "label": ""
            }
          ]
        },
        {
          "type": "Group",
          "label": "Gestion des horaires",
          "elements": [
            {
              "type": "OpenCloseWeekScheduler",
              "scope": "#/properties/schedules",
              "label": "Horaires",
              "options": {
                "labelOpen": "Début",
                "labelClose": "Clôture"
              }
            }
          ]
        }  
      ]
    },
    "initialValue": {
      "collections": [],
      "schedules": [
        {
          "openDay": 0,
          "closeDay": 6,
          "openTime": "00:00",
          "closeTime": "23:59"
        }
      ],
      "activeUsers": []
    },
    "submit": {
      "destination": "Request",
      "type": "Deferred"
    }
  }

Then, we create a schema.web for this collection and define at least one view configuration. We need a view with a column for the field activeUsers in order to be able to access this value in the upcoming menu we will create.

root/collections/services/schema.web

{
    "moduleId": "modules.web.web-1",
    "name": "Gestion des services",
    "displayedProperty": "name",
    "views": [
        {
            "id": "base",
            "name": "Basique",
            "reorderable": true,
            "isDefault": true,
            "sort": [
                {
                    "field": "name",
                    "direction": "asc"
                }
            ],
            "columns": [
                {
                    "name": "Nom du service",
                    "field": "name",
                    "position": 0
                },
                {
                    "name": "Référence",
                    "field": "ref",
                    "position": 1
                },
                {
                    "name": "Utilisateurs actifs",
                    "field": "activeUsers",
                    "render": "TAGS",
                    "position": 2
                },
                {
                    "name": "Obligatoire",
                    "field": "mandatory",
                    "render": "BOOLEAN",
                    "position": 3
                }
            ]
        }
    ]
}

Before creating the dashboard, we will set up a menu that will allow the user to enter or leave a service. Each one of this action will trigger a script where we update the service by adding or removing the current authentified user into the list of active users.

root/collections/services/dashboard/menu/menu.web

{
    "moduleId": [
        "modules.web.web-1"
    ],
    "name": "Alarms menu",
    "description": "All standard alarm operations",
    "menus": [
        {
            "label": "Prendre le service",
            "icon": "meeting_room",
            "context": [
                {
                    "type": "CollectionTable",
                    "action": "root.collections.services.dashboard.menu.enter_service",
                    "condition": "${rows.selected}.length === 0 && !${rows.clicked.activeUsers}.includes(${user.username})",
                    "scopes": [
                        "Click"
                    ],
                    "input": {
                        "scriptId": {
                            "expression": "'root.collections.services.dashboard.menu.enter_service'"
                        },
                        "arguments": {
                            "expression": "[{'schema': ${schema}, 'documentId': ${rows.clicked._id}, 'user': ${user.username}}]"
                        }
                    },
                    "output": [
                        {
                            "operation": "snackbar",
                            "input": {
                                "message": {
                                    "expression": "'Service commencé'"
                                }
                            }
                        }
                    ]
                }
            ]
        },
        {
            "label": "Terminer le service",
            "icon": "no_meeting_room",
            "context": [
                {
                    "type": "CollectionTable",
                    "action": "root.collections.services.dashboard.menu.close_service",
                    "condition": "${rows.selected}.length === 0 && ${rows.clicked.activeUsers}.includes(${user.username})",
                    "scopes": [
                        "Click"
                    ],
                    "input": {
                        "scriptId": {
                            "expression": "'root.collections.services.dashboard.menu.close_service'"
                        },
                        "arguments": {
                            "expression": "[{'schema': ${schema}, 'documentId': ${rows.clicked._id}, 'user': ${user.username}}]"
                        }
                    },
                    "output": [
                        {
                            "operation": "snackbar",
                            "input": {
                                "message": {
                                    "expression": "'Service terminé'"
                                }
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

root/collections/services/dashboard/menu/enter_service/enter.js

main()

function main() {
    trigger.parameters.forEach(element => {
        collections.update(element.schema, element.documentId, [{field: "activeUsers", operation: "PUSH", content: collections.getUsername()}]); 
    });
}

root/collections/services/dashboard/menu/close_service/close.js

main()

function main() {
    trigger.parameters.forEach(element => {
        collections.update(element.schema, element.documentId, [{field: "activeUsers", operation: "PULL", content: collections.getUsername()}]); 
    });
}

Finally, we can create a dashboard with a simple CollectionTable linked to the form and menu we just created and to services rights schema.

root/collections/services/dashboard/dashboard.view

{
    "configuration": [
        {
            "type": "CollectionTable",
            "id": "D2H2STZ3",
            "title": "",
            "options": {
                "userPreference": "LOCAL_STORAGE"
            },
            "menuReferences": [
                "root.collections.services.dashboard.menu"
            ],
            "collectionTableWidgetSettings": {
                "defaultSchema": "root.collections.services",
                "defaultView": "base",
                "defaultFilter": "all",
                "includeSchemas": [
                    "root.collections.services"
                ],
                "disableDisplayTypes": [],
                "defaultDisplayType": "table",
                "disableFormPicker": false,
                "disableFormCreate": false,
                "disableFormEdit": false,
                "pageSize": 50,
                "pageSizes": [
                    50,
                    100,
                    200
                ],
                "resizeMode": "widget",
                "disableToolbarTableRefresh": false,
                "disableSchemaUpdate": false,
                "disableViewUpdate": false,
                "disableFilterUpdate": false,
                "disableToolbar": false,
                "disableToolbarMenu": false,
                "disableSidePanel": false,
                "disableToolbarExport": false,
                "disableToolbarColumnShowHide": false,
                "disableToolbarFilterShowHide": false,
                "disableToolbarSummaryShowHide": false,
                "disableToolbarSearch": false,
                "disableToolbarColumnChooser": false,
                "disableToolbarClearFilter": false,
                "submitSettings": {
                    "disableSubmit": false,
                    "disableApply": false,
                    "disableSaveFeedback": false,
                    "submitText": "Sauvegarder et quitter",
                    "applyText": "Sauvegarder"
                }
            }
        }
    ],
    "layout": {
        "lg": [
            {
                "w": 12,
                "h": 6,
                "x": 0,
                "y": 0,
                "i": "D2H2STZ3",
                "minH": 0
            }
        ]
    },
    "breakpoints": {
        "lg": 1200,
        "md": 996,
        "sm": 768,
        "xs": 480,
        "xxs": 0
    },
    "cols": {
        "lg": 12,
        "md": 10,
        "sm": 6,
        "xs": 4,
        "xxs": 2
    },
    "rowHeight": 150
}

You should now have a dashboard allowing you to create services. The form should look something like this:

../../_images/collections-rights-services-forms.png

What’s next ?

After following each one of these steps, you now have configure and gain access to collections rights. You can now create profiles and services as you wish and create entries in users rights collection for each one of the users you want to limit access. You can check out this example to create a script that will fetch all the users from osp-keycloak and insert them if needed in the users rights collection.