Skip to content
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

Open
wants to merge 23 commits into
base: v2
Choose a base branch
from

Conversation

asafc
Copy link
Contributor

@asafc asafc commented Jul 28, 2024

No description provided.

@asafc asafc force-pushed the asaf/cto-314-data-filtering-poc branch from dc95497 to 91a0520 Compare July 28, 2024 13:25
@asafc asafc marked this pull request as ready for review August 12, 2024 13:12
@asafc asafc changed the title data filtering poc (DRAFT - IN PROGRESS!) First data filtering api route (supports RBAC policy) Aug 12, 2024
@asafc asafc force-pushed the asaf/cto-314-data-filtering-poc branch from 05c4e93 to 1b4bcc8 Compare August 12, 2024 13:15
@@ -0,0 +1,11 @@
.PHONY: help
Copy link
Contributor

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

Comment on lines +1 to +9
# 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
```
Copy link
Contributor

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

Comment on lines +65 to +88
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
}
"""
Copy link
Contributor

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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this ?

Comment on lines +740 to +744
return Response(
content=json.dumps(residual_policy.dict()),
status_code=status.HTTP_200_OK,
media_type="application/json",
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the response is schemaless ?

Comment on lines +65 to +75
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()
Copy link
Contributor

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 ?

Comment on lines +30 to +35
"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,
Copy link
Contributor

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 )

Comment on lines +57 to +61
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)
Copy link
Contributor

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 ?

Comment on lines +72 to +75
if len(join_conditions) == 0:
raise TypeError(
f"You must call QueryBuilder.join(table, condition) to map residual references to other SQL tables"
)
Copy link
Contributor

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
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants