Пример #1
0
async def get_realm_status(conn, organization_id, realm_id):
    rep = await conn.fetchrow(
        *_q_get_realm_status(organization_id=organization_id, realm_id=realm_id)
    )
    if not rep:
        raise RealmNotFoundError(f"Realm `{realm_id}` doesn't exist")
    return rep
Пример #2
0
async def _get_realm_role_for_not_revoked(conn, organization_id, realm_id, users=None):
    now = pendulum.now()

    def _cook_role(row):
        if row["revoked_on"] and row["revoked_on"] <= now:
            return None
        if row["role"] is None:
            return None
        return STR_TO_REALM_ROLE[row["role"]]

    if users:
        rep = await conn.fetch(
            *_q_get_realm_role_for_not_revoked_with_users(
                organization_id=organization_id, realm_id=realm_id, users_ids=users
            )
        )
        roles = {row["user_id"]: _cook_role(row) for row in rep}
        for user in users or ():
            if user not in roles:
                raise RealmNotFoundError(f"User `{user}` doesn't exist")

        return roles

    else:
        rep = await conn.fetch(
            *_q_get_realm_role_for_not_revoked(organization_id=organization_id, realm_id=realm_id)
        )

        return {row["user_id"]: _cook_role(row) for row in rep if _cook_role(row) is not None}
Пример #3
0
async def query_get_role_certificates(
    conn,
    organization_id: OrganizationID,
    author: DeviceID,
    realm_id: UUID,
    since: pendulum.DateTime,
) -> List[bytes]:
    ret = await conn.fetch(*_q_get_role_certificates(
        organization_id=organization_id, realm_id=realm_id))

    if not ret:
        # Existing group must have at least one owner user
        raise RealmNotFoundError(f"Realm `{realm_id}` doesn't exist")

    out = []
    author_current_role = None
    for user_id, role, certif, certified_on in ret:
        if not since or certified_on > since:
            out.append(certif)
        if user_id == author.user_id:
            author_current_role = role

    if author_current_role is None:
        raise RealmAccessError()

    return out
Пример #4
0
async def query_get_current_roles(conn, organization_id: OrganizationID,
                                  realm_id: UUID) -> Dict[UserID, RealmRole]:
    ret = await conn.fetch(*_q_get_current_roles(
        organization_id=organization_id, realm_id=realm_id))

    if not ret:
        # Existing group must have at least one owner user
        raise RealmNotFoundError(f"Realm `{realm_id}` doesn't exist")

    return {
        UserID(user_id): STR_TO_REALM_ROLE[role]
        for user_id, role in ret if role is not None
    }
Пример #5
0
async def query_get_status(conn, organization_id: OrganizationID,
                           author: DeviceID, realm_id: UUID) -> RealmStatus:
    ret = await conn.fetchrow(
        *_q_get_realm_status(organization_id=organization_id,
                             realm_id=realm_id,
                             user_id=author.user_id))
    if not ret:
        raise RealmNotFoundError(f"Realm `{realm_id}` doesn't exist")

    if not ret["has_access"]:
        raise RealmAccessError()

    return RealmStatus(
        maintenance_type=STR_TO_REALM_MAINTENANCE_TYPE.get(
            ret["maintenance_type"]),
        maintenance_started_on=ret["maintenance_started_on"],
        maintenance_started_by=ret["maintenance_started_by"],
        encryption_revision=ret["encryption_revision"],
    )
Пример #6
0
async def query_get_stats(conn, organization_id: OrganizationID,
                          author: DeviceID, realm_id: UUID) -> RealmStats:
    ret = await conn.fetchrow(
        *_q_has_realm_access(organization_id=organization_id,
                             realm_id=realm_id,
                             user_id=author.user_id))
    if not ret:
        raise RealmNotFoundError(f"Realm `{realm_id}` doesn't exist")

    if not ret["has_access"]:
        raise RealmAccessError()
    blocks_size = await conn.fetch(*_q_get_blocks_size_from_realm(
        organization_id=organization_id, realm_id=realm_id))
    vlobs_size = await conn.fetch(*_q_get_vlob_size_from_realm(
        organization_id=organization_id, realm_id=realm_id))
    RealmStats.blocks_size = 0
    RealmStats.vlobs_size = 0
    if "sum" in blocks_size[0] and blocks_size[0]["sum"] is not None:
        RealmStats.blocks_size = blocks_size[0]["sum"]
    if "sum" in vlobs_size[0] and vlobs_size[0]["sum"] is not None:
        RealmStats.vlobs_size = vlobs_size[0]["sum"]

    return RealmStats
Пример #7
0
 def _get_realm(self, organization_id, realm_id):
     try:
         return self._realms[(organization_id, realm_id)]
     except KeyError:
         raise RealmNotFoundError(f"Realm `{realm_id}` doesn't exist")
Пример #8
0
    async def update_roles(
        self,
        organization_id: OrganizationID,
        new_role: RealmGrantedRole,
        recipient_message: Optional[bytes] = None,
    ) -> None:
        assert new_role.granted_by.user_id != new_role.user_id

        try:
            user = self._user_component._get_user(organization_id,
                                                  new_role.user_id)
        except UserNotFoundError:
            raise RealmNotFoundError(
                f"User `{new_role.user_id}` doesn't exist")

        if user.profile == UserProfile.OUTSIDER and new_role.role in (
                RealmRole.MANAGER,
                RealmRole.OWNER,
        ):
            raise RealmIncompatibleProfileError(
                "User with OUTSIDER profile cannot be MANAGER or OWNER")

        realm = self._get_realm(organization_id, new_role.realm_id)

        if realm.status.in_maintenance:
            raise RealmInMaintenanceError(
                "Data realm is currently under maintenance")

        owner_only = (RealmRole.OWNER, )
        owner_or_manager = (RealmRole.OWNER, RealmRole.MANAGER)
        existing_user_role = realm.roles.get(new_role.user_id)
        if existing_user_role in owner_or_manager or new_role.role in owner_or_manager:
            needed_roles = owner_only
        else:
            needed_roles = owner_or_manager

        author_role = realm.roles.get(new_role.granted_by.user_id)
        if author_role not in needed_roles:
            raise RealmAccessError()

        if existing_user_role == new_role.role:
            raise RealmRoleAlreadyGranted()

        realm.granted_roles.append(new_role)

        await self._send_event(
            BackendEvent.REALM_ROLES_UPDATED,
            organization_id=organization_id,
            author=new_role.granted_by,
            realm_id=new_role.realm_id,
            user=new_role.user_id,
            role=new_role.role,
        )

        if recipient_message is not None:
            await self._message_component.send(
                organization_id,
                new_role.granted_by,
                new_role.user_id,
                new_role.granted_on,
                recipient_message,
            )
Пример #9
0
async def query_update_roles(
    conn,
    organization_id: OrganizationID,
    new_role: RealmGrantedRole,
    recipient_message: Optional[bytes],
) -> None:
    if new_role.granted_by.user_id == new_role.user_id:
        raise RealmAccessError("Cannot modify our own role")

    # Make sure user profile is compatible
    rep = await conn.fetchrow(*_q_get_user_profile(
        organization_id=organization_id, user_id=new_role.user_id))
    if not rep:
        raise RealmNotFoundError(f"User `{new_role.user_id}` doesn't exist")
    if rep["profile"] == UserProfile.OUTSIDER.value and new_role.role in (
            RealmRole.MANAGER,
            RealmRole.OWNER,
    ):
        raise RealmIncompatibleProfileError(
            "User with OUTSIDER profile cannot be MANAGER or OWNER")

    # Retrieve realm and make sure it is not under maintenance
    rep = await conn.fetchrow(*_q_get_realm_status(
        organization_id=organization_id, realm_id=new_role.realm_id))
    if not rep:
        raise RealmNotFoundError(f"Realm `{new_role.realm_id}` doesn't exist")
    if rep["maintenance_type"]:
        raise RealmInMaintenanceError(
            "Data realm is currently under maintenance")

    # Check access rights and user existance
    ((author_id, author_role),
     (user_id, existing_user_role)) = await conn.fetch(*_q_get_roles(
         organization_id=organization_id,
         realm_id=new_role.realm_id,
         users_ids=(new_role.granted_by.user_id, new_role.user_id),
     ))
    assert author_id
    assert user_id

    author_role = STR_TO_REALM_ROLE.get(author_role)
    existing_user_role = STR_TO_REALM_ROLE.get(existing_user_role)
    owner_only = (RealmRole.OWNER, )
    owner_or_manager = (RealmRole.OWNER, RealmRole.MANAGER)
    if existing_user_role in owner_or_manager or new_role.role in owner_or_manager:
        needed_roles = owner_only
    else:
        needed_roles = owner_or_manager

    if author_role not in needed_roles:
        raise RealmAccessError()

    if existing_user_role == new_role.role:
        raise RealmRoleAlreadyGranted()

    await conn.execute(*_q_insert_realm_user_role(
        organization_id=organization_id,
        realm_id=new_role.realm_id,
        user_id=new_role.user_id,
        role=new_role.role.value if new_role.role else None,
        certificate=new_role.certificate,
        granted_by=new_role.granted_by,
        granted_on=new_role.granted_on,
    ))

    await send_signal(
        conn,
        BackendEvent.REALM_ROLES_UPDATED,
        organization_id=organization_id,
        author=new_role.granted_by,
        realm_id=new_role.realm_id,
        user=new_role.user_id,
        role_str=new_role.role.value if new_role.role else None,
    )

    if recipient_message:
        await send_message(
            conn,
            organization_id,
            new_role.granted_by,
            new_role.user_id,
            new_role.granted_on,
            recipient_message,
        )