def load_google_specific_user_data(db_session, test_user_d): """Add Google-specific user data to Fence db.""" gpg = GoogleProxyGroup(id=userd_dict["gpg_id"], email=userd_dict["gpg_email"]) gsak = GoogleServiceAccountKey( id=userd_dict["gsak_id"], key_id=userd_dict["gsak_key_id"], service_account_id=userd_dict["gsa_id"], ) gsa = GoogleServiceAccount( id=userd_dict["gsa_id"], google_unique_id="d_gui", user_id=userd_dict["user_id"], google_project_id="d_gpid", email=userd_dict["gsa_email"], ) bkt = Bucket(id=userd_dict["bucket_id"]) gbag = GoogleBucketAccessGroup( id=userd_dict["gbag_id"], bucket_id=userd_dict["bucket_id"], email=userd_dict["gbag_email"], ) gpg_gbag = GoogleProxyGroupToGoogleBucketAccessGroup( id=userd_dict["gpg_to_gbag_id"], proxy_group_id=userd_dict["gpg_id"], access_group_id=userd_dict["gbag_id"], ) uga = UserGoogleAccount( id=userd_dict["uga_id"], email=userd_dict["uga_email"], user_id=userd_dict["user_id"], ) uga_pg = UserGoogleAccountToProxyGroup( user_google_account_id=userd_dict["uga_id"], proxy_group_id=userd_dict["gpg_id"]) db_session.add_all([gpg, gsak, gsa, bkt, gbag, gpg_gbag, uga, uga_pg]) user = (db_session.query(User).filter_by( username=userd_dict["user_username"]).first()) user.google_proxy_group_id = userd_dict["gpg_id"] db_session.commit()
def force_update_user_google_account_expiration(user_google_account, proxy_group_id, google_email, expiration, session): """ Adds user's google account to proxy group and/or updates expiration for that google account's access. WARNING: This assumes that provided arguments represent valid information. This BLINDLY adds without verification. Do verification before this. Specifically, this ASSUMES that the proxy group provided belongs to the given user and that the user has ALREADY authenticated to prove the provided google_email is also their's. Args: user_google_account (str): User's linked Google account google_email (str): User's Google email proxy_group_id (str): User's Proxy Google group id expiration (int): new expiration for User's linked Google account to live in the proxy group session: db session to work with """ account_in_proxy_group = ( session.query(UserGoogleAccountToProxyGroup).filter( UserGoogleAccountToProxyGroup.user_google_account_id == user_google_account.id).first()) if account_in_proxy_group: account_in_proxy_group.expires = expiration else: account_in_proxy_group = UserGoogleAccountToProxyGroup( user_google_account_id=user_google_account.id, proxy_group_id=proxy_group_id, expires=expiration, ) session.add(account_in_proxy_group) _add_google_email_to_proxy_group(google_email=google_email, proxy_group_id=proxy_group_id)
def test_google_id_token_linked(db_session, encoded_creds_jwt, oauth_test_client): """ Test google email and link expiration are in id_token for a linked account """ user_id = encoded_creds_jwt["user_id"] proxy_group_id = encoded_creds_jwt["proxy_group_id"] original_expiration = 1000 google_account = "*****@*****.**" # add google account and link existing_account = UserGoogleAccount(email=google_account, user_id=user_id) db_session.add(existing_account) db_session.commit() g_account_access = UserGoogleAccountToProxyGroup( user_google_account_id=existing_account.id, proxy_group_id=proxy_group_id, expires=original_expiration, ) db_session.add(g_account_access) db_session.commit() # get google account info with utility function assert get_linked_google_account_email(user_id) == google_account assert get_linked_google_account_exp(user_id) == original_expiration # get the id token through endpoint data = {"confirm": "yes"} oauth_test_client.authorize(data=data) tokens = oauth_test_client.token() id_token = jwt.decode(tokens.id_token, verify=False) assert "google" in id_token["context"]["user"] assert (id_token["context"]["user"]["google"].get("linked_google_account") == google_account) assert (id_token["context"]["user"]["google"].get( "linked_google_account_exp") == original_expiration)
def test_google_link_g_account_access_extension( app, client, db_session, encoded_creds_jwt, add_new_g_acnt_mock, google_auth_get_user_info_mock, add_google_email_to_proxy_group_mock, ): """ Test the link endpoint that gets hit after authN when the provided Google account is already linked. This time test if we correctly extend the google accounts access. """ user_id = encoded_creds_jwt["user_id"] proxy_group_id = encoded_creds_jwt["proxy_group_id"] original_expiration = 1000 test_auth_code = "abc123" redirect = "http://localhost" google_account = "*****@*****.**" test_session_jwt = create_session_token( app.keypairs[0], config.get("SESSION_TIMEOUT"), context={ "google_link": True, "user_id": user_id, "google_proxy_group_id": proxy_group_id, "redirect": redirect, }, ) existing_account = UserGoogleAccount(email=google_account, user_id=user_id) db_session.add(existing_account) db_session.commit() g_account_access = UserGoogleAccountToProxyGroup( user_google_account_id=existing_account.id, proxy_group_id=proxy_group_id, expires=original_expiration, ) db_session.add(g_account_access) db_session.commit() # manually set cookie for initial session client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt) # simulate successfully authed reponse with user email google_auth_get_user_info_mock.return_value = {"email": google_account} r = client.get("/link/google/callback", query_string={"code": test_auth_code}) account_in_proxy_group = ( db_session.query(UserGoogleAccountToProxyGroup).filter( UserGoogleAccountToProxyGroup.user_google_account_id == existing_account.id).first()) assert account_in_proxy_group.proxy_group_id == proxy_group_id # check that expiration changed and that it's less than the cfg # expires in (since this check will happen a few seconds after # it gets set) assert account_in_proxy_group.expires != original_expiration assert account_in_proxy_group.expires <= ( int(time.time()) + config["GOOGLE_ACCOUNT_ACCESS_EXPIRES_IN"]) assert not add_new_g_acnt_mock.called assert r.status_code == 302 parsed_url = urlparse(r.headers["Location"]) query_params = parse_qs(parsed_url.query) response_redirect = urlunparse( (parsed_url.scheme, parsed_url.netloc, parsed_url.path, "", "", "")) assert "exp" in query_params assert query_params["linked_email"][0] == google_account assert response_redirect == redirect assert not flask.session.get("google_link") assert not flask.session.get("user_id") assert not flask.session.get("google_proxy_group_id") assert not add_google_email_to_proxy_group_mock.called
def test_patch_google_link_account_not_in_token( app, client, db_session, encoded_creds_jwt, google_auth_get_user_info_mock, add_google_email_to_proxy_group_mock, ): """ Test extending expiration for previously linked G account access via PATCH. This will test the case where the linking happened during the life of an access token and the same access token is used here (e.g. account exists but a new token hasn't been generated with the linkage info yet) """ encoded_credentials_jwt = encoded_creds_jwt["jwt"] user_id = encoded_creds_jwt["user_id"] proxy_group_id = encoded_creds_jwt["proxy_group_id"] original_expiration = 1000 google_account = "*****@*****.**" test_session_jwt = create_session_token( app.keypairs[0], config.get("SESSION_TIMEOUT"), context={"google_proxy_group_id": proxy_group_id}, ) existing_account = UserGoogleAccount(email=google_account, user_id=user_id) db_session.add(existing_account) db_session.commit() g_account_access = UserGoogleAccountToProxyGroup( user_google_account_id=existing_account.id, proxy_group_id=proxy_group_id, expires=original_expiration, ) db_session.add(g_account_access) db_session.commit() # manually set cookie for initial session client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt) r = client.patch( "/link/google", headers={"Authorization": "Bearer " + encoded_credentials_jwt}) assert r.status_code == 200 account_in_proxy_group = ( db_session.query(UserGoogleAccountToProxyGroup).filter( UserGoogleAccountToProxyGroup.user_google_account_id == existing_account.id).first()) assert account_in_proxy_group.proxy_group_id == proxy_group_id # check that expiration changed and that it's less than the cfg # expires in (since this check will happen a few seconds after # it gets set) assert account_in_proxy_group.expires != original_expiration assert account_in_proxy_group.expires <= ( int(time.time()) + config["GOOGLE_ACCOUNT_ACCESS_EXPIRES_IN"]) assert not add_google_email_to_proxy_group_mock.called
def test_patch_google_link( app, client, db_session, encoded_creds_jwt, google_auth_get_user_info_mock, add_google_email_to_proxy_group_mock, ): """ Test extending expiration for previously linked G account access via PATCH. Test valid and invalid expires_in parameters. """ encoded_credentials_jwt = encoded_creds_jwt["jwt"] user_id = encoded_creds_jwt["user_id"] proxy_group_id = encoded_creds_jwt["proxy_group_id"] original_expiration = 1000 google_account = "*****@*****.**" test_session_jwt = create_session_token( app.keypairs[0], config.get("SESSION_TIMEOUT"), context={ "google_proxy_group_id": proxy_group_id, "linked_google_email": google_account, }, ) existing_account = UserGoogleAccount(email=google_account, user_id=user_id) db_session.add(existing_account) db_session.commit() g_account_access = UserGoogleAccountToProxyGroup( user_google_account_id=existing_account.id, proxy_group_id=proxy_group_id, expires=original_expiration, ) db_session.add(g_account_access) db_session.commit() # manually set cookie for initial session client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt) r = client.patch( "/link/google", headers={"Authorization": "Bearer " + encoded_credentials_jwt}) assert r.status_code == 200 account_in_proxy_group = ( db_session.query(UserGoogleAccountToProxyGroup).filter( UserGoogleAccountToProxyGroup.user_google_account_id == existing_account.id).first()) assert account_in_proxy_group.proxy_group_id == proxy_group_id # check that expiration changed and that it's less than the cfg # expires in (since this check will happen a few seconds after # it gets set) updated_expiration = account_in_proxy_group.expires assert updated_expiration != original_expiration assert updated_expiration <= (int(time.time()) + config["GOOGLE_ACCOUNT_ACCESS_EXPIRES_IN"]) assert not add_google_email_to_proxy_group_mock.called # invalid expires_in: should fail requested_exp = "abc" # expires_in must be int >0 r = client.patch( "/link/google?expires_in={}".format(requested_exp), headers={"Authorization": "Bearer " + encoded_credentials_jwt}, ) assert r.status_code == 400 # valid expires_in: should succeed requested_exp = 60 r = client.patch( "/link/google?expires_in={}".format(requested_exp), headers={"Authorization": "Bearer " + encoded_credentials_jwt}, ) assert r.status_code == 200 account_in_proxy_group = ( db_session.query(UserGoogleAccountToProxyGroup).filter( UserGoogleAccountToProxyGroup.user_google_account_id == existing_account.id).first()) # make sure the link is valid for the requested time # (allow up to 15 sec for runtime) diff = account_in_proxy_group.expires - int(time.time()) assert requested_exp <= diff <= requested_exp + 15