Permissions

Entities that users create on qalx can only ever be accessed by other users in the same company. Further to this restriction you can also restrict access for users to create, update and delete entities by using projects, teams and tags. These are all administered via the qalx console.

Note

Currently only a company superuser has access to the qalx console. Please contact us if you require additional company superusers.

User Types

Currently there are two different user types on qalx. Each of these has access to a different set of data.

Superuser

A company superuser has access to all entities created for their company, regardless of what they were tagged with

Normal User

Normal users can access entities that have no tags as well as entities that are tagged with tags that they have access to via a project.

Example Setup

Once you have configured a project with some tags and assigned some teams to it via the qalx console we can begin creating data that only certain users can access.

All the examples on this page assume we have the following users, teams and projects configured:

Users

  • joe-superuser@mycompany.org - a superuser at mycompany

  • fred-user@mycompany.org - a normal user at mycompany

  • jane-user@mycompany.org - a normal user at mycompany

Teams

The teams with the users who are assigned to them.

  • Billing
    • fred-user@mycompany.org

  • Engineering
    • jane-user@mycompany.org

Projects

We have two projects configured, each with a few tags:

1st Project

Tag Name

Tag Value

project_code

ABC123

project_name

my-billing-project

department

billing

Assigned Teams

  • Billing

2nd Project

Tag Name

Tag Value

project_code

DEF456

project_name

my-engineering-project

department

engineering

Assigned Teams

  • Engineering

Tagging

Now that you’ve configured your teams, projects and users it’s time to start tagging data.

Adding Data

A session can be initialised with an optional project_name argument. Once that has been done, every entity created or updated with that session will be tagged with the project_name tag.

Note

All tags are lower cased and stripped of trailing whitespace when being saved by qalx. i.e. “Adding a tag of ‘My Engineering Project ‘ will be saved as ‘my engineering project’.

This won’t affect the adding or querying of entities.

Jane starts a new qalx session for her project

>>>  from pyqalx import QalxSession
>>>  qalx = QalxSession(project_name="my-engineering-project")
>>>  item = qalx.item.add(data={"width": 20, "length": 15})
>>>  print(item)
>>>  # The item was created with the project_name tag
>>>  {'guid': UUID('94652e3c-9249-49b9-a414-218626ee5522'),
      ...snip...
     'tags': [{'name': 'project_name', 'value': 'my-engineering-project'}],
>>>  }

But what if Fred tries to create an item on the same project? He will get an error as he doesn’t have permission to create entities with that tag

>>>  from pyqalx import QalxSession
>>>  qalx = QalxSession(project_name="my-engineering-project")
>>>  item = qalx.item.add(data={"width": 20, "length": 15})
>>>  '''
>>>  status_code: 400
>>>  reason: Bad Request
>>>  errors: {'tags': {'non_field_errors': ['You do not have permission to write the following 1 tags: `name:project_name, value:my-engineering-project`']}}
>>>  '''

Joe (the company superuser) can make entities with this tag though.

>>>  from pyqalx import QalxSession
>>>  qalx = QalxSession(project_name="my-engineering-project")
>>>  item = qalx.item.add(data={"width": 20, "length": 15})
>>>  print(item)
>>>  # The item was created with the project_name tag
>>>  {'guid': UUID('2acb5033-2fcb-4e81-84e7-b1addeb03839'),
     ...snip...
      'tags': [{'name': 'project_name', 'value': 'my-engineering-project'}],
>>>   }

Jane decides she wants to add extra tags to her session. She can only add tags that she has access to - otherwise she will receive an error. Every entity created/updated from this point will have these extra tags applied

>>>  from pyqalx import QalxSession
>>>  qalx = QalxSession(project_name="my-engineering-project")
>>>  qalx.tags.add(name="project_code", value="DEF456")

>>>  item = qalx.item.add(data={"width": 20, "length": 15})
>>>  print(item)
>>>  {'guid': UUID('2acb5033-2fcb-4e81-84e7-b1addeb03839'),
     ...snip...
      'tags': [{'name': 'project_name', 'value': 'my-engineering-project'},
               {'name': 'project_code', 'value': 'DEF456'}],
>>>   }

Retrieving Data

When retrieving data, qalx looks at the tags that the user has access to and only returns data that has tags that the user can access or is untagged

Warning

Remember, by default, qalx will not tag entities. Therefore, by default, all entities created will be accessible to every user on the company.

Joe, our superuser, creates a few items, some tagged, some not tagged.

>>>  from pyqalx import QalxSession
>>>  qalx = QalxSession()
>>>  # this is an untagged item
>>>  qalx.item.add(data={'weight': 50})
>>>
>>>  # Joe then adds a tag
>>>  qalx.tags.add(name="project_code", value="DEF456")
>>>  # This will be tagged
>>>  qalx.item.add(data={'height': 75})
>>>
>>>  # Clear all tags from the session
>>>  qalx.tags.clear()
>>>
>>>  # Add a new tag but for a different project
>>>  qalx.tags.add(name="project_code", value="ABC123")
>>>  # This will be tagged
>>>  qalx.item.add(data={'length': 100})

Jane will only be able to access the untagged item and the one created for her project_code.

>>> from pyqalx import QalxSession
>>> qalx = QalxSession()
>>> # Have added `fields` to keep the returned data smaller
>>> print(qalx.item.find(fields=['data', 'tags']))
>>> {'query': {'filter': {},
>>>            'sort': None,
>>>            'skip': 0,
>>>            'limit': 25,
>>>            'count': 3,
>>>            'next': 'item?fields=tags&limit=25&skip=25',
>>>             'previous': None},
>>>  'data': [{'guid': UUID('ceda759d-9e72-4a30-9d13-b5c990364b1d'),
               'data': {'weight': 50},
               'tags': []},
               {'guid': '12e4e564-d35f-413a-aa09-68fc91cc53c3',
               'data': {'height': 75},
               'tags': [{'name': 'project_code', 'value': 'DEF456']}]
>>> }

Fred will only be able to access the untagged item and the one created for his project code.

>>> from pyqalx import QalxSession
>>> qalx = QalxSession()
>>> # Have added `fields` to keep the returned data smaller
>>> print(qalx.item.find(fields=['data', 'tags']))
>>> {'query': {'filter': {},
>>>            'sort': None,
>>>            'skip': 0,
>>>            'limit': 25,
>>>            'count': 3,
>>>            'next': 'item?fields=tags&limit=25&skip=25',
>>>             'previous': None},
>>>  'data': [{'guid': UUID('ceda759d-9e72-4a30-9d13-b5c990364b1d'),
               'data': {'weight': 50},
               'tags': []},
               {'guid': '616c08f2-f421-4504-962d-8d6ee8d719f8',
               'data': {'length': 100},
               'tags': [{'name': 'project_code', 'value': 'ABC123']}]
>>> }

If you have tags specified on a Qalx session then any query to find or find_one will include those tags on the query.

>>> from pyqalx import QalxSession
>>> qalx = QalxSession(project_name="my-engineering-project")
>>> qalx.tags.add(name="project_code", value="DEF456")

# This will only return data which is tagged with a project_name of "my-engineering-project"
# and a project_code of "DEF456"
>>> qalx.item.find()

The above example is equivalent to the following.

>>> from pyqalx import QalxSession
>>> qalx = QalxSession()
>>> qalx.item.find({"$and": [
...         {"tags": {"$elemMatch": {"name": "project_code", "value": "DEF456"}}},
...         {"tags": {"$elemMatch": {"name": "project_name", "value": "my-engineering-project"}}}]})