mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-01 04:44:52 +03:00
add admin precedence to proxy role_map resolution to prevent downgrade
This commit is contained in:
parent
fe3677c7df
commit
82cb69526b
@ -166,6 +166,12 @@ In this example:
|
|||||||
- If no mapping matches, Frigate falls back to `default_role` if configured.
|
- If no mapping matches, Frigate falls back to `default_role` if configured.
|
||||||
- If `role_map` is not defined, Frigate assumes the role header directly contains `admin`, `viewer`, or a custom role name.
|
- If `role_map` is not defined, Frigate assumes the role header directly contains `admin`, `viewer`, or a custom role name.
|
||||||
|
|
||||||
|
**Note on matching semantics:**
|
||||||
|
|
||||||
|
- Admin precedence: if the `admin` mapping matches , Frigate resolves the session to `admin` to avoid accidental downgrade
|
||||||
|
when a user belongs to multiple groups (for example both admin and viewer
|
||||||
|
groups).
|
||||||
|
|
||||||
#### Port Considerations
|
#### Port Considerations
|
||||||
|
|
||||||
**Authenticated Port (8971)**
|
**Authenticated Port (8971)**
|
||||||
|
|||||||
@ -439,10 +439,11 @@ def resolve_role(
|
|||||||
Determine the effective role for a request based on proxy headers and configuration.
|
Determine the effective role for a request based on proxy headers and configuration.
|
||||||
|
|
||||||
Order of resolution:
|
Order of resolution:
|
||||||
1. If a role header is defined in proxy_config.header_map.role:
|
1. If a role header is defined in proxy_config.header_map.role:
|
||||||
- If a role_map is configured, treat the header as group claims
|
- If a role_map is configured, treat the header as group claims
|
||||||
(split by proxy_config.separator) and map to roles.
|
(split by proxy_config.separator) and map to roles.
|
||||||
- If no role_map is configured, treat the header as role names directly.
|
Admin matches short-circuit to admin.
|
||||||
|
- If no role_map is configured, treat the header as role names directly.
|
||||||
2. If no valid role is found, return proxy_config.default_role if it's valid in config_roles, else 'viewer'.
|
2. If no valid role is found, return proxy_config.default_role if it's valid in config_roles, else 'viewer'.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -492,6 +493,12 @@ def resolve_role(
|
|||||||
}
|
}
|
||||||
logger.debug("Matched roles from role_map: %s", matched_roles)
|
logger.debug("Matched roles from role_map: %s", matched_roles)
|
||||||
|
|
||||||
|
# If admin matches, prioritize it to avoid accidental downgrade when
|
||||||
|
# users belong to both admin and lower-privilege groups.
|
||||||
|
if "admin" in matched_roles and "admin" in config_roles:
|
||||||
|
logger.debug("Resolved role (with role_map) to 'admin'.")
|
||||||
|
return "admin"
|
||||||
|
|
||||||
if matched_roles:
|
if matched_roles:
|
||||||
resolved = next(
|
resolved = next(
|
||||||
(r for r in config_roles if r in matched_roles), validated_default
|
(r for r in config_roles if r in matched_roles), validated_default
|
||||||
|
|||||||
@ -31,6 +31,21 @@ class TestProxyRoleResolution(unittest.TestCase):
|
|||||||
role = resolve_role(headers, self.proxy_config, self.config_roles)
|
role = resolve_role(headers, self.proxy_config, self.config_roles)
|
||||||
self.assertEqual(role, "admin")
|
self.assertEqual(role, "admin")
|
||||||
|
|
||||||
|
def test_role_map_or_matching(self):
|
||||||
|
config = self.proxy_config
|
||||||
|
config.header_map.role_map = {
|
||||||
|
"admin": ["group_admin", "group_privileged"],
|
||||||
|
}
|
||||||
|
|
||||||
|
# OR semantics: a single matching group should map to the role
|
||||||
|
headers = {"x-remote-role": "group_admin"}
|
||||||
|
role = resolve_role(headers, config, self.config_roles)
|
||||||
|
self.assertEqual(role, "admin")
|
||||||
|
|
||||||
|
headers = {"x-remote-role": "group_admin|group_privileged"}
|
||||||
|
role = resolve_role(headers, config, self.config_roles)
|
||||||
|
self.assertEqual(role, "admin")
|
||||||
|
|
||||||
def test_direct_role_header_with_separator(self):
|
def test_direct_role_header_with_separator(self):
|
||||||
config = self.proxy_config
|
config = self.proxy_config
|
||||||
config.header_map.role_map = None # disable role_map
|
config.header_map.role_map = None # disable role_map
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user