q_user_internal_id, q_device_internal_id, ) _q_get_user_devices = (Query.from_(t_device).select( t_device.device_id).where(t_device.user_ == q_user_internal_id( organization_id=Parameter("$1"), user_id=Parameter("$2"))).get_sql()) _q_insert_user = (Query.into(t_user).columns( "organization", "user_id", "is_admin", "user_certificate", "user_certifier", "created_on").insert( q_organization_internal_id(Parameter("$1")), Parameter("$2"), Parameter("$3"), Parameter("$4"), q_device_internal_id(organization_id=Parameter("$1"), device_id=Parameter("$5")), Parameter("$6"), ).get_sql()) _q_insert_device = (Query.into(t_device).columns( "organization", "user_", "device_id", "device_certificate", "device_certifier", "created_on").insert( q_organization_internal_id(Parameter("$1")), q_user_internal_id(organization_id=Parameter("$1"), user_id=Parameter("$2")), Parameter("$3"), Parameter("$4"), q_device_internal_id(organization_id=Parameter("$1"), device_id=Parameter("$5")), Parameter("$6"), ).get_sql())
async def update( self, organization_id: OrganizationID, author: DeviceID, encryption_revision: int, vlob_id: UUID, version: int, timestamp: pendulum.Pendulum, blob: bytes, ) -> None: async with self.dbh.pool.acquire() as conn, conn.transaction(): realm_id = await _get_realm_id_from_vlob_id(conn, organization_id, vlob_id) await _check_realm_and_write_access( conn, organization_id, author, realm_id, encryption_revision ) query = """ SELECT version, created_on FROM vlob_atom WHERE organization = ({}) AND vlob_id = $2 ORDER BY version DESC LIMIT 1 """.format( q_organization_internal_id(Parameter("$1")) ) previous = await conn.fetchrow(query, organization_id, vlob_id) if not previous: raise VlobNotFoundError(f"Vlob `{vlob_id}` doesn't exist") elif previous["version"] != version - 1: raise VlobVersionError() elif previous["created_on"] > timestamp: raise VlobTimestampError() query = """ INSERT INTO vlob_atom ( organization, vlob_encryption_revision, vlob_id, version, blob, size, author, created_on ) SELECT ({}), ({}), $5, $9, $6, $7, ({}), $8 RETURNING _id """.format( q_organization_internal_id(Parameter("$1")), q_vlob_encryption_revision_internal_id( organization_id=Parameter("$1"), realm_id=Parameter("$3"), encryption_revision=Parameter("$4"), ), q_device_internal_id(organization_id=Parameter("$1"), device_id=Parameter("$2")), ) try: vlob_atom_internal_id = await conn.fetchval( query, organization_id, author, realm_id, encryption_revision, vlob_id, blob, len(blob), timestamp, version, ) except UniqueViolationError: # Should not occurs in theory given we are in a transaction raise VlobVersionError() await _vlob_updated( conn, vlob_atom_internal_id, organization_id, author, realm_id, vlob_id, version )
async def query_start_reencryption_maintenance( conn, organization_id: OrganizationID, author: DeviceID, realm_id: UUID, encryption_revision: int, per_participant_message: Dict[UserID, bytes], timestamp: pendulum.Pendulum, ) -> None: # Retrieve realm and make sure it is not under maintenance rep = await get_realm_status(conn, organization_id, realm_id) if rep["maintenance_type"]: raise RealmInMaintenanceError( f"Realm `{realm_id}` alrealy in maintenance") if encryption_revision != rep["encryption_revision"] + 1: raise RealmEncryptionRevisionError("Invalid encryption revision") roles = await get_realm_role_for_not_revoked(conn, organization_id, realm_id) if per_participant_message.keys() ^ roles.keys(): raise RealmParticipantsMismatchError( "Realm participants and message recipients mismatch") if roles.get(author.user_id) != RealmRole.OWNER: raise RealmAccessError() query = """ UPDATE realm SET encryption_revision=$6, maintenance_started_by=({}), maintenance_started_on=$4, maintenance_type=$5 WHERE _id = ({}) """.format( q_device_internal_id(organization_id=Parameter("$1"), device_id=Parameter("$3")), q_realm_internal_id(organization_id=Parameter("$1"), realm_id=Parameter("$2")), ) await conn.execute(query, organization_id, realm_id, author, timestamp, "REENCRYPTION", encryption_revision) query = """ INSERT INTO vlob_encryption_revision( realm, encryption_revision ) SELECT ({}), $3 """.format( q_realm_internal_id(organization_id=Parameter("$1"), realm_id=Parameter("$2"))) await conn.execute(query, organization_id, realm_id, encryption_revision) await send_signal( conn, "realm.maintenance_started", organization_id=organization_id, author=author, realm_id=realm_id, encryption_revision=encryption_revision, ) for recipient, body in per_participant_message.items(): await send_message(conn, organization_id, author, recipient, timestamp, body)
async def create( self, organization_id: OrganizationID, author: DeviceID, realm_id: UUID, encryption_revision: int, vlob_id: UUID, timestamp: pendulum.Pendulum, blob: bytes, ) -> None: async with self.dbh.pool.acquire() as conn, conn.transaction(): await _check_realm_and_write_access( conn, organization_id, author, realm_id, encryption_revision ) # Actually create the vlob try: query = """ INSERT INTO vlob_atom ( organization, vlob_encryption_revision, vlob_id, version, blob, size, author, created_on ) SELECT ({}), ({}), $5, 1, $6, $7, ({}), $8 RETURNING _id """.format( q_organization_internal_id(organization_id=Parameter("$1")), Query.from_(t_vlob_encryption_revision) .where( ( t_vlob_encryption_revision.realm == q_realm_internal_id( organization_id=Parameter("$1"), realm_id=Parameter("$3") ) ) & (t_vlob_encryption_revision.encryption_revision == Parameter("$4")) ) .select("_id"), q_device_internal_id( organization_id=Parameter("$1"), device_id=Parameter("$2") ), ) vlob_atom_internal_id = await conn.fetchval( query, organization_id, author, realm_id, encryption_revision, vlob_id, blob, len(blob), timestamp, ) except UniqueViolationError: raise VlobAlreadyExistsError() await _vlob_updated( conn, vlob_atom_internal_id, organization_id, author, realm_id, vlob_id )