.. _permissions: =========== 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 .. code-block:: python >>> 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 .. code-block:: python >>> 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. .. code-block:: python >>> 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 .. code-block:: python >>> 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. .. code-block:: python >>> 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. .. code-block:: python >>> 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. .. code-block:: python >>> 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. .. code-block:: python >>> 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. .. code-block:: python >>> 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"}}}]})