Skip to content

Commit 67e5a32

Browse files
committed
add allowed ngnix support
1 parent 51d2416 commit 67e5a32

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

horizon/enforcer/api.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
UserTenantsResult,
3636
AuthorizedUsersResult,
3737
AuthorizedUsersAuthorizationQuery,
38+
User,
3839
)
3940
from horizon.enforcer.schemas_kong import (
4041
KongAuthorizationInput,
@@ -43,6 +44,7 @@
4344
KongWrappedAuthorizationQuery,
4445
)
4546
from horizon.enforcer.schemas_v1 import AuthorizationQueryV1
47+
from horizon.enforcer.utils.headers_utils import get_case_insensitive
4648
from horizon.enforcer.utils.mapping_rules_utils import MappingRulesUtils
4749
from horizon.enforcer.utils.statistics_utils import StatisticsManager
4850
from horizon.state import PersistentStateHandler
@@ -553,6 +555,106 @@ async def is_allowed(
553555
)
554556
return result
555557

558+
@router.post(
559+
"/allowed",
560+
response_model=AuthorizationResult,
561+
status_code=status.HTTP_200_OK,
562+
response_model_exclude_none=True,
563+
dependencies=[Depends(enforce_pdp_token)],
564+
)
565+
async def is_allowed(
566+
request: Request,
567+
query: Union[AuthorizationQuery, AuthorizationQueryV1],
568+
x_permit_sdk_language: Optional[str] = Depends(notify_seen_sdk),
569+
):
570+
if isinstance(query, AuthorizationQueryV1):
571+
raise HTTPException(
572+
status_code=status.HTTP_421_MISDIRECTED_REQUEST,
573+
detail="Mismatch between client version and PDP version,"
574+
" required v2 request body, got v1. "
575+
"hint: try to update your client version to v2",
576+
)
577+
query = cast(AuthorizationQuery, query)
578+
579+
response = await _is_allowed(query, request, MAIN_POLICY_PACKAGE)
580+
log_query_result(query, response)
581+
try:
582+
raw_result = json.loads(response.body).get("result", {})
583+
processed_query = (
584+
get_v1_processed_query(raw_result)
585+
or get_v2_processed_query(raw_result)
586+
or {}
587+
)
588+
result = {
589+
"allow": raw_result.get("allow", False),
590+
"result": raw_result.get(
591+
"allow", False
592+
), # fallback for older sdks (TODO: remove)
593+
"query": processed_query,
594+
"debug": raw_result.get("debug", {}),
595+
}
596+
except:
597+
result = dict(allow=False, result=False)
598+
logger.warning(
599+
"is allowed (fallback response)", reason="cannot decode opa response"
600+
)
601+
return result
602+
603+
@router.post(
604+
"/nginx_allowed",
605+
response_model=AuthorizationResult,
606+
status_code=status.HTTP_200_OK,
607+
response_model_exclude_none=True,
608+
dependencies=[Depends(enforce_pdp_token)],
609+
)
610+
async def is_allowed_nginx(
611+
request: Request,
612+
):
613+
user_key = get_case_insensitive(request.headers, "permit-user-key")
614+
tenant_id = get_case_insensitive(request.headers, "permit-tenant-id")
615+
action = get_case_insensitive(request.headers, "permit-action")
616+
resource_type = get_case_insensitive(request.headers, "permit-resource-type")
617+
618+
if (
619+
user_key is None
620+
or tenant_id is None
621+
or action is None
622+
or resource_type is None
623+
):
624+
raise HTTPException(
625+
status_code=status.HTTP_400_BAD_REQUEST,
626+
detail="Missing required headers: 'Permit-User-Key', 'Permit-Tenant-Id', 'Permit-Action', 'Permit-Resource-Type'",
627+
)
628+
query = AuthorizationQuery(
629+
user=User(key=user_key),
630+
action=action,
631+
resource=Resource(type=resource_type, tenant=tenant_id),
632+
)
633+
634+
response = await _is_allowed(query, request, MAIN_POLICY_PACKAGE)
635+
log_query_result(query, response)
636+
try:
637+
raw_result = json.loads(response.body).get("result", {})
638+
processed_query = (
639+
get_v1_processed_query(raw_result)
640+
or get_v2_processed_query(raw_result)
641+
or {}
642+
)
643+
result = {
644+
"allow": raw_result.get("allow", False),
645+
"result": raw_result.get(
646+
"allow", False
647+
), # fallback for older sdks (TODO: remove)
648+
"query": processed_query,
649+
"debug": raw_result.get("debug", {}),
650+
}
651+
except:
652+
result = dict(allow=False, result=False)
653+
logger.warning(
654+
"is allowed (fallback response)", reason="cannot decode opa response"
655+
)
656+
return result
657+
556658
@router.post(
557659
"/kong",
558660
response_model=KongAuthorizationResult,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def get_case_insensitive(dictionary, key) -> str | None:
2+
if isinstance(key, str):
3+
return next(
4+
(dictionary[k] for k in dictionary if k.lower() == key.lower()), None
5+
)
6+
return dictionary.get(key, None)

0 commit comments

Comments
 (0)