Пример #1
0
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
Пример #2
0
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
Пример #3
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")
Пример #4
0
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"]
Пример #5
0
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
Пример #6
0
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]
Пример #7
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
Пример #8
0
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
Пример #9
0
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
Пример #10
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
Пример #11
0
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"

    """
Пример #12
0
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()