async def _get_user_invitation(self, conn, organization_id: OrganizationID, user_id: UserID): if await self._user_exists(conn, organization_id, user_id): raise UserAlreadyExistsError(f"User `{user_id}` already exists") result = await conn.fetchrow( """ SELECT user_invitations.user_id, devices.device_id, user_invitations.created_on FROM user_invitations LEFT JOIN devices ON user_invitations.creator = devices._id WHERE user_invitations.organization = ( SELECT _id from organizations WHERE organization_id = $1 ) AND user_invitations.user_id = $2 """, organization_id, user_id, ) if not result: raise UserNotFoundError(user_id) return UserInvitation(user_id=UserID(result[0]), creator=DeviceID(result[1]), created_on=result[2])
async def _get_user_invitation(conn, organization_id: OrganizationID, user_id: UserID): if await _user_exists(conn, organization_id, user_id): raise UserAlreadyExistsError(f"User `{user_id}` already exists") result = await conn.fetchrow(_q_get_invitation, organization_id, user_id) if not result: raise UserNotFoundError(user_id) return UserInvitation(user_id=UserID(result[0]), creator=DeviceID(result[1]), created_on=result[2])
async def test_user_invite(monkeypatch, backend, apiv1_alice_backend_sock, alice, mallory): dummy_user_id = UserID("dummy") await backend.user.create_user_invitation( alice.organization_id, UserInvitation(dummy_user_id, alice.device_id)) user_invitation_created = trio.Event() vanilla_create_user_invitation = backend.user.create_user_invitation async def _mocked_create_user_invitation(*args, **kwargs): ret = await vanilla_create_user_invitation(*args, **kwargs) user_invitation_created.set() return ret monkeypatch.setattr(backend.user, "create_user_invitation", _mocked_create_user_invitation) with trio.fail_after(1): async with user_invite(apiv1_alice_backend_sock, user_id=mallory.user_id) as prep: # Wait for invitation to be created before fetching it ! await user_invitation_created.wait() # No the user we are waiting for await backend.user.claim_user_invitation( alice.organization_id, dummy_user_id, b"<dummy encrypted_claim>") await backend.user.claim_user_invitation( alice.organization_id, mallory.user_id, b"<mallory encrypted_claim>") assert prep[0] == { "status": "ok", "encrypted_claim": b"<mallory encrypted_claim>" }
async def test_user_get_invitation_creator_with_trustchain_ok( certificates_store, backend_data_binder_factory, local_device_factory, backend, alice, mallory, apiv1_anonymous_backend_sock, ): binder = backend_data_binder_factory(backend) roger1 = local_device_factory("roger@dev1") mike1 = local_device_factory("mike@dev1") await binder.bind_device(roger1, certifier=alice) await binder.bind_device(mike1, certifier=roger1) await binder.bind_revocation(roger1.user_id, certifier=mike1) invitation = UserInvitation(user_id=mallory.user_id, creator=mike1.device_id) await backend.user.create_user_invitation(alice.organization_id, invitation) rep = await user_get_invitation_creator(apiv1_anonymous_backend_sock, invited_user_id=invitation.user_id) cooked_rep = { **rep, "device_certificate": certificates_store.translate_certif(rep["device_certificate"]), "user_certificate": certificates_store.translate_certif(rep["user_certificate"]), "trustchain": { "devices": sorted( certificates_store.translate_certifs( rep["trustchain"]["devices"])), "users": sorted( certificates_store.translate_certifs( rep["trustchain"]["users"])), "revoked_users": sorted( certificates_store.translate_certifs( rep["trustchain"]["revoked_users"])), }, } assert cooked_rep == { "status": "ok", "device_certificate": "<mike@dev1 device certif>", "user_certificate": "<mike user certif>", "trustchain": { "devices": sorted([ "<alice@dev1 device certif>", "<roger@dev1 device certif>", "<mike@dev1 device certif>", ]), "users": sorted([ "<alice user certif>", "<roger user certif>", "<mike user certif>" ]), "revoked_users": ["<roger revoked user certif>"], }, }
async def mallory_invitation(backend, alice, mallory): invitation = UserInvitation(user_id=mallory.user_id, creator=alice.device_id) await backend.user.create_user_invitation(alice.organization_id, invitation) return invitation
async def mallory_invitation(backend, alice, mallory): invitation = UserInvitation(mallory.user_id, alice.device_id, Pendulum(2000, 1, 2)) await backend.user.create_user_invitation(alice.organization_id, invitation) return invitation