async def _process_message_sharing_revoked( self, msg: SharingRevokedMessageContent) -> None: """ Raises: FSError FSBackendOfflineError """ # Unlike when somebody grant us workspace access, here we should no # longer be able to access the workspace. # This also include workspace participants, hence we have no way # verifying the sender is manager/owner... But this is not really a trouble: # if we cannot access the workspace info, we have been revoked anyway ! try: await self.remote_loader.load_realm_current_roles(msg.id) except FSWorkspaceNoAccess: # Exactly what we expected ! pass else: # We still have access over the workspace, nothing to do then return async with self._update_user_manifest_lock: user_manifest = self.get_user_manifest() # Save the revocation information in the user manifest existing_workspace_entry = user_manifest.get_workspace_entry( msg.id) if not existing_workspace_entry: # No workspace entry, nothing to update then return timestamp = self.device.timestamp() workspace_entry = merge_workspace_entry( None, existing_workspace_entry, existing_workspace_entry.evolve(role=None, role_cached_on=timestamp), ) if existing_workspace_entry == workspace_entry: # Cheap idempotent check return timestamp = self.device.timestamp() user_manifest = user_manifest.evolve_workspaces_and_mark_updated( timestamp, workspace_entry) await self.set_user_manifest(user_manifest) self.event_bus.send(CoreEvent.USERFS_UPDATED) self.event_bus.send( CoreEvent.SHARING_UPDATED, new_entry=workspace_entry, previous_entry=existing_workspace_entry, )
async def _process_message_sharing_granted( self, msg: Union[SharingRevokedMessageContent, SharingReencryptedMessageContent] ): """ Raises: FSError FSBackendOfflineError FSSharingNotAllowedError """ # We cannot blindly trust the message sender ! Hence we first # interrogate the backend to make sure he is a workspace manager/owner. # Note this means we refuse to process messages from a former-manager, # even if the message was sent at a time the user was manager (in such # case the user can still ask for another manager to re-do the sharing # so it's no big deal). try: roles = await self.remote_loader.load_realm_current_roles(msg.id) except FSWorkspaceNoAccess: # Seems we lost the access roles anyway, nothing to do then return if roles.get(msg.author.user_id, None) not in (WorkspaceRole.OWNER, WorkspaceRole.MANAGER): raise FSSharingNotAllowedError( f"User {msg.author.user_id} cannot share workspace `{msg.id}`" " with us (requires owner or manager right)" ) # Determine the access roles we have been given to self_role = roles.get(self.device.user_id) # Finally insert the new workspace entry into our user manifest workspace_entry = WorkspaceEntry( # Name are not required to be unique across workspaces, so no check to do here name=f"{msg.name} (shared by {msg.author.user_id})", id=msg.id, key=msg.key, encryption_revision=msg.encryption_revision, encrypted_on=msg.encrypted_on, role=self_role, role_cached_on=pendulum_now(), ) async with self._update_user_manifest_lock: user_manifest = self.get_user_manifest() # Check if we already know this workspace already_existing_entry = user_manifest.get_workspace_entry(msg.id) if already_existing_entry: # Merge with existing as target to keep possible workpace rename workspace_entry = merge_workspace_entry( None, workspace_entry, already_existing_entry ) user_manifest = user_manifest.evolve_workspaces_and_mark_updated(workspace_entry) await self.set_user_manifest(user_manifest) self.event_bus.send("userfs.updated") if not already_existing_entry: # TODO: remove this event ? self.event_bus.send("fs.entry.synced", id=workspace_entry.id) self.event_bus.send( "sharing.updated", new_entry=workspace_entry, previous_entry=already_existing_entry )