Git Product home page Git Product logo

Comments (3)

Godzilla5111 avatar Godzilla5111 commented on May 29, 2024 1

@AbdealiLoKo In order to use the 'authorized_resources' method, which is one of the two methods by which data filtering is initiated through on Oso (the other being authorized_query, which the authorized_resources method uses under the hood), you need to implement an Adapter.

I noticed you imported the SQLAlchemy Adapter but did not use it, that might be one of the reasons the authorized_resources method is not working. Please refer to the link below for the implementation.

Data Filtering with Oso

Apart from that, I did slight modifications to your code and it worked out for me.
The changes that I made were -

  • Set up the data filtering adapter
  • While registering the classes to oso, I did not specify the fields explicitly
  • Made a slight modification in the 'has_permission rule' inside the policy

Please find the changed code below.

# Models
import enum

from sqlalchemy import Boolean, Column, Enum, ForeignKey, Integer, MetaData, create_engine
from sqlalchemy.orm import declarative_base, relationship, sessionmaker


BaseModel = declarative_base(metadata=MetaData())


class ArticleType(enum.Enum):
    NEWS = "News"
    RECIPE = "Recipe"
    BLOG = "Blog"


class Action(enum.Enum):
    READ = "Read"
    WRITE = "Write"


class UserPermission(BaseModel):
    __tablename__ = "user_permission"
    id = Column(Integer, primary_key=True)
    article_type = Column(Enum(ArticleType), nullable=False)
    action = Column(Enum(Action), nullable=False)
    access = Column(Boolean(), nullable=False)
    user_id = Column(
        Integer, ForeignKey("user.id", ondelete="CASCADE"), index=True, nullable=False
    )


class User(BaseModel):
    __tablename__ = "user"
    id = Column(Integer, primary_key=True)
    permissions = relationship(
        UserPermission, single_parent=True, cascade="all, delete-orphan"
    )


class Article(BaseModel):
    __tablename__ = "article"
    id = Column(Integer, primary_key=True)
    type = Column(Enum(ArticleType))


# Create some data
engine = create_engine("sqlite://", isolation_level=None)
BaseModel.metadata.create_all(engine)

factory = sessionmaker(bind=engine, autocommit=False)
session = factory()


reader = User(
    permissions=[
        UserPermission(article_type=ArticleType.NEWS, action=Action.READ, access=1),
        UserPermission(article_type=ArticleType.RECIPE, action=Action.READ, access=1),
        UserPermission(article_type=ArticleType.NEWS, action=Action.WRITE, access=0),
        UserPermission(article_type=ArticleType.RECIPE, action=Action.WRITE, access=0),
    ]
)
writer = User(
    permissions=[
        UserPermission(article_type=ArticleType.NEWS, action=Action.READ, access=1),
        UserPermission(article_type=ArticleType.RECIPE, action=Action.READ, access=1),
        UserPermission(article_type=ArticleType.NEWS, action=Action.WRITE, access=1),
        UserPermission(article_type=ArticleType.RECIPE, action=Action.WRITE, access=1),
    ]
)

news = Article(type=ArticleType.NEWS)

session.add(reader)
session.add(writer)
session.add(news)
session.commit()


# OSO auth
from oso import NotFoundError, Oso


oso = Oso()
oso.register_class(Article)
oso.register_class(User)
oso.load_str(
    """
allow(actor, action, resource) if
  has_permission(actor, action, resource);

has_permission(user: User, action: String, article: Article) if
  perm in user.permissions and
  perm.article_type = article.type and
  perm.action.value = action and
  perm.access;


resource Article {
  permissions = ["Read", "Write", "Approve"];
}

actor User {}

"""
)

oso.authorize(reader, "Read", news)
print("Viewer can read news")
oso.authorize(writer, "Read", news)
print("Writer can read news")

try:
    oso.authorize(reader, "Write", news)
except NotFoundError:
    print("Viewer cannot write news")

oso.authorize(writer, "Write", news)
print("Writer can write news")

# OSO query
from polar.data.adapter.sqlalchemy_adapter import SqlAlchemyAdapter

oso.set_data_filtering_adapter(SqlAlchemyAdapter(session))

oso.authorized_resources(reader, 'Read', Article)

from oso.

AbdealiLoKo avatar AbdealiLoKo commented on May 29, 2024 1

Ah, I see - thanks for that !

from oso.

Godzilla5111 avatar Godzilla5111 commented on May 29, 2024

Please find the diff for the changes that I have made ...
image

from oso.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.