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
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}
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
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 }
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"], )
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
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")
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, )
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, )