File size: 1,758 Bytes
7cc81cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from __future__ import annotations

import unittest

from app.security.context import AuthContext
from app.security.errors import ForbiddenError
from app.security.service import APIKeyService


class SecurityRoleEnforcementTests(unittest.TestCase):
    def test_viewer_scope_is_enforced_by_authoritative_membership_role(self) -> None:
        context = AuthContext(
            api_key_id="key",
            key_name="Viewer Key",
            key_prefix="mp_test_viewer",
            environment="test",
            role="viewer",
            scopes=frozenset({"projects:read", "projects:write", "jobs:create"}),
            requests_per_minute=60,
            concurrent_jobs=1,
            uploads_per_hour=1,
            processing_bytes_per_day=1024,
        )

        APIKeyService.authorize(context, "projects:read")
        APIKeyService.authorize(context, "jobs:read")

        with self.assertRaises(ForbiddenError):
            APIKeyService.authorize(context, "projects:write")
        with self.assertRaises(ForbiddenError):
            APIKeyService.authorize(context, "jobs:create")

    def test_explicit_scopes_still_bypass_role_when_authorized(self) -> None:
        context = AuthContext(
            api_key_id="key",
            key_name="Developer Key",
            key_prefix="mp_test_dev",
            environment="test",
            role="developer",
            scopes=frozenset({"projects:write", "jobs:create"}),
            requests_per_minute=60,
            concurrent_jobs=1,
            uploads_per_hour=1,
            processing_bytes_per_day=1024,
        )

        APIKeyService.authorize(context, "projects:write")
        APIKeyService.authorize(context, "jobs:create")


if __name__ == "__main__":
    unittest.main()