def test_authorize_page_login_user_non_supported_flow(flask_client): """return 400 if the flow is not supported""" user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() # Not provide any flow r = flask_client.get( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", # not provide response_type param here )) # Provide a not supported flow html = r.get_data(as_text=True) assert r.status_code == 400 assert "SimpleLogin only support the following OIDC flows" in html r = flask_client.get( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", # SL does not support this flow combination response_type="code token id_token", )) html = r.get_data(as_text=True) assert r.status_code == 400 assert "SimpleLogin only support the following OIDC flows" in html
def test_authorize_page_invalid_client_id(flask_client): """make sure to redirect user to redirect_url?error=invalid_client_id""" user = login(flask_client) Client.create_new("test client", user.id) db.session.commit() r = flask_client.get( url_for( "oauth.authorize", client_id="invalid_client_id", state="teststate", redirect_uri="http://localhost", response_type="code", )) assert r.status_code == 302 assert ( r.location == "http://localhost?error=invalid_client_id&client_id=invalid_client_id")
def new_client(): form = NewClientForm() if form.validate_on_submit(): client = Client.create_new(form.name.data, current_user.id) db.session.commit() flash("Your app has been created", "success") return redirect( url_for("developer.client_detail", client_id=client.id, is_new=1)) return render_template("developer/new_client.html", form=form)
def test_authorize_id_token_flow(flask_client): """make sure the authorize redirects user to correct page for the *ID-Token Flow* , ie when response_type=id_token The /authorize endpoint should return an id_token """ user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() # user allows client on the authorization page r = flask_client.post( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", response_type="id_token", # id_token flow ), data={ "button": "allow", "suggested-email": "[email protected]", "suggested-name": "AB CD" }, # user will be redirected to client page, do not allow redirection here # to assert the redirect url # follow_redirects=True, ) assert r.status_code == 302 # user gets redirected back to client page # r.location will have this form http://localhost?state=teststate&code=knuyjepwvg o = urlparse(r.location) assert o.netloc == "localhost" assert not o.fragment assert o.query # parse the fragment, should return something like # {'state': ['teststate'], 'id_token': ['knuyjepwvg']} queries = parse_qs(o.query) assert len(queries) == 2 assert queries["state"] == ["teststate"] # access_token must be returned assert len(queries["id_token"]) == 1 # id_token must be a valid, correctly signed JWT assert verify_id_token(queries["id_token"][0])
def test_authorize_page_unknown_redirect_uri(flask_client): """make sure to redirect user to redirect_url?error=unknown_redirect_uri""" user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() r = flask_client.get( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="https://unknown.com", response_type="code", )) assert r.status_code == 302 assert r.location == "https://unknown.com?error=unknown_redirect_uri"
def test_authorize_page_http_not_allowed(flask_client): """make sure to redirect user to redirect_url?error=http_not_allowed""" user = login(flask_client) client = Client.create_new("test client", user.id) client.approved = True db.session.commit() r = flask_client.get( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://mywebsite.com", response_type="code", )) assert r.status_code == 302 assert r.location == "http://mywebsite.com?error=http_not_allowed"
def test_encode_decode(flask_client): user = User.create(email="[email protected]", password="******", name="Test User", activated=True) db.session.commit() client1 = Client.create_new(name="Demo", user_id=user.id) client1.oauth_client_id = "client-id" client1.oauth_client_secret = "client-secret" db.session.commit() client_user = ClientUser.create(client_id=client1.id, user_id=user.id) db.session.commit() jwt_token = make_id_token(client_user) assert type(jwt_token) is str assert verify_id_token(jwt_token)
def test_authorize_page_non_login_user(flask_client): """make sure to display login page for non-authenticated user""" user = User.create("*****@*****.**", "test user") client = Client.create_new("test client", user.id) db.session.commit() r = flask_client.get( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", response_type="code", )) html = r.get_data(as_text=True) assert r.status_code == 200 assert "In order to accept the request, you need to sign in" in html
def test_authorize_page_login_user(flask_client): """make sure to display authorization page for authenticated user""" user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() r = flask_client.get( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", response_type="code", )) html = r.get_data(as_text=True) assert r.status_code == 200 assert "[email protected] (Personal Email)" in html
def new_client(): form = NewClientForm() if form.validate_on_submit(): client = Client.create_new(form.name.data, current_user.id) db.session.commit() flash("Your app has been created", "success") # if this is the first app user creates, sends an email to ask for feedback if db.session.query(Client).filter_by( user_id=current_user.id).count() == 1: LOG.d(f"send feedback email to user {current_user}") email_utils.send_new_app_email(current_user.email, current_user.name) return redirect( url_for("developer.client_detail", client_id=client.id, is_new=1)) return render_template("developer/new_client.html", form=form)
def test_authorize_code_id_token_flow(flask_client): """make sure the authorize redirects user to correct page for the *ID-Token Code Flow* , ie when response_type=id_token,code The /authorize endpoint should return an id_token, code and id_token must contain *c_hash* The /token endpoint must return a access_token and an id_token """ user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() # user allows client on the authorization page r = flask_client.post( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", response_type="id_token code", # id_token,code flow ), data={ "button": "allow", "suggested-email": "[email protected]", "suggested-name": "AB CD" }, # user will be redirected to client page, do not allow redirection here # to assert the redirect url # follow_redirects=True, ) assert r.status_code == 302 # user gets redirected back to client page # r.location will have this form http://localhost?state=teststate&code=knuyjepwvg o = urlparse(r.location) assert o.netloc == "localhost" assert not o.fragment assert o.query # parse the query, should return something like # {'state': ['teststate'], 'id_token': ['knuyjepwvg'], 'code': ['longstring']} queries = parse_qs(o.query) assert len(queries) == 3 assert queries["state"] == ["teststate"] assert len(queries["id_token"]) == 1 assert len(queries["code"]) == 1 # id_token must be a valid, correctly signed JWT id_token = queries["id_token"][0] assert verify_id_token(id_token) # make sure jwt has all the necessary fields jwt = decode_id_token(id_token) # payload should have this format # { # 'at_hash': 'jLDmoGpuOIHwxeyFEe9SKw', # 'aud': 'testclient-sywcpwsyua', # 'auth_time': 1565450736, # 'avatar_url': None, # 'client': 'test client', # 'email': '[email protected]', # 'email_verified': True, # 'exp': 1565454336, # 'iat': 1565450736, # 'id': 1, # 'iss': 'http://localhost', # 'name': 'AB CD', # 'sub': '1' # } payload = json.loads(jwt.claims) # at_hash MUST be present when the flow is id_token,token assert "c_hash" in payload assert "aud" in payload assert "auth_time" in payload assert "avatar_url" in payload assert "client" in payload assert "email" in payload assert "email_verified" in payload assert "exp" in payload assert "iat" in payload assert "id" in payload assert "iss" in payload assert "name" in payload assert "sub" in payload # <<< Exchange the code to get access_token >>> basic_auth_headers = base64.b64encode( f"{client.oauth_client_id}:{client.oauth_client_secret}".encode( )).decode("utf-8") r = flask_client.post( url_for("oauth.token"), headers={"Authorization": "Basic " + basic_auth_headers}, data={ "grant_type": "authorization_code", "code": queries["code"][0] }, ) # r.json should have this format # { # 'access_token': 'avmhluhonsouhcwwailydwvhankspptgidoggcbu', # 'id_token': 'ab.cd.xy', # 'expires_in': 3600, # 'scope': '', # 'token_type': 'bearer', # 'user': { # 'avatar_url': None, # 'client': 'test client', # 'email': '[email protected]', # 'email_verified': True, # 'id': 1, # 'name': 'AB CD' # } # } assert r.status_code == 200 assert r.json["access_token"] assert r.json["expires_in"] == 3600 assert not r.json["scope"] assert r.json["token_type"] == "Bearer" client_user = ClientUser.first() assert r.json["user"] == { "avatar_url": None, "client": "test client", "email": "[email protected]", "email_verified": True, "id": client_user.id, "name": "AB CD", "sub": str(client_user.id), } # id_token must be returned assert r.json["id_token"] # id_token must be a valid, correctly signed JWT assert verify_id_token(r.json["id_token"])
def test_authorize_token_id_token_flow(flask_client): """make sure the authorize redirects user to correct page for the *ID-Token Token Flow* , ie when response_type=id_token,token The /authorize endpoint should return an id_token and access_token id_token, once decoded, should contain *at_hash* in payload """ user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() # user allows client on the authorization page r = flask_client.post( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", response_type="id_token token", # id_token,token flow ), data={ "button": "allow", "suggested-email": "[email protected]", "suggested-name": "AB CD" }, # user will be redirected to client page, do not allow redirection here # to assert the redirect url # follow_redirects=True, ) assert r.status_code == 302 # user gets redirected back to client page # r.location will have this form http://localhost?state=teststate&code=knuyjepwvg o = urlparse(r.location) assert o.netloc == "localhost" assert o.fragment assert not o.query # parse the fragment, should return something like # {'state': ['teststate'], 'id_token': ['knuyjepwvg']} queries = parse_qs(o.fragment) assert len(queries) == 3 assert queries["state"] == ["teststate"] # access_token must be returned assert len(queries["id_token"]) == 1 assert len(queries["access_token"]) == 1 # id_token must be a valid, correctly signed JWT id_token = queries["id_token"][0] assert verify_id_token(id_token) # make sure jwt has all the necessary fields jwt = decode_id_token(id_token) # payload should have this format # { # 'at_hash': 'jLDmoGpuOIHwxeyFEe9SKw', # 'aud': 'testclient-sywcpwsyua', # 'auth_time': 1565450736, # 'avatar_url': None, # 'client': 'test client', # 'email': '[email protected]', # 'email_verified': True, # 'exp': 1565454336, # 'iat': 1565450736, # 'id': 1, # 'iss': 'http://localhost', # 'name': 'AB CD', # 'sub': '1' # } payload = json.loads(jwt.claims) # at_hash MUST be present when the flow is id_token,token assert "at_hash" in payload assert "aud" in payload assert "auth_time" in payload assert "avatar_url" in payload assert "client" in payload assert "email" in payload assert "email_verified" in payload assert "exp" in payload assert "iat" in payload assert "id" in payload assert "iss" in payload assert "name" in payload assert "sub" in payload
def fake_data(): LOG.d("create fake data") # Create a user user = User.create( email="*****@*****.**", name="John Wick", password="******", activated=True, is_admin=True, # enable_otp=True, otp_secret="base32secret3232", intro_shown=True, fido_uuid=None, ) user.trial_end = None Session.commit() # add a profile picture file_path = "profile_pic.svg" s3.upload_from_bytesio( file_path, open(os.path.join(ROOT_DIR, "static", "default-icon.svg"), "rb"), content_type="image/svg", ) file = File.create(user_id=user.id, path=file_path, commit=True) user.profile_picture_id = file.id Session.commit() # create a bounced email alias = Alias.create_new_random(user) Session.commit() bounce_email_file_path = "bounce.eml" s3.upload_email_from_bytesio( bounce_email_file_path, open(os.path.join(ROOT_DIR, "local_data", "email_tests", "2.eml"), "rb"), "download.eml", ) refused_email = RefusedEmail.create( path=bounce_email_file_path, full_report_path=bounce_email_file_path, user_id=user.id, commit=True, ) contact = Contact.create( user_id=user.id, alias_id=alias.id, website_email="*****@*****.**", reply_email="*****@*****.**", commit=True, ) EmailLog.create( user_id=user.id, contact_id=contact.id, alias_id=contact.alias_id, refused_email_id=refused_email.id, bounced=True, commit=True, ) LifetimeCoupon.create(code="lifetime-coupon", nb_used=10, commit=True) Coupon.create(code="coupon", commit=True) # Create a subscription for user Subscription.create( user_id=user.id, cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234", update_url="https://checkout.paddle.com/subscription/update?user=1234", subscription_id="123", event_time=arrow.now(), next_bill_date=arrow.now().shift(days=10).date(), plan=PlanEnum.monthly, commit=True, ) CoinbaseSubscription.create(user_id=user.id, end_at=arrow.now().shift(days=10), commit=True) api_key = ApiKey.create(user_id=user.id, name="Chrome") api_key.code = "code" api_key = ApiKey.create(user_id=user.id, name="Firefox") api_key.code = "codeFF" pgp_public_key = open(get_abs_path("local_data/public-pgp.asc")).read() m1 = Mailbox.create( user_id=user.id, email="*****@*****.**", verified=True, pgp_public_key=pgp_public_key, ) m1.pgp_finger_print = load_public_key(pgp_public_key) Session.commit() # [email protected] is in a LOT of data breaches Alias.create(email="*****@*****.**", user_id=user.id, mailbox_id=m1.id) for i in range(3): if i % 2 == 0: a = Alias.create(email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=m1.id) else: a = Alias.create( email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=user.default_mailbox_id, ) Session.commit() if i % 5 == 0: if i % 2 == 0: AliasMailbox.create(alias_id=a.id, mailbox_id=user.default_mailbox_id) else: AliasMailbox.create(alias_id=a.id, mailbox_id=m1.id) Session.commit() # some aliases don't have any activity # if i % 3 != 0: # contact = Contact.create( # user_id=user.id, # alias_id=a.id, # website_email=f"contact{i}@example.com", # reply_email=f"rep{i}@sl.local", # ) # Session.commit() # for _ in range(3): # EmailLog.create(user_id=user.id, contact_id=contact.id, alias_id=contact.alias_id) # Session.commit() # have some disabled alias if i % 5 == 0: a.enabled = False Session.commit() custom_domain1 = CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) Session.commit() Alias.create( user_id=user.id, email="*****@*****.**", mailbox_id=user.default_mailbox_id, custom_domain_id=custom_domain1.id, commit=True, ) Alias.create( user_id=user.id, email="*****@*****.**", mailbox_id=user.default_mailbox_id, custom_domain_id=custom_domain1.id, commit=True, ) Directory.create(user_id=user.id, name="abcd") Directory.create(user_id=user.id, name="xyzt") Session.commit() # Create a client client1 = Client.create_new(name="Demo", user_id=user.id) client1.oauth_client_id = "client-id" client1.oauth_client_secret = "client-secret" Session.commit() RedirectUri.create(client_id=client1.id, uri="https://your-website.com/oauth-callback") client2 = Client.create_new(name="Demo 2", user_id=user.id) client2.oauth_client_id = "client-id2" client2.oauth_client_secret = "client-secret2" Session.commit() ClientUser.create(user_id=user.id, client_id=client1.id, name="Fake Name") referral = Referral.create(user_id=user.id, code="Website", name="First referral") Referral.create(user_id=user.id, code="Podcast", name="First referral") Payout.create(user_id=user.id, amount=1000, number_upgraded_account=100, payment_method="BTC") Payout.create( user_id=user.id, amount=5000, number_upgraded_account=200, payment_method="PayPal", ) Session.commit() for i in range(6): Notification.create(user_id=user.id, message=f"""Hey hey <b>{i}</b> """ * 10) Session.commit() user2 = User.create( email="*****@*****.**", password="******", activated=True, referral_id=referral.id, ) Mailbox.create(user_id=user2.id, email="*****@*****.**", verified=True) Session.commit() ManualSubscription.create( user_id=user2.id, end_at=arrow.now().shift(years=1, days=1), comment="Local manual", commit=True, ) SLDomain.create(domain="premium.com", premium_only=True, commit=True) hibp1 = Hibp.create(name="first breach", description="breach description", commit=True) hibp2 = Hibp.create(name="second breach", description="breach description", commit=True) breached_alias1 = Alias.create(email="*****@*****.**", user_id=user.id, mailbox_id=m1.id, commit=True) breached_alias2 = Alias.create(email="*****@*****.**", user_id=user.id, mailbox_id=m1.id, commit=True) AliasHibp.create(hibp_id=hibp1.id, alias_id=breached_alias1.id) AliasHibp.create(hibp_id=hibp2.id, alias_id=breached_alias2.id) # old domain will have ownership_verified=True CustomDomain.create(user_id=user.id, domain="old.com", verified=True, ownership_verified=True)
def fake_data(): LOG.d("create fake data") # Remove db if exist if os.path.exists("db.sqlite"): LOG.d("remove existing db file") os.remove("db.sqlite") # Create all tables db.create_all() # Create a user user = User.create( email="*****@*****.**", name="John Wick", password="******", activated=True, is_admin=True, # enable_otp=True, otp_secret="base32secret3232", intro_shown=True, fido_uuid=None, ) user.trial_end = None db.session.commit() # add a profile picture file_path = "profile_pic.svg" s3.upload_from_bytesio( file_path, open(os.path.join(ROOT_DIR, "static", "default-icon.svg"), "rb"), content_type="image/svg", ) file = File.create(user_id=user.id, path=file_path, commit=True) user.profile_picture_id = file.id db.session.commit() # create a bounced email alias = Alias.create_new_random(user) db.session.commit() bounce_email_file_path = "bounce.eml" s3.upload_email_from_bytesio( bounce_email_file_path, open(os.path.join(ROOT_DIR, "local_data", "email_tests", "2.eml"), "rb"), "download.eml", ) refused_email = RefusedEmail.create( path=bounce_email_file_path, full_report_path=bounce_email_file_path, user_id=user.id, commit=True, ) contact = Contact.create( user_id=user.id, alias_id=alias.id, website_email="*****@*****.**", reply_email="*****@*****.**", commit=True, ) EmailLog.create( user_id=user.id, contact_id=contact.id, refused_email_id=refused_email.id, bounced=True, commit=True, ) LifetimeCoupon.create(code="coupon", nb_used=10, commit=True) # Create a subscription for user Subscription.create( user_id=user.id, cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234", update_url="https://checkout.paddle.com/subscription/update?user=1234", subscription_id="123", event_time=arrow.now(), next_bill_date=arrow.now().shift(days=10).date(), plan=PlanEnum.monthly, commit=True, ) CoinbaseSubscription.create( user_id=user.id, end_at=arrow.now().shift(days=10), commit=True ) api_key = ApiKey.create(user_id=user.id, name="Chrome") api_key.code = "code" api_key = ApiKey.create(user_id=user.id, name="Firefox") api_key.code = "codeFF" pgp_public_key = open(get_abs_path("local_data/public-pgp.asc")).read() m1 = Mailbox.create( user_id=user.id, email="*****@*****.**", verified=True, pgp_public_key=pgp_public_key, ) m1.pgp_finger_print = load_public_key(pgp_public_key) db.session.commit() for i in range(3): if i % 2 == 0: a = Alias.create( email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=m1.id ) else: a = Alias.create( email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=user.default_mailbox_id, ) db.session.commit() if i % 5 == 0: if i % 2 == 0: AliasMailbox.create(alias_id=a.id, mailbox_id=user.default_mailbox_id) else: AliasMailbox.create(alias_id=a.id, mailbox_id=m1.id) db.session.commit() # some aliases don't have any activity # if i % 3 != 0: # contact = Contact.create( # user_id=user.id, # alias_id=a.id, # website_email=f"contact{i}@example.com", # reply_email=f"rep{i}@sl.local", # ) # db.session.commit() # for _ in range(3): # EmailLog.create(user_id=user.id, contact_id=contact.id) # db.session.commit() # have some disabled alias if i % 5 == 0: a.enabled = False db.session.commit() CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) CustomDomain.create( user_id=user.id, domain="very-long-domain.com.net.org", verified=True ) db.session.commit() Directory.create(user_id=user.id, name="abcd") Directory.create(user_id=user.id, name="xyzt") db.session.commit() # Create a client client1 = Client.create_new(name="Demo", user_id=user.id) client1.oauth_client_id = "client-id" client1.oauth_client_secret = "client-secret" client1.published = True db.session.commit() RedirectUri.create(client_id=client1.id, uri="https://ab.com") client2 = Client.create_new(name="Demo 2", user_id=user.id) client2.oauth_client_id = "client-id2" client2.oauth_client_secret = "client-secret2" client2.published = True db.session.commit() ClientUser.create(user_id=user.id, client_id=client1.id, name="Fake Name") referral = Referral.create(user_id=user.id, code="REFCODE", name="First referral") db.session.commit() for i in range(6): Notification.create(user_id=user.id, message=f"""Hey hey <b>{i}</b> """ * 10) db.session.commit() user2 = User.create( email="*****@*****.**", password="******", activated=True, referral_id=referral.id, ) Mailbox.create(user_id=user2.id, email="*****@*****.**", verified=True) db.session.commit() ManualSubscription.create( user_id=user2.id, end_at=arrow.now().shift(years=1, days=1), commit=True )
def fake_data(): LOG.d("create fake data") # Remove db if exist if os.path.exists("db.sqlite"): LOG.d("remove existing db file") os.remove("db.sqlite") # Create all tables db.create_all() # Create a user user = User.create( email="*****@*****.**", name="John Wick", password="******", activated=True, is_admin=True, otp_secret="base32secret3232", ) db.session.commit() LifetimeCoupon.create(code="coupon", nb_used=10) db.session.commit() # Create a subscription for user Subscription.create( user_id=user.id, cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234", update_url="https://checkout.paddle.com/subscription/update?user=1234", subscription_id="123", event_time=arrow.now(), next_bill_date=arrow.now().shift(days=10).date(), plan=PlanEnum.monthly, ) db.session.commit() api_key = ApiKey.create(user_id=user.id, name="Chrome") api_key.code = "code" GenEmail.create_new(user.id, "e1@") GenEmail.create_new(user.id, "e2@") GenEmail.create_new(user.id, "e3@") CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) CustomDomain.create(user_id=user.id, domain="very-long-domain.com.net.org", verified=True) db.session.commit() Directory.create(user_id=user.id, name="abcd") Directory.create(user_id=user.id, name="xyzt") db.session.commit() # Create a client client1 = Client.create_new(name="Demo", user_id=user.id) client1.oauth_client_id = "client-id" client1.oauth_client_secret = "client-secret" client1.published = True db.session.commit() RedirectUri.create(client_id=client1.id, uri="https://ab.com") client2 = Client.create_new(name="Demo 2", user_id=user.id) client2.oauth_client_id = "client-id2" client2.oauth_client_secret = "client-secret2" client2.published = True db.session.commit() db.session.commit()
def fake_data(): LOG.d("create fake data") # Remove db if exist if os.path.exists("db.sqlite"): LOG.d("remove existing db file") os.remove("db.sqlite") # Create all tables db.create_all() # Create a user user = User.create( email="*****@*****.**", name="John Wick", password="******", activated=True, is_admin=True, enable_otp=False, otp_secret="base32secret3232", intro_shown=True, fido_uuid=None, ) user.include_sender_in_reverse_alias = None db.session.commit() user.trial_end = None LifetimeCoupon.create(code="coupon", nb_used=10, commit=True) # Create a subscription for user # Subscription.create( # user_id=user.id, # cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234", # update_url="https://checkout.paddle.com/subscription/update?user=1234", # subscription_id="123", # event_time=arrow.now(), # next_bill_date=arrow.now().shift(days=10).date(), # plan=PlanEnum.monthly, # ) # db.session.commit() CoinbaseSubscription.create(user_id=user.id, end_at=arrow.now().shift(days=10), commit=True) api_key = ApiKey.create(user_id=user.id, name="Chrome") api_key.code = "code" api_key = ApiKey.create(user_id=user.id, name="Firefox") api_key.code = "codeFF" pgp_public_key = open(get_abs_path("local_data/public-pgp.asc")).read() m1 = Mailbox.create( user_id=user.id, email="*****@*****.**", verified=True, pgp_public_key=pgp_public_key, ) m1.pgp_finger_print = load_public_key(pgp_public_key) db.session.commit() for i in range(3): if i % 2 == 0: a = Alias.create(email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=m1.id) else: a = Alias.create( email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=user.default_mailbox_id, ) db.session.commit() if i % 5 == 0: if i % 2 == 0: AliasMailbox.create(alias_id=a.id, mailbox_id=user.default_mailbox_id) else: AliasMailbox.create(alias_id=a.id, mailbox_id=m1.id) db.session.commit() # some aliases don't have any activity # if i % 3 != 0: # contact = Contact.create( # user_id=user.id, # alias_id=a.id, # website_email=f"contact{i}@example.com", # reply_email=f"rep{i}@sl.local", # ) # db.session.commit() # for _ in range(3): # EmailLog.create(user_id=user.id, contact_id=contact.id) # db.session.commit() # have some disabled alias if i % 5 == 0: a.enabled = False db.session.commit() CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) CustomDomain.create(user_id=user.id, domain="very-long-domain.com.net.org", verified=True) db.session.commit() Directory.create(user_id=user.id, name="abcd") Directory.create(user_id=user.id, name="xyzt") db.session.commit() # Create a client client1 = Client.create_new(name="Demo", user_id=user.id) client1.oauth_client_id = "client-id" client1.oauth_client_secret = "client-secret" client1.published = True db.session.commit() RedirectUri.create(client_id=client1.id, uri="https://ab.com") client2 = Client.create_new(name="Demo 2", user_id=user.id) client2.oauth_client_id = "client-id2" client2.oauth_client_secret = "client-secret2" client2.published = True db.session.commit() ClientUser.create(user_id=user.id, client_id=client1.id, name="Fake Name") referral = Referral.create(user_id=user.id, code="REFCODE", name="First referral") db.session.commit() for i in range(6): Notification.create(user_id=user.id, message=f"""Hey hey <b>{i}</b> """ * 10) db.session.commit() User.create( email="*****@*****.**", password="******", activated=True, referral_id=referral.id, ) db.session.commit()
def test_authorize_code_flow_with_openid_scope(flask_client): """make sure the authorize redirects user to correct page for the *Code Flow* and when the *openid* scope is present , ie when response_type=code, openid in scope The authorize endpoint should stay the same: return the *code*. The token endpoint however should now return id_token in addition to the access_token """ user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() # user allows client on the authorization page r = flask_client.post( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", response_type="code", scope="openid", # openid is in scope ), data={ "button": "allow", "suggested-email": "[email protected]", "suggested-name": "AB CD" }, # user will be redirected to client page, do not allow redirection here # to assert the redirect url # follow_redirects=True, ) assert r.status_code == 302 # user gets redirected back to client page # r.location will have this form http://localhost?state=teststate&code=knuyjepwvg o = urlparse(r.location) assert o.netloc == "localhost" assert not o.fragment # parse the query, should return something like # {'state': ['teststate'], 'code': ['knuyjepwvg'], 'scope': ["openid"]} queries = parse_qs(o.query) assert len(queries) == 3 assert queries["state"] == ["teststate"] assert len(queries["code"]) == 1 # Exchange the code to get access_token basic_auth_headers = base64.b64encode( f"{client.oauth_client_id}:{client.oauth_client_secret}".encode( )).decode("utf-8") r = flask_client.post( url_for("oauth.token"), headers={"Authorization": "Basic " + basic_auth_headers}, data={ "grant_type": "authorization_code", "code": queries["code"][0] }, ) # r.json should have this format # { # 'access_token': 'avmhluhonsouhcwwailydwvhankspptgidoggcbu', # 'expires_in': 3600, # 'scope': '', # 'token_type': 'bearer', # 'user': { # 'avatar_url': None, # 'client': 'test client', # 'email': '[email protected]', # 'email_verified': True, # 'id': 1, # 'name': 'AB CD' # } # } assert r.status_code == 200 assert r.json["access_token"] assert r.json["expires_in"] == 3600 assert r.json["scope"] == "openid" assert r.json["token_type"] == "Bearer" client_user = ClientUser.first() assert r.json["user"] == { "avatar_url": None, "client": "test client", "email": "[email protected]", "email_verified": True, "id": client_user.id, "name": "AB CD", "sub": str(client_user.id), } # id_token must be returned assert r.json["id_token"] # id_token must be a valid, correctly signed JWT assert verify_id_token(r.json["id_token"])