Пример #1
0
def test_set_get_session():
    from sqlalchemy_oso.session import set_get_session
    from oso import Oso

    def get_session():
        engine = create_engine("sqlite://")
        Base.metadata.create_all(engine)

        Session = sessionmaker(bind=engine)
        session = Session()

        load_fixture_data(session)

        return session

    oso = Oso()
    set_get_session(oso, get_session)
    register_models(oso, Base)
    test_str = """get_repo(name: String) if
                    session = OsoSession.get() and
                    repo = session.query(Repository).filter_by(name: name).first() and
                    repo.name = name;
                    """

    oso.load_str(test_str)
    results = oso.query_rule("get_repo", "Abbey Road")
    assert next(results)
    results = oso.query_rule("get_repo", "Abbey Road")
    assert next(results)
Пример #2
0
def authorize_model_filter(oso: Oso, actor, action, session: Session, model):
    """Return SQLAlchemy expression that applies the policy to ``model``.

    Executing this query will return only authorized objects. If the request is
    not authorized, a query that always contains no result will be returned.

    :param oso: The oso class to use for evaluating the policy.
    :param actor: The actor to authorize.
    :param action: The action to authorize.

    :param session: The SQLAlchemy session.
    :param model: The model to authorize, must be a SQLAlchemy model.
    """
    try:
        mapped_class = inspect(model, raiseerr=True).class_
    except AttributeError:
        raise TypeError(f"Expected a model; received: {model}")

    partial_resource = Partial("resource",
                               TypeConstraint(polar_model_name(mapped_class)))
    results = oso.query_rule("allow", actor, action, partial_resource)

    combined_filter = None
    has_result = False
    for result in results:
        has_result = True

        resource_partial = result["bindings"]["resource"]
        filter = partial_to_filter(resource_partial,
                                   session,
                                   model,
                                   get_model=oso.get_class)
        if combined_filter is None:
            combined_filter = filter
        else:
            combined_filter = combined_filter | filter

    if not has_result:
        return sql.false()

    return combined_filter
Пример #3
0
# Test that a built in string method can be called.
oso.load_str("""?= x = "hello world!" and x.endswith("world!");""")

# Test that a custom error type is thrown.
exception_thrown = False
try:
    oso.load_str("missingSemicolon()")
except UnrecognizedEOF as e:
    exception_thrown = True
    assert (
        str(e)
        == "hit the end of the file unexpectedly. Did you forget a semi-colon at line 1, column 19"
    )
assert exception_thrown

assert list(oso.query_rule("specializers", D("hello"), B.C("hello")))
assert list(oso.query_rule("floatLists"))
assert list(oso.query_rule("intDicts"))
assert list(oso.query_rule("comparisons"))
assert list(oso.query_rule("testForall"))
assert list(oso.query_rule("testRest"))
assert list(oso.query_rule("testMatches", A("hello")))
assert list(oso.query_rule("testMethodCalls", A("hello"), B.C("hello")))
assert list(oso.query_rule("testOr"))
assert list(oso.query_rule("testHttpAndPathMapper"))
assert list(oso.query_rule("testUnifyClass", A))

# Test that cut doesn't return anything.
assert not list(oso.query_rule("testCut"))

# Test that a constant can be called.
Пример #4
0
def authorize_model(oso: Oso, actor, action, session: Session, model):
    """Return SQLAlchemy expression that applies the policy to ``model``.

    Executing this query will return only authorized objects. If the request is
    not authorized, a query that always contains no result will be returned.

    :param oso: The oso class to use for evaluating the policy.
    :param actor: The actor to authorize.
    :param action: The action to authorize.

    :param session: The SQLAlchemy session.
    :param model: The model to authorize, must be a SQLAlchemy model or alias.
    """
    def get_field_type(model, field):
        try:
            field = getattr(model, field)
        except AttributeError:
            raise PolarRuntimeError(f"Cannot get property {field} on {model}.")

        try:
            return field.entity.class_
        except AttributeError as e:
            raise PolarRuntimeError(
                f"Cannot determine type of {field} on {model}.") from e

    oso.host.get_field = get_field_type

    try:
        mapped_class = inspect(model, raiseerr=True).class_
    except AttributeError:
        raise TypeError(f"Expected a model; received: {model}")

    resource = Variable("resource")
    constraint = TypeConstraint(resource, polar_model_name(mapped_class))
    results = oso.query_rule(
        "allow",
        actor,
        action,
        resource,
        bindings={resource: constraint},
        accept_expression=True,
    )

    combined_filter = None
    has_result = False
    for result in results:
        has_result = True

        resource_partial = result["bindings"]["resource"]
        filter = partial_to_filter(resource_partial,
                                   session,
                                   model,
                                   get_model=oso.get_class)
        if combined_filter is None:
            combined_filter = filter
        else:
            combined_filter = combined_filter | filter

    if not has_result:
        return sql.false()

    return combined_filter
Пример #5
0
# Test that a built in string method can be called.
oso.load_str("""?= x = "hello world!" and x.endswith("world!");""")

# Test that a custom error type is thrown.
exception_thrown = False
try:
    oso.load_str("missingSemicolon()")
except UnrecognizedEOF as e:
    exception_thrown = True
    assert (
        str(e)
        == "hit the end of the file unexpectedly. Did you forget a semi-colon at line 1, column 19"
    )
assert exception_thrown

assert list(oso.query_rule("specializers", D("hello"), B.C("hello")))
assert list(oso.query_rule("floatLists"))
assert list(oso.query_rule("intDicts"))
assert list(oso.query_rule("comparisons"))
assert list(oso.query_rule("testForall"))
assert list(oso.query_rule("testRest"))
assert list(oso.query_rule("testMatches", A("hello")))
assert list(oso.query_rule("testMethodCalls", A("hello"), B.C("hello")))
assert list(oso.query_rule("testOr"))
assert list(oso.query_rule("testUnifyClass", A))

# Test that cut doesn't return anything.
assert not list(oso.query_rule("testCut"))

# Test that a constant can be called.
oso.register_constant(math, "MyMath")