import base64 import json import pytest from fxa.errors import ClientError from api import * @pytest.fixture def push_server(): s = PushServer() yield s s.server.shutdown() s.server.server_close() @pytest.fixture(scope="class") def mail_server(): s = MailServer() yield s s.stop() @pytest.fixture def client(): return AuthClient() def _login(client, email, mail_server): # unverified accounts and unverified session behave the same, so we don't bother # with dedicated unverified-session tests and just always verify. c = client.login(email, "") (to, body) = mail_server.wait() assert to == [email] c.post_a('/session/verify_code', { 'code': body.strip() }) return c def _account(client, primary, email, mail_server): s = client.create_account(email, "") try: (to, body) = mail_server.wait() assert to == [email] data = json.loads(base64.urlsafe_b64decode(body.split("#/verify/", maxsplit=1)[1]).decode('utf8')) s.post_a('/recovery_email/verify_code', { 'uid': data['uid'], 'code': data['code'] }) if primary: yield s else: c = _login(client, email, mail_server) yield c s.password = c.password finally: try: s.destroy_account(email, s.password) except ClientError as e: # don't fail if the account was already deleted if e.details['errno'] != 102: raise email1 = f"test.account-{os.urandom(8).hex()}@test-auth" email2 = f"test.account2-{os.urandom(8).hex()}@test-auth" @pytest.fixture(scope="class") def account_plain(request, mail_server): for a in _account(AuthClient(), True, email1, mail_server): yield a break @pytest.fixture(scope="class") def account2_plain(request, mail_server): for a in _account(AuthClient(), True, email2, mail_server): yield a break @pytest.fixture(params=[True, False], ids=["primary", "secondary"], scope="class") def account(request, mail_server): for a in _account(AuthClient(), request.param, email1, mail_server): yield a @pytest.fixture(params=[True, False], ids=["primary", "secondary"], scope="class") def account2(request, mail_server): for a in _account(AuthClient(), request.param, email2, mail_server): yield a @pytest.fixture(scope="class") def unverified_account(mail_server): client = AuthClient() s = client.create_account(email1, "") yield s s.destroy_account(s.email, "") @pytest.fixture def login(client, mail_server): return _login(client, email1, mail_server) @pytest.fixture def login2(client, mail_server): return _login(client, email2, mail_server) def _refresh_token(account, scope): body = { "client_id": "5882386c6d801776", "ttl": 60, "grant_type": "fxa-credentials", "access_type": "offline", "scope": scope, } yield account.post_a("/oauth/token", body) @pytest.fixture def refresh_token(account): for r in _refresh_token(account, "profile https://identity.mozilla.com/apps/oldsync https://identity.mozilla.com/tokens/session"): yield AuthClient(email=account.email, bearer=r['refresh_token'], props=r) @pytest.fixture def narrow_refresh_token(account): for r in _refresh_token(account, "profile https://identity.mozilla.com/tokens/session"): yield AuthClient(email=account.email, bearer=r['refresh_token'], props=r) def _account_or_rt(account, request, scope): if request.param: yield account else: for r in _refresh_token(account, scope): yield AuthClient(email=account.email, bearer=r['refresh_token'], props=r) @pytest.fixture(params=[True, False], ids=["session", "refresh_token"]) def account_or_rt(account, request): for r in _account_or_rt(account, request, "profile https://identity.mozilla.com/apps/oldsync https://identity.mozilla.com/tokens/session"): yield r @pytest.fixture def forgot_token(account, mail_server): resp = account.post_a("/password/forgot/send_code", { 'email': account.email }) assert 'passwordForgotToken' in resp assert resp['ttl'] == 300 assert resp['codeLength'] == 16 assert resp['tries'] == 1 (to, body) = mail_server.wait() assert account.email in to pc = PasswordChange(account.client, resp['passwordForgotToken'], 'passwordForgotToken') pc.code = body.strip() return pc