feat: Support system scope for policy list and check
1. support system scope for policy list and check 2. add target for check policy api 3. update version of requirements and test-requirements Change-Id: If251d26bdb522b03a8fb94ae0034d8ca44be5b61
This commit is contained in:
parent
4d6f784384
commit
08c6265d1e
@ -2207,6 +2207,14 @@
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Policies rules list"
|
||||
},
|
||||
"target": {
|
||||
"title": "Target",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Policies targets"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -23,10 +23,10 @@ click>=7.1.2,<=8.1.3 # BSD License (3 clause)
|
||||
jinja2>=2.11.3,<=3.1.2 # BSD License (3 clause)
|
||||
h11<0.13,>=0.11 # MIT
|
||||
MarkupSafe>=2.0.1,<=2.1.1 # BSD License (3 clause)
|
||||
python-keystoneclient>=3.21.0,<=4.5.0 # Apache-2.0
|
||||
python-cinderclient>=5.0.2,<=8.3.0 # Apache-2.0
|
||||
python-keystoneclient>=3.21.0 # Apache-2.0
|
||||
python-cinderclient>=5.0.2 # Apache-2.0
|
||||
python-glanceclient>=2.17.1 # Apache-2.0
|
||||
python-neutronclient>=6.14.1,<=7.8.0 # Apache-2.0
|
||||
python-novaclient>=15.1.1,<=18.0.0 # Apache-2.0
|
||||
keystoneauth1>=3.17.4,<=4.6.0 # Apache-2.0
|
||||
python-neutronclient>=6.14.1 # Apache-2.0
|
||||
python-novaclient>=15.1.1 # Apache-2.0
|
||||
keystoneauth1>=3.17.4 # Apache-2.0
|
||||
oslo.policy>=2.3.4 # Apache-2.0
|
||||
|
@ -17,10 +17,12 @@ from __future__ import annotations
|
||||
from typing import Dict
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from keystoneauth1.exceptions.http import Unauthorized as KeystoneUnauthorized
|
||||
|
||||
from skyline_apiserver import schemas
|
||||
from skyline_apiserver.api import deps
|
||||
from skyline_apiserver.client.utils import generate_session, get_access
|
||||
from skyline_apiserver.client.utils import generate_session, get_access, get_system_scope_access
|
||||
from skyline_apiserver.log import LOG
|
||||
from skyline_apiserver.policy import ENFORCER, UserContext
|
||||
|
||||
router = APIRouter()
|
||||
@ -75,10 +77,24 @@ def _generate_target(profile: schemas.Profile) -> Dict[str, str]:
|
||||
)
|
||||
async def list_policies(
|
||||
profile: schemas.Profile = Depends(deps.get_profile_update_jwt),
|
||||
):
|
||||
) -> schemas.Policies:
|
||||
session = await generate_session(profile)
|
||||
access = await get_access(session)
|
||||
user_context = UserContext(access)
|
||||
try:
|
||||
system_scope_access = await get_system_scope_access(
|
||||
profile.keystone_token, profile.region
|
||||
)
|
||||
user_context["system_scope"] = (
|
||||
"all"
|
||||
if getattr(system_scope_access, "system")
|
||||
and getattr(system_scope_access, "system", {}).get("all", False)
|
||||
else user_context["system_scope"]
|
||||
)
|
||||
except KeystoneUnauthorized:
|
||||
# User is not authorized to access the system scope. So just ignore the
|
||||
# exception and use the user_context as is.
|
||||
LOG.debug("Keystone token is invalid. No privilege to access system scope.")
|
||||
target = _generate_target(profile)
|
||||
result = [
|
||||
{"rule": rule, "allowed": ENFORCER.authorize(rule, target, user_context)}
|
||||
@ -103,11 +119,26 @@ async def list_policies(
|
||||
async def check_policies(
|
||||
policy_rules: schemas.PoliciesRules,
|
||||
profile: schemas.Profile = Depends(deps.get_profile_update_jwt),
|
||||
):
|
||||
) -> schemas.Policies:
|
||||
session = await generate_session(profile)
|
||||
access = await get_access(session)
|
||||
user_context = UserContext(access)
|
||||
try:
|
||||
system_scope_access = await get_system_scope_access(
|
||||
profile.keystone_token, profile.region
|
||||
)
|
||||
user_context["system_scope"] = (
|
||||
"all"
|
||||
if getattr(system_scope_access, "system")
|
||||
and getattr(system_scope_access, "system", {}).get("all", False)
|
||||
else user_context["system_scope"]
|
||||
)
|
||||
except KeystoneUnauthorized:
|
||||
# User is not authorized to access the system scope. So just ignore the
|
||||
# exception and use the user_context as is.
|
||||
LOG.debug("Keystone token is invalid. No privilege to access system scope.")
|
||||
target = _generate_target(profile)
|
||||
target.update(policy_rules.target if policy_rules.target else {})
|
||||
try:
|
||||
result = [
|
||||
{"rule": rule, "allowed": ENFORCER.authorize(rule, target, user_context)}
|
||||
|
@ -69,6 +69,13 @@ def get_system_session() -> Session:
|
||||
return SESSION
|
||||
|
||||
|
||||
async def get_system_scope_access(keystone_token: str, region: str) -> AccessInfoV3:
|
||||
auth_url = await get_endpoint(region, "keystone", get_system_session())
|
||||
scope_auth = Token(auth_url, keystone_token, system_scope="all")
|
||||
session = Session(auth=scope_auth, verify=False, timeout=constants.DEFAULT_TIMEOUT)
|
||||
return await run_in_threadpool(session.auth.get_auth_ref, session)
|
||||
|
||||
|
||||
async def get_access(session: Session) -> AccessInfoV3:
|
||||
auth = session.auth
|
||||
if auth._needs_reauthenticate():
|
||||
|
@ -45,7 +45,12 @@ class UserContext(MutableMapping):
|
||||
self._data.setdefault("domain_name", getattr(access, "domain_name", None))
|
||||
self._data.setdefault("user_domain_name", getattr(access, "user_domain_name", None))
|
||||
self._data.setdefault("project_domain_name", getattr(access, "project_domain_name", None))
|
||||
self._data.setdefault("system_scope", getattr(access, "system_scope", None))
|
||||
self._data.setdefault(
|
||||
"system_scope",
|
||||
"all"
|
||||
if getattr(access, "system") and getattr(access, "system", {}).get("all", False)
|
||||
else "",
|
||||
)
|
||||
self._data.setdefault("role_ids", getattr(access, "role_ids", []))
|
||||
self._data.setdefault("roles", getattr(access, "role_names", []))
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
@ -30,3 +30,4 @@ class Policies(BaseModel):
|
||||
|
||||
class PoliciesRules(BaseModel):
|
||||
rules: List[str] = Field(..., description="Policies rules list")
|
||||
target: Optional[Dict[str, str]] = Field(None, description="Policies targets")
|
||||
|
@ -18,4 +18,4 @@ mimesis<=4.1.3 # MIT
|
||||
asgi-lifespan<=1.0.1 # MIT
|
||||
types-PyYAML<=5.4.10 # Apache-2.0
|
||||
oslo.log<=5.0.0 # Apache-2.0
|
||||
neutron-lib>=2.15.0,<=2.21.0 # Apache-2.0
|
||||
neutron-lib>=2.15.0 # Apache-2.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user