-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First data filtering api route (supports RBAC policy) #162
base: v2
Are you sure you want to change the base?
Conversation
dc95497
to
91a0520
Compare
…back to boolean expression
…e response encoding to the api wrapper
05c4e93
to
1b4bcc8
Compare
@@ -0,0 +1,11 @@ | |||
.PHONY: help |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in favor of using poetry instead of all of that, this is really hard to manage and poetry basically abstracts everything
# Permit.io Data Filtering SDK (EAP) | ||
|
||
Initial SDK to enable data filtering scenarios based on compiling OPA policies from Rego AST into SQL-like expressions. | ||
|
||
## Installation | ||
|
||
```py | ||
pip install permit-datafilter | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a detailed readme & reference our docs
TEMP_PARTIAL_EVAL_POLICY = """ | ||
package permit.partial_eval | ||
|
||
import future.keywords.contains | ||
import future.keywords.if | ||
import future.keywords.in | ||
|
||
default allow := false | ||
|
||
allow if { | ||
checked_permission := sprintf("%s:%s", [input.resource.type, input.action]) | ||
|
||
some granting_role, role_data in data.roles | ||
some resource_type, actions in role_data.grants | ||
granted_action := actions[_] | ||
granted_permission := sprintf("%s:%s", [resource_type, granted_action]) | ||
|
||
some tenant, roles in data.users[input.user.key].roleAssignments | ||
role := roles[_] | ||
role == granting_role | ||
checked_permission == granted_permission | ||
input.resource.tenant == tenant | ||
} | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this here also ?
@@ -125,7 +125,7 @@ def _get_pdp_version(cls) -> Optional[str]: | |||
if os.path.exists(PDP_VERSION_FILENAME): | |||
with open(PDP_VERSION_FILENAME) as f: | |||
return f.read().strip() | |||
return None | |||
return "0.0.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this ?
return Response( | ||
content=json.dumps(residual_policy.dict()), | ||
status_code=status.HTTP_200_OK, | ||
media_type="application/json", | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the response is schemaless ?
CompileResponse.update_forward_refs() | ||
CompileResponseComponents.update_forward_refs() | ||
CRQuerySet.update_forward_refs() | ||
CRQuery.update_forward_refs() | ||
CRExpression.update_forward_refs() | ||
CRTerm.update_forward_refs() | ||
CRSupportBlock.update_forward_refs() | ||
CRSupportModule.update_forward_refs() | ||
CRSupportModulePackage.update_forward_refs() | ||
CRRegoRule.update_forward_refs() | ||
CRRuleHead.update_forward_refs() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is that used for ?
"eq": lambda c, v: c == v, | ||
"ne": lambda c, v: c != v, | ||
"lt": lambda c, v: c < v, | ||
"gt": lambda c, v: c > v, | ||
"le": lambda c, v: c <= v, | ||
"ge": lambda c, v: c >= v, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are already builtin functions for that ( check out import operator
)
def column_table_name(c: Column) -> str: | ||
return cast(sa.Table, c.table).name | ||
|
||
def is_main_table_column(c: Column) -> bool: | ||
return column_table_name(c) == _get_table_name(table) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are those functions declared inside the function ?
if len(join_conditions) == 0: | ||
raise TypeError( | ||
f"You must call QueryBuilder.join(table, condition) to map residual references to other SQL tables" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this won't work with SQLAlchemy auto join techniques and "load options"
@@ -14,3 +14,4 @@ httpx>=0.27.0,<1 | |||
protobuf>=3.20.2 # not directly required, pinned by Snyk to avoid a vulnerability | |||
opal-common==0.7.6 | |||
opal-client==0.7.6 | |||
permit-datafilter>=0.0.3,<1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make this "optional" dependency, otherwise you require everyone that uses our SDK to have SQLAlchemy and many other unnecessary packages
No description provided.