Skip to content

Commit

Permalink
Merge pull request #203 from permitio/omer/per-10805-get-user-permiss…
Browse files Browse the repository at this point in the history
…ions

User Permissions external data store
  • Loading branch information
omer9564 authored Nov 5, 2024
2 parents cf37796 + 0c6a279 commit b64833e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 17 deletions.
29 changes: 15 additions & 14 deletions horizon/enforcer/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,23 +475,24 @@ async def user_permissions(
query: UserPermissionsQuery,
x_permit_sdk_language: Optional[str] = Depends(notify_seen_sdk),
):
response = await _is_allowed(query, request, USER_PERMISSIONS_POLICY_PACKAGE)
log_query_result(query, response)
try:
raw_result = json.loads(response.body).get("result", {})
processed_query = (
get_v1_processed_query(raw_result)
or get_v2_processed_query(raw_result)
or {}
)
def parse_func(result: dict) -> dict | list:
return result.get("permissions", {})

result = parse_obj_as(
UserPermissionsResult, raw_result.get("permissions", {})
)
except:
response = await conditional_is_allowed(
query,
request,
policy_package=USER_PERMISSIONS_POLICY_PACKAGE,
external_data_manager_path=f"/user-permissions",
external_data_manager_params=query.get_filters(),
legacy_parse_func=parse_func,
)
try:
result = parse_obj_as(UserPermissionsResult, response)
except Exception as e:
result = parse_obj_as(UserPermissionsResult, {})
logger.warning(
"is allowed (fallback response)", reason="cannot decode opa response"
"user permissions (fallback response)",
reason="cannot decode opa response",
)
return result

Expand Down
10 changes: 10 additions & 0 deletions horizon/enforcer/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ class UserPermissionsQuery(BaseSchema):
resource_types: Optional[list[str]] = None
context: Optional[dict[str, Any]] = {}

def get_filters(self) -> dict:
filters = {}
if self.tenants:
filters["tenants"] = self.tenants
if self.resources:
filters["resource_instances"] = self.resources
if self.resource_types:
filters["resource_types"] = self.resource_types
return filters


class AuthorizationResult(BaseSchema):
allow: bool = False
Expand Down
43 changes: 40 additions & 3 deletions horizon/tests/test_enforcer_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,38 @@ async def pdp_api_client() -> TestClient:
[{"key": "default-2", "attributes": {}}, {"key": "default", "attributes": {}}],
[{"key": "default-2", "attributes": {}}, {"key": "default", "attributes": {}}],
),
(
"/user-permissions",
"/user-permissions",
UserPermissionsQuery(
user=User(key="user1"),
),
None,
{
"user1": {
"resource": {
"key": "resource_x",
"attributes": {},
"type": "resource1",
},
"tenant": {"key": "default", "attributes": {}},
"permissions": ["read:read"],
"roles": ["admin"],
}
},
{
"user1": {
"resource": {
"key": "resource_x",
"attributes": {},
"type": "resource1",
},
"tenant": {"key": "default", "attributes": {}},
"permissions": ["read:read"],
"roles": ["admin"],
}
},
),
]


Expand Down Expand Up @@ -513,9 +545,14 @@ def post_endpoint():
assert response.json() == expected_response
elif isinstance(expected_response, dict):
for k, v in expected_response.items():
assert (
response.json()[k] == v
), f"Expected {k} to be {v} but got {response.json()[k]}"
try:
assert (
response.json()[k] == v
), f"Expected {k} to be {v} but got {response.json()[k]}"
except KeyError:
pytest.fail(
f"response missing key {k} from expected response:\n,{response.json()}"
)
else:
raise TypeError(
f"Unexpected expected response type, expected one of list, dict and got {type(expected_response)}"
Expand Down

0 comments on commit b64833e

Please sign in to comment.