From c201ac261de8049e8f1e1756973601f8d712ed45 Mon Sep 17 00:00:00 2001 From: Matthew Evans <7916000+ml-evs@users.noreply.github.com> Date: Fri, 28 Jul 2023 01:01:54 +0100 Subject: [PATCH] Add concept of user manager permissions (#417) * Add concept of user manager permissions * Add managers to people model --- pydatalab/pydatalab/models/people.py | 4 ++++ pydatalab/pydatalab/routes/utils.py | 14 +++++++++++++- pydatalab/schemas/cell.json | 7 +++++++ pydatalab/schemas/sample.json | 7 +++++++ pydatalab/schemas/startingmaterial.json | 7 +++++++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/pydatalab/pydatalab/models/people.py b/pydatalab/pydatalab/models/people.py index 38b97ac56..75a018889 100644 --- a/pydatalab/pydatalab/models/people.py +++ b/pydatalab/pydatalab/models/people.py @@ -6,6 +6,7 @@ from pydantic import BaseModel, EmailStr, Field, validator from pydatalab.models.entries import Entry +from pydatalab.models.utils import PyObjectId class IdentityType(str, Enum): @@ -76,6 +77,9 @@ class Person(Entry): contact_email: Optional[EmailStr] """In the case of multiple *verified* email identities, this email will be used as the primary contact.""" + managers: Optional[List[PyObjectId]] + """A list of user IDs that can manage this person's items.""" + @validator("type", pre=True, always=True) def add_missing_type(cls, v): """Fill in missing `type` field if not provided.""" diff --git a/pydatalab/pydatalab/routes/utils.py b/pydatalab/pydatalab/routes/utils.py index 0880a1822..ec56b98b4 100644 --- a/pydatalab/pydatalab/routes/utils.py +++ b/pydatalab/pydatalab/routes/utils.py @@ -3,7 +3,9 @@ from flask_login import current_user from pydatalab.config import CONFIG +from pydatalab.logger import LOGGER from pydatalab.login import UserRole +from pydatalab.mongo import get_database def get_default_permissions(user_only: bool = True) -> Dict[str, Any]: @@ -31,7 +33,17 @@ def get_default_permissions(user_only: bool = True) -> Dict[str, Any]: null_perm = {"creator_ids": {"$size": 0}} if current_user.is_authenticated and current_user.person is not None: - user_perm = {"creator_ids": {"$in": [current_user.person.immutable_id]}} + # find managed users under the given user (can later be expanded to groups) + managed_users = list( + get_database().users.find( + {"managers": {"$in": [current_user.person.immutable_id]}}, projection={"_id": 1} + ) + ) + if managed_users: + managed_users = [u["_id"] for u in managed_users] + LOGGER.info("Found users %s for user %s", managed_users, current_user.person) + + user_perm = {"creator_ids": {"$in": [current_user.person.immutable_id] + managed_users}} if user_only: return user_perm return {"$or": [user_perm, null_perm]} diff --git a/pydatalab/schemas/cell.json b/pydatalab/schemas/cell.json index cda818bbb..ec5223132 100644 --- a/pydatalab/schemas/cell.json +++ b/pydatalab/schemas/cell.json @@ -339,6 +339,13 @@ "title": "Contact Email", "type": "string", "format": "email" + }, + "managers": { + "title": "Managers", + "type": "array", + "items": { + "type": "string" + } } } }, diff --git a/pydatalab/schemas/sample.json b/pydatalab/schemas/sample.json index c58827e5f..ba29b0ff3 100644 --- a/pydatalab/schemas/sample.json +++ b/pydatalab/schemas/sample.json @@ -298,6 +298,13 @@ "title": "Contact Email", "type": "string", "format": "email" + }, + "managers": { + "title": "Managers", + "type": "array", + "items": { + "type": "string" + } } } }, diff --git a/pydatalab/schemas/startingmaterial.json b/pydatalab/schemas/startingmaterial.json index c72cfa0be..0d10ac0bf 100644 --- a/pydatalab/schemas/startingmaterial.json +++ b/pydatalab/schemas/startingmaterial.json @@ -349,6 +349,13 @@ "title": "Contact Email", "type": "string", "format": "email" + }, + "managers": { + "title": "Managers", + "type": "array", + "items": { + "type": "string" + } } } },