def create_client( username, urls, DB, name="", description="", auto_approve=False, is_admin=False, grant_types=None, confidential=True, arborist=None, policies=None, allowed_scopes=None, ): client_id = random_str(40) if arborist is not None: arborist.create_client(client_id, policies) grant_types = grant_types driver = SQLAlchemyDriver(DB) client_secret = None hashed_secret = None if confidential: client_secret = random_str(55) hashed_secret = bcrypt.hashpw(client_secret.encode("utf-8"), bcrypt.gensalt()).decode("utf-8") auth_method = "client_secret_basic" if confidential else "none" allowed_scopes = allowed_scopes or config["CLIENT_ALLOWED_SCOPES"] if not set(allowed_scopes).issubset(set(config["CLIENT_ALLOWED_SCOPES"])): raise ValueError("Each allowed scope must be one of: {}".format( config["CLIENT_ALLOWED_SCOPES"])) if "openid" not in allowed_scopes: allowed_scopes.append("openid") logger.warning( 'Adding required "openid" scope to list of allowed scopes.') with driver.session as s: user = query_for_user(session=s, username=username) if not user: user = User(username=username, is_admin=is_admin) s.add(user) if s.query(Client).filter(Client.name == name).first(): if arborist is not None: arborist.delete_client(client_id) raise Exception("client {} already exists".format(name)) client = Client( client_id=client_id, client_secret=hashed_secret, user=user, redirect_uris=urls, _allowed_scopes=" ".join(allowed_scopes), description=description, name=name, auto_approve=auto_approve, grant_types=grant_types, is_confidential=confidential, token_endpoint_auth_method=auth_method, ) s.add(client) s.commit() return client_id, client_secret
def test_client_delete(app, db_session, cloud_manager, test_user_a): """ Test that the client delete function correctly cleans up the client's service accounts and the client themself. """ client_name = "test123" client = Client(client_id=client_name, client_secret="secret", name=client_name) db_session.add(client) db_session.commit() client_service_account = GoogleServiceAccount( google_unique_id="jf09238ufposijf", client_id=client.client_id, user_id=test_user_a["user_id"], google_project_id="test", email="*****@*****.**", ) db_session.add(client_service_account) db_session.commit() # empty return means success (cloud_manager.return_value.__enter__.return_value.delete_service_account. return_value) = {} delete_client_action(app.config["DB"], client_name) client_after = db_session.query(Client).filter_by(name=client_name).all() client_service_account_after = ( db_session.query(GoogleServiceAccount).filter_by( client_id=client.client_id)).all() assert len(client_after) == 0 assert len(client_service_account_after) == 0
def test_modify_client_action_modify_allowed_scopes_append_true(db_session): client_id = "testid" client_name = "test123" client = Client( client_id=client_id, client_secret="secret", name=client_name, _allowed_scopes="openid user data", ) db_session.add(client) db_session.commit() modify_client_action( db_session, client.name, set_auto_approve=True, name="test321", description="test client", append=True, allowed_scopes=["new_scope", "new_scope_2", "new_scope_3"], ) list_client_action(db_session) assert client.auto_approve == True assert client.name == "test321" assert client.description == "test client" assert (client._allowed_scopes == "openid user data new_scope new_scope_2 new_scope_3")
def test_modify_client_action_modify_append_url(db_session): client_id = "testid" client_name = "test123" client = Client( client_id=client_id, client_secret="secret", name=client_name, _allowed_scopes="openid user data", redirect_uris="abcd", ) db_session.add(client) db_session.commit() modify_client_action( db_session, client.name, set_auto_approve=True, name="test321", description="test client", urls=["test1", "test2", "test3"], append=True, ) list_client_action(db_session) assert client.auto_approve == True assert client.name == "test321" assert client.description == "test client" assert client.redirect_uris == ["abcd", "test1", "test2", "test3"]
def test_client_delete_error(app, db_session, cloud_manager, test_user_a): """ Test that when Google gives us an error when deleting the service account, we don't remove it from the db. """ client_name = "test123" client = Client(client_id=client_name, client_secret="secret", name=client_name) db_session.add(client) db_session.commit() client_service_account = GoogleServiceAccount( google_unique_id="jf09238ufposijf", client_id=client.client_id, user_id=test_user_a["user_id"], google_project_id="test", email="*****@*****.**", ) db_session.add(client_service_account) db_session.commit() # error when deleting service account ( cloud_manager.return_value.__enter__.return_value.delete_service_account.return_value ) = {"error": "something bad happened"} delete_client_action(config["DB"], client_name) client_after = db_session.query(Client).filter_by(name=client_name).all() client_service_account_after = ( db_session.query(GoogleServiceAccount).filter_by(client_id=client.client_id) ).all() # make sure client is deleted but service account we couldn't delete stays assert len(client_after) == 0 assert len(client_service_account_after) == 1
def test_list_client_action(db_session, capsys): client_name = "test123" client = Client(client_id=client_name, client_secret="secret", name=client_name) db_session.add(client) db_session.commit() list_client_action(db_session) captured = capsys.readouterr() assert "'client_id': " + "'test123'" in captured[0] assert "'client_secret': " + "'secret'" in captured[0] assert "'name': " + "'test123'" in captured[0]
def test_google_attempt_delete_unowned_access_token(app, client, oauth_client, cloud_manager, db_session): """ Test ``DELETE /credentials/google``. """ client_id = oauth_client["client_id"] service_account_key = "some_key_321" proxy_group_id = "proxy_group_0" path = ("/credentials/google/" + service_account_key + "/") with app.test_client() as app_client: # set global client context flask.g.client_id = client_id # get test user info user = (db_session.query(User).filter_by(username="******").first()) user_id = user.id # create a proxy group for user proxy_group = GoogleProxyGroup( id=proxy_group_id, user_id=user_id, ) db_session.add(proxy_group) # create a service account for A DIFFERENT CLIENT client = Client( client_id="NOT_THIS_GUY", client_secret="a0987u23on192y", name="NOT_THIS_GUY", ) service_account = GoogleServiceAccount( google_unique_id="123456789", client_id="NOT_THIS_GUY", user_id=user_id, email=("NOT_THIS_GUY" + "-" + str(user_id) + "@test.com")) db_session.add(user) db_session.add(client) db_session.add(service_account) db_session.commit() response = app_client.delete(path, data={}) # check that we didn't try to get key info or delete, # since the current user/client doesn't have the key assert (cloud_manager.return_value.__enter__.return_value. get_service_account_keys_info).called is False assert (cloud_manager.return_value.__enter__.return_value. delete_service_account_key).called is False assert response.status_code == 404
def test_google_attempt_delete_unowned_access_token(app, client, oauth_client, cloud_manager, db_session, encoded_creds_jwt): """ Test ``DELETE /credentials/google``. """ encoded_credentials_jwt = encoded_creds_jwt["jwt"] user_id = encoded_creds_jwt["user_id"] service_account_key = "some_key_321" path = "/credentials/google/" + service_account_key + "/" # create a service account for A DIFFERENT CLIENT client_entry = Client(client_id="NOT_THIS_GUY", client_secret="a0987u23on192y", name="NOT_THIS_GUY") service_account = GoogleServiceAccount( google_unique_id="123456789", client_id="NOT_THIS_GUY", user_id=user_id, email=("NOT_THIS_GUY" + "-" + str(user_id) + "@test.com"), google_project_id="projectId-0", ) db_session.add(client_entry) db_session.add(service_account) db_session.commit() # make function return the service account we created and don't try to update db # since we already did it in the test mock = MagicMock() mock.return_value = service_account patch("fence.resources.google.utils.get_or_create_service_account", mock).start() patch("fence.resources.google.utils._update_service_account_db_entry", mock).start() response = client.delete( path, data={}, headers={"Authorization": "Bearer " + encoded_credentials_jwt}) # check that we didn't try to get key info or delete, # since the current user/client doesn't have the key assert (cloud_manager.return_value.__enter__.return_value. get_service_account_keys_info).called is False assert (cloud_manager.return_value.__enter__.return_value. delete_service_account_key).called is False assert response.status_code == 404
def test_user_delete_cascade(db_session): """ test deleting a user will cascade to its children """ user = User(username="******") client = Client( name="test_client", user=user, client_id=random_str(40), client_secret=random_str(60), ) db_session.add(user) db_session.add(client) db_session.flush() assert len(user.clients) == 1 db_session.delete(user) assert db_session.query(Client).filter_by( client_id=client.client_id).count() == 0
def create_client( username, urls, DB, name="", description="", auto_approve=False, is_admin=False, grant_types=None, confidential=True, ): grant_types = grant_types driver = SQLAlchemyDriver(DB) client_id = random_str(40) client_secret = None hashed_secret = None if confidential: client_secret = random_str(55) hashed_secret = bcrypt.hashpw(client_secret, bcrypt.gensalt()) auth_method = "client_secret_basic" if confidential else "none" with driver.session as s: user = query_for_user(session=s, username=username) if not user: user = User(username=username, is_admin=is_admin) s.add(user) if s.query(Client).filter(Client.name == name).first(): raise Exception("client {} already exists".format(name)) client = Client( client_id=client_id, client_secret=hashed_secret, user=user, redirect_uris=urls, _allowed_scopes=" ".join(config["CLIENT_ALLOWED_SCOPES"]), description=description, name=name, auto_approve=auto_approve, grant_types=grant_types, is_confidential=confidential, token_endpoint_auth_method=auth_method, ) s.add(client) s.commit() return client_id, client_secret
def test_modify_client_action(db_session): client_id = "testid" client_name = "test123" client = Client(client_id=client_id, client_secret="secret", name=client_name) db_session.add(client) db_session.commit() modify_client_action( db_session, client.name, set_auto_approve=True, name="test321", description="test client", urls=["test"], ) list_client_action(db_session) assert client.auto_approve == True assert client.name == "test321" assert client.description == "test client" """
def load_non_google_user_data(db_session, test_user_d): """Add general, non-Google user data to Fence db.""" client = Client( client_id=userd_dict["client_id"], user_id=userd_dict["user_id"], issued_at=420, expires_at=42020, redirect_uri="dclient.com", grant_type="dgrant", response_type="dresponse", scope="dscope", name="dclientname", _allowed_scopes="dallscopes", ) grp = Group(id=userd_dict["group_id"]) usr_grp = UserToGroup(user_id=userd_dict["user_id"], group_id=userd_dict["group_id"]) db_session.add_all([client, grp, usr_grp]) db_session.commit()