def test_quickstart_policy_3(): oso = Oso() oso.register_class(Expense) oso.load_file("../polar/expenses-03-py.polar") expense = EXPENSES[1] assert oso.is_allowed("*****@*****.**", "GET", expense) assert not oso.is_allowed("*****@*****.**", "GET", expense)
def test_quickstart_policy_4(): oso = Oso() oso.register_class(Expense) oso.load_file("../polar/expenses-04.polar") assert oso.is_allowed("*****@*****.**", "GET", EXPENSES[1]) assert not oso.is_allowed("*****@*****.**", "GET", EXPENSES[3]) assert not oso.is_allowed("*****@*****.**", "GET", EXPENSES[1]) assert oso.is_allowed("*****@*****.**", "GET", EXPENSES[3])
def test_quickstart_policy_2(): oso = Oso() alice = "*****@*****.**" expense = EXPENSES[1] assert not oso.is_allowed(alice, "GET", expense) oso.register_class(Expense) oso.load_file("../polar/expenses-02.polar") assert oso.is_allowed(alice, "GET", expense) assert not oso.is_allowed("*****@*****.**", "GET", expense)
def create_team_role( org_id: UUID, team_id: UUID, req: schemas.TeamRoleRequest, current_user: models.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), ): team = crud.team.get(db, team_id) if team is None or team.organization_fk != org_id: raise HTTPException(status_code=404) if not auth.is_allowed(current_user, "CREATE_ROLE", team): raise HTTPException(status_code=403) user_to_add = crud.user.get(db, id=req.user_id) if user_to_add is None: raise HTTPException(status_code=404) crud.team_roles.add_user_role(db, user=user_to_add, resource=team, role_name=req.user_role) return "OK"
def create_team( org_id: UUID, req: schemas.TeamCreateRequest, current_user: models.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), ): org = crud.org.get(db, org_id) if org is None: raise HTTPException(status_code=404) # check if user is allowed to create a new team create_team = schemas.TeamCreate( creator=current_user, organization=org, name=req.name, description=req.description, is_active=True, ) new_team = crud.team.create_model(create_team) if not auth.is_allowed(current_user, "CREATE", new_team): raise HTTPException(status_code=403) # add the newly created model to db created_team = crud.team.add_model_to_db(db, model=new_team) # add the user as the team owner crud.team_roles.add_user_role(db, current_user, created_team, "OWNER") return created_team
def delete_dataroom_team_role( org_id: UUID, dataroom_id: UUID, role_id: UUID, current_user: models.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), ): dataroom = crud.dataroom.get(db, dataroom_id) if dataroom is None or dataroom.organization_fk != org_id: raise HTTPException(status_code=404) if not auth.is_allowed(current_user, "DELETE_ROLE", dataroom): raise HTTPException(status_code=403) role = db.query(models.DataRoomRole).filter_by(id=role_id).first() if role is None: raise HTTPException(status_code=404) if role.team_id != role.team_id: raise HTTPException(status_code=404) crud.room_roles.delete_team_role(db, team_role_id=role.id) return "OK"
def create_dataroom_team_role( org_id: UUID, dataroom_id: UUID, req: schemas.DataRoomTeamRoleRequest, current_user: models.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), ): dataroom = crud.dataroom.get(db, dataroom_id) if dataroom is None or dataroom.organization_fk != org_id: raise HTTPException(status_code=404) if not auth.is_allowed(current_user, "CREATE_ROLE", dataroom): raise HTTPException(status_code=403) team_to_add = crud.team.get(db, id=req.team_id) if team_to_add is None: raise HTTPException(status_code=404) crud.room_roles.add_team_role(db, team=team_to_add, room=dataroom, role_name=req.team_role) return "OK"
def update_team_role( org_id: UUID, team_id: UUID, role_id: UUID, req: schemas.TeamRoleRequest, current_user: models.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), ): team = crud.team.get(db, team_id) if team is None or team.organization_fk != org_id: raise HTTPException(status_code=404) if not auth.is_allowed(current_user, "DELETE_ROLE", team): raise HTTPException(status_code=403) role = db.query(models.TeamRole).filter_by(id=role_id).first() if role is None: raise HTTPException(status_code=404) if role.user_id != req.user_id: raise HTTPException(status_code=404) user = crud.user.get(db, id=role.user_id) if user is None: raise HTTPException(status_code=404) crud.team_roles.update_user_role(db, user=user, resource=team, role_name=req.user_role) return "OK"
def create_invite_to_room( dataroom_id: UUID, org_id: UUID, req: schemas.InviteAPIRequest, current_user: models.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), ): # check whether the path is correct so that dataroom belongs to org # and dataroom actually exists room = crud.dataroom.get(db, id=dataroom_id) if not room: raise HTTPException(status_code=400) if not room.organization_fk == org_id: raise HTTPException(status_code=400) # check whether the user is allowed to create invites if not auth.is_allowed(current_user, "INVITE_GUESTS", room): raise HTTPException(status_code=404, detail="Not enough privileges") # check whether the invitee already exists in db, if not create him/her create_user = schemas.UserCreate(email=req.email, password=security.random_password()) invitee = crud.user.create_if_not_exists(db, obj_in=create_user) # add user to the specific role crud.room_roles.add_user_role(db, invitee, room, req.user_role) # generate access url access_token_expires = timedelta(days=req.expires_in) token = security.create_access_token(invitee.id, expires_delta=access_token_expires) # generate invitation entry in db create_invite = schemas.InviteCreate( invitee=invitee, jwt_token=token, dataroom=room, creator=current_user, expires_in=security.calculate_expires_in_days(req.expires_in), ) crud.invite.create(db, obj_in=create_invite) # generate access link access_link = f"{settings.DOMAIN_NAME}/access?token={token}" # generate email and send invite to the user send_access_email( email_to=req.email, access_link=access_link, invitor_name=f"{current_user.first_name} {current_user.last_name}", ) return "OK"
def rmdir(path): import shutil import getpass from oso import Oso oso = Oso() oso.register_class(PathAttributes) oso.load_files(["rmdir.polar"]) path_attributes = get_path_attributes(path) user_id = getpass.getuser() if oso.is_allowed(user_id, "can_remove", path_attributes): shutil.rmtree(path) else: raise PermissionError(f"You cannot delete {path}")
def get_datarooms( org_id: UUID, db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), current_user: models.User = Depends(deps.get_current_active_user), ): org = crud.org.get(db, org_id) if org is None: raise HTTPException(status_code=404) # first find out if the user is allowed to list rooms in a given org if not auth.is_allowed(current_user, "LIST_ROOMS", org): raise HTTPException(status_code=400, detail="Not enough privileges") rooms = crud.dataroom.get_multi_by_org(db, org) return rooms
def list_documents( dataroom_id: UUID, org_id: UUID, db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), current_user: models.User = Depends(deps.get_current_active_user), ) -> Any: # check whether the path is correct and dataroom belongs to org room = crud.dataroom.get(db, id=dataroom_id) if not room.organization_fk == org_id: raise HTTPException(status_code=400) # make sure user is allowed to list documents if not auth.is_allowed(current_user, "LIST_DOCUMENTS", room): raise HTTPException(status_code=404) documents = crud.document.get_multi_by_room(db, dataroom_id) return documents
def update_invitation( dataroom_id: UUID, org_id: UUID, invite_id: UUID, req: schemas.InviteAPIRequest, current_user: models.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), ): # check whether the path is correct so that dataroom belongs to org # and dataroom actually exists room = crud.dataroom.get(db, id=dataroom_id) if not room: raise HTTPException(status_code=400) if not room.organization_fk == org_id: raise HTTPException(status_code=400) # check whether the user is allowed to create invites if not auth.is_allowed(current_user, "INVITE_GUESTS", room): raise HTTPException(status_code=404, detail="Not enough privileges") invitation = crud.invite.get(db, invite_id) if not invitation: raise HTTPException(status_code=404) if not invitation.invitee.email == req.email: raise HTTPException(status_code=400) crud.room_roles.update_user_role(db, invitation.invitee, room, req.user_role) expires_in_timestamp = security.calculate_expires_in_days(req.expires_in) invitation_update_schema = schemas.InviteUpdate( expires_in=expires_in_timestamp) crud.invite.update(db, db_obj=invitation, obj_in=invitation_update_schema) return "OK"
def update_team( org_id: UUID, team_id: UUID, req: schemas.TeamCreateRequest, current_user: models.User = Depends(deps.get_current_active_user), db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), ): team = crud.team.get(db, team_id) if team is None or team.organization_fk != org_id: raise HTTPException(status_code=404) if not auth.is_allowed(current_user, "UPDATE", team): raise HTTPException(status_code=403) update_team = schemas.TeamUpdate(name=req.name, description=req.description) updated_team = crud.team.update(db, db_obj=team, obj_in=update_team) return updated_team
def test_team_dataroom_roles(db: Session, data: Data, oso: Oso): # make sure that a user that does not have direct # room roles can still manage room because of a team # role user_roles_in_room_1: List = oso_roles.get_user_roles( db, data.member_team_1, Dataroom, data.room_1.id) # user does not have direct access to the room count_of_roles = len(user_roles_in_room_1) assert count_of_roles == 0 # but still gets it via his team role (which is a members role) assert oso.is_allowed(data.member_team_1, "READ", data.room_1) is True assert oso.is_allowed(data.member_team_1, "LIST_DOCUMENTS", data.room_1) is True assert oso.is_allowed(data.member_team_1, "DELETE", data.room_1) is False assert oso.is_allowed(data.member_team_1, "UPDATE", data.room_1) is False assert oso.is_allowed(data.member_team_1, "INVITE_GUESTS", data.room_1) is False # does not have access to other rooms assert oso.is_allowed(data.member_team_1, "READ", data.room_2) is False assert oso.is_allowed(data.member_team_1, "LIST_DOCUMENTS", data.room_2) is False # is allowed to create his own documents in a room new_document_team_member_1 = Document( name="New Doc Team Member 1", description="Test", file_name="new_doc_team_member_1", extension="txt", md5_sum=UUID("87a6909ab71ec463f013325dbf9f3543"), mime_type="text/plain", size=50, creator=data.member_team_1, dataroom=data.room_1, ) assert (oso.is_allowed(data.member_team_1, "CREATE", new_document_team_member_1) is True)
def create_dataroom( org_id: UUID, dataroom_request: schemas.DataRoomCreateRequest, db: Session = Depends(deps.get_db), auth: Oso = Depends(deps.get_oso), current_user: models.User = Depends(deps.get_current_active_user), ): org = crud.org.get(db, org_id) if org is None: raise HTTPException(status_code=404) # create the room model in order to verify if user is allowed to create it create_room_schema = schemas.DataRoomCreate(creator=current_user, organization=org, name=dataroom_request.name) new_room = crud.dataroom.create_model(create_room_schema) # first find out if the user is allowed to create rooms in a given org if not auth.is_allowed(current_user, "CREATE", new_room): raise HTTPException(status_code=403, detail="Not enough privileges") new_room = crud.dataroom.add_model_to_db(db, model=new_room) return new_room
oso.register_class(B.C, name="C", from_polar=custom_c_constructor) class E: @staticmethod def sum(*args): return sum(*args) oso.register_class(E) polar_file = os.path.dirname(os.path.realpath(__file__)) + "/test.polar" oso.load_file(polar_file) assert oso.is_allowed("a", "b", "c") # 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
def test_dataroom_roles(db: Session, data: Data, oso: Oso): # Guest can access the documents for the room in which he is guest assert oso.is_allowed(data.guest_read_user_room_1, "READ", data.room_1) is True assert (oso.is_allowed(data.guest_read_user_room_1, "LIST_DOCUMENTS", data.room_1) is True) assert (oso.is_allowed(data.guest_read_user_room_1, "READ", data.document_room_1) is True) # Guest cannot see other datarooms assert (oso.is_allowed(data.guest_read_user_room_1, "LIST_ROOMS", data.first_org) is False) assert oso.is_allowed(data.guest_read_user_room_1, "READ", data.room_2) is False assert (oso.is_allowed(data.guest_read_user_room_1, "READ", data.document_room_2) is False) new_document_guest_1 = Document( name="Test Document", description="Test", file_name="hallo", extension="txt", md5_sum=UUID("87a6909ab71ec463f013325dbf9f3541"), mime_type="text/plain", size=50, creator=data.guest_read_user_room_1, dataroom=data.room_1, ) new_document_guest_2 = Document( name="New Doc Guest 2", description="Test", file_name="new_doc_guest_2", extension="txt", md5_sum=UUID("87a6909ab71ec463f013325dbf9f3541"), mime_type="text/plain", size=50, creator=data.guest_write_user_room_1, dataroom=data.room_1, ) # Only guest with write access can create a new document assert (oso.is_allowed(data.guest_write_user_room_1, "CREATE", new_document_guest_2) is True) assert (oso.is_allowed(data.guest_read_user_room_1, "CREATE", new_document_guest_1) is False) # add the second new document to db so that we can test edits db.add(new_document_guest_2) db.commit() db.refresh(new_document_guest_2) assert (oso.is_allowed(data.guest_write_user_room_1, "UPDATE", new_document_guest_2) is True) assert (oso.is_allowed(data.guest_write_user_room_1, "DELETE", new_document_guest_2) is True) assert (oso.is_allowed(data.guest_write_user_room_1, "UPDATE", data.document_room_1) is False) assert (oso.is_allowed(data.guest_write_user_room_1, "DELETE", data.document_room_1) is False) assert (oso.is_allowed(data.admin_user_room_1, "UPDATE", data.document_room_1) is True) assert (oso.is_allowed(data.admin_user_room_1, "DELETE", data.document_room_1) is True) # Only OWNERS can delete a dataroom assert oso.is_allowed(data.member_user_org_1, "DELETE", data.room_1) is True assert oso.is_allowed(data.guest_read_user_room_1, "DELETE", data.room_1) is False assert oso.is_allowed(data.guest_write_user_room_1, "DELETE", data.room_1) is False # Admin are allowed to invite_guests assert oso.is_allowed(data.admin_user_room_1, "INVITE_GUESTS", data.room_1) is True assert oso.is_allowed(data.admin_user_room_1, "INVITE_GUESTS", data.room_2) is False new_document_member_1 = Document( name="New Doc Member 1", description="Test", file_name="new_doc_member_1", extension="txt", md5_sum=UUID("87a6909ab71ec463f013325dbf9f3543"), mime_type="text/plain", size=50, creator=data.member_user_room_1, dataroom=data.room_1, ) # Members can create documents and edit and delete their own assert (oso.is_allowed(data.member_user_room_1, "CREATE", new_document_member_1) is True) db.add(new_document_member_1) db.commit() db.refresh(new_document_member_1) assert (oso.is_allowed(data.member_user_room_1, "UPDATE", new_document_member_1) is True) assert (oso.is_allowed(data.member_user_room_1, "DELETE", new_document_member_1) is True) assert (oso.is_allowed(data.member_user_room_1, "UPDATE", new_document_guest_2) is False) assert (oso.is_allowed(data.member_user_room_1, "DELETE", new_document_guest_2) is False)
def test_org_roles(db: Session, data: Data, oso: Oso): # Any type of org role can read the specific org but not another org assert oso.is_allowed(data.member_user_org_1, "READ", data.first_org) is True assert oso.is_allowed(data.admin_user_org_1, "READ", data.first_org) is True assert oso.is_allowed(data.lead_user_org_1, "READ", data.first_org) is True assert oso.is_allowed(data.lead_user_org_1, "READ", data.second_org) is False assert oso.is_allowed(data.member_user_org_1, "READ", data.second_org) is False assert oso.is_allowed(data.admin_user_org_1, "READ", data.second_org) is False # Any type of org role can list all the teams in the specific org assert oso.is_allowed(data.member_user_org_1, "LIST_TEAMS", data.first_org) is True assert oso.is_allowed(data.admin_user_org_1, "LIST_TEAMS", data.first_org) is True assert oso.is_allowed(data.lead_user_org_1, "LIST_TEAMS", data.first_org) is True assert oso.is_allowed(data.lead_user_org_1, "LIST_TEAMS", data.second_org) is False assert (oso.is_allowed(data.member_user_org_1, "LIST_TEAMS", data.second_org) is False) assert oso.is_allowed(data.admin_user_org_1, "LIST_TEAMS", data.second_org) is False # Any type of org role can list all the rooms in the specific org assert oso.is_allowed(data.member_user_org_1, "LIST_ROOMS", data.first_org) is True assert oso.is_allowed(data.admin_user_org_1, "LIST_ROOMS", data.first_org) is True assert oso.is_allowed(data.lead_user_org_1, "LIST_ROOMS", data.first_org) is True assert oso.is_allowed(data.lead_user_org_1, "LIST_ROOMS", data.second_org) is False assert (oso.is_allowed(data.member_user_org_1, "LIST_ROOMS", data.second_org) is False) assert oso.is_allowed(data.admin_user_org_1, "LIST_ROOMS", data.second_org) is False # Only admin user can edit the org assert oso.is_allowed(data.admin_user_org_1, "UPDATE", data.first_org) is True assert oso.is_allowed(data.member_user_org_1, "UPDATE", data.first_org) is False assert oso.is_allowed(data.lead_user_org_1, "UPDATE", data.first_org) is False # Only admin user can list org roles assert oso.is_allowed(data.admin_user_org_1, "LIST_ROLES", data.first_org) is True assert oso.is_allowed(data.member_user_org_1, "LIST_ROLES", data.first_org) is False assert oso.is_allowed(data.lead_user_org_1, "LIST_ROLES", data.first_org) is False # Only admin user can add interact with org roles new_role_insert = OrganizationRole( name="MEMBER", organization=data.first_org, user=data.guest_read_user_room_1) # type: ignore assert oso.is_allowed(data.admin_user_org_1, "CREATE", new_role_insert) is True assert oso.is_allowed(data.admin_user_org_1, "READ", new_role_insert) is True assert oso.is_allowed(data.admin_user_org_1, "UPDATE", new_role_insert) is True assert oso.is_allowed(data.admin_user_org_1, "DELETE", new_role_insert) is True assert oso.is_allowed(data.member_user_org_1, "CREATE", new_role_insert) is False assert oso.is_allowed(data.member_user_org_1, "READ", new_role_insert) is False assert oso.is_allowed(data.member_user_org_1, "UPDATE", new_role_insert) is False assert oso.is_allowed(data.member_user_org_1, "DELETE", new_role_insert) is False assert oso.is_allowed(data.lead_user_org_1, "CREATE", new_role_insert) is False assert oso.is_allowed(data.lead_user_org_1, "READ", new_role_insert) is False assert oso.is_allowed(data.lead_user_org_1, "UPDATE", new_role_insert) is False assert oso.is_allowed(data.lead_user_org_1, "DELETE", new_role_insert) is False # Only admins and leads can create teams not member new_team_resource = Team( "TestTeam", "This is a test", True, creator=data.admin_user_org_1, organization=data.first_org, ) assert oso.is_allowed(data.admin_user_org_1, "CREATE", new_team_resource) is True assert oso.is_allowed(data.lead_user_org_1, "CREATE", new_team_resource) is True assert oso.is_allowed(data.member_user_org_1, "CREATE", new_team_resource) is False # Only admins can delete teams not member and lead assert oso.is_allowed(data.admin_user_org_1, "DELETE", new_team_resource) is True assert oso.is_allowed(data.lead_user_org_1, "DELETE", new_team_resource) is False assert oso.is_allowed(data.member_user_org_1, "DELETE", new_team_resource) is False # Any role in the org can read the team assert oso.is_allowed(data.admin_user_org_1, "READ", new_team_resource) is True assert oso.is_allowed(data.lead_user_org_1, "READ", new_team_resource) is True assert oso.is_allowed(data.member_user_org_1, "READ", new_team_resource) is True # Anyone in the org can create and read datarooms new_dataroom_resource = Dataroom( name="MyRoom", description="New Room", creator=data.admin_user_org_1, organization=data.first_org, ) assert (oso.is_allowed(data.admin_user_org_1, "CREATE", new_dataroom_resource) is True) assert oso.is_allowed(data.lead_user_org_1, "CREATE", new_dataroom_resource) is True assert (oso.is_allowed(data.member_user_org_1, "CREATE", new_dataroom_resource) is True) assert oso.is_allowed(data.admin_user_org_1, "READ", new_dataroom_resource) is True assert oso.is_allowed(data.lead_user_org_1, "READ", new_dataroom_resource) is True assert oso.is_allowed(data.member_user_org_1, "READ", new_dataroom_resource) is True
from oso import Oso oso = Oso() oso.load_str("""allow("user", "can_use", "this_program");""") if oso.is_allowed("user", "can_use", "this_program"): print("Hello from oso") else: print("Access denied") if oso.is_allowed("user-123", "can_run", "this_program"): print("Hello again, but you probably can't run this line.") else: print("You weren't authorized by the rules!")
from oso import Oso from expense import EXPENSES def setup_oso(): oso = Oso() return oso oso = setup_oso() oso = Oso() actor = "*****@*****.**" resource = EXPENSES[1] oso.is_allowed(actor, "GET", resource)