Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3017753b88 | ||
|
|
6a4127ed24 | ||
|
|
f3ad539998 | ||
|
|
ed8dc01ed9 | ||
|
|
adbc6c6861 | ||
|
|
99e64bdcd3 | ||
|
|
7d64ca1cff | ||
|
|
69f169fa6a | ||
|
|
b3a53a7f58 | ||
|
|
6cd904d460 | ||
|
|
18732801b5 | ||
|
|
e0baca15a9 | ||
|
|
69a71aabbb | ||
|
|
bf315b85ca | ||
|
|
2c43a13774 | ||
|
|
164f5f9615 | ||
|
|
8e3a4d95da | ||
|
|
d9fe727c3f | ||
|
|
2dd062787d | ||
|
|
c7011040c3 | ||
|
|
7937de5d7d | ||
|
|
4ff934ad98 | ||
|
|
ef9fee1585 | ||
|
|
0cc6299d1c | ||
|
|
556b650c7a | ||
|
|
9eb8613c05 | ||
|
|
977783c126 | ||
|
|
ec5835ca77 |
No files matched your search
@@ -31,13 +31,13 @@ logger = get_logger(__name__)
|
|||||||
|
|
||||||
# Enterprise: Personal Access Tokens (PATs). PATs are an enterprise-only feature, so the
|
# Enterprise: Personal Access Tokens (PATs). PATs are an enterprise-only feature, so the
|
||||||
# resolver lives in the enterprise package. In the community edition that package is absent
|
# resolver lives in the enterprise package. In the community edition that package is absent
|
||||||
# and this falls back to a no-op, meaning "cmat_" bearer tokens simply fail normal JWT
|
# and this falls back to a no-op, meaning "rpat_" bearer tokens simply fail normal JWT
|
||||||
# verification like any other invalid token. See app/enterprise/services/pat.py.
|
# verification like any other invalid token. See app/enterprise/services/pat.py.
|
||||||
#
|
#
|
||||||
# The enterprise resolver is imported lazily (on first use) rather than at module load: the
|
# The enterprise resolver is imported lazily (on first use) rather than at module load: the
|
||||||
# enterprise package pulls in the API routers, which import this module, so an eager import
|
# enterprise package pulls in the API routers, which import this module, so an eager import
|
||||||
# here would create a circular import during application start-up.
|
# here would create a circular import during application start-up.
|
||||||
PAT_TOKEN_PREFIX = "cmat_"
|
PAT_TOKEN_PREFIX = "rpat_"
|
||||||
_pat_resolver = None
|
_pat_resolver = None
|
||||||
_pat_resolver_loaded = False
|
_pat_resolver_loaded = False
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ def test_validate_token_roundtrip_and_last_used(db, test_user):
|
|||||||
def test_validate_token_rejects_wrong_and_garbage(db, test_user):
|
def test_validate_token_rejects_wrong_and_garbage(db, test_user):
|
||||||
repo = PersonalAccessTokenRepository(db)
|
repo = PersonalAccessTokenRepository(db)
|
||||||
repo.create_token(user_id=test_user.id, organization_id=test_user.organization_id, name="cli")
|
repo.create_token(user_id=test_user.id, organization_id=test_user.organization_id, name="cli")
|
||||||
assert repo.validate_token("cmat_not-a-real-token") is None
|
assert repo.validate_token("rpat_not-a-real-token") is None
|
||||||
assert repo.validate_token("jwt-style-token") is None
|
assert repo.validate_token("jwt-style-token") is None
|
||||||
assert repo.validate_token("") is None
|
assert repo.validate_token("") is None
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ def test_resolve_pat_user_rejects_non_pat_token(db):
|
|||||||
assert resolve_pat_user("", db) is None
|
assert resolve_pat_user("", db) is None
|
||||||
|
|
||||||
|
|
||||||
# --- Integration: the open-source get_current_user hook resolves cmat_ tokens ---
|
# --- Integration: the open-source get_current_user hook resolves rpat_ tokens ---
|
||||||
|
|
||||||
import asyncio # noqa: E402
|
import asyncio # noqa: E402
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ def test_get_current_user_accepts_valid_pat(db, test_user):
|
|||||||
|
|
||||||
def test_get_current_user_rejects_bogus_pat(db, test_user):
|
def test_get_current_user_rejects_bogus_pat(db, test_user):
|
||||||
with pytest.raises(HTTPException) as exc:
|
with pytest.raises(HTTPException) as exc:
|
||||||
asyncio.run(get_current_user(_request_with_bearer("cmat_bogus"), None, db))
|
asyncio.run(get_current_user(_request_with_bearer("rpat_bogus"), None, db))
|
||||||
assert exc.value.status_code == 401
|
assert exc.value.status_code == 401
|
||||||
|
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ from app.enterprise.schemas.personal_access_token import PATCreate # noqa: E402
|
|||||||
|
|
||||||
|
|
||||||
def test_create_pat_rejected_when_request_uses_a_pat(db, test_user):
|
def test_create_pat_rejected_when_request_uses_a_pat(db, test_user):
|
||||||
req = _request_with_bearer("cmat_sometoken")
|
req = _request_with_bearer("rpat_sometoken")
|
||||||
with pytest.raises(HTTPException) as exc:
|
with pytest.raises(HTTPException) as exc:
|
||||||
# current_user/request are passed as kwargs, matching how FastAPI invokes the
|
# current_user/request are passed as kwargs, matching how FastAPI invokes the
|
||||||
# handler (the rate-limit decorator reads current_user from kwargs).
|
# handler (the rate-limit decorator reads current_user from kwargs).
|
||||||
@@ -180,8 +180,8 @@ def test_create_pat_rejected_when_request_uses_a_pat(db, test_user):
|
|||||||
|
|
||||||
|
|
||||||
def test_create_pat_allowed_with_interactive_session(db, test_user):
|
def test_create_pat_allowed_with_interactive_session(db, test_user):
|
||||||
# A JWT bearer (not cmat_) represents an interactive login and is allowed.
|
# A JWT bearer (not rpat_) represents an interactive login and is allowed.
|
||||||
req = _request_with_bearer("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.payload.sig")
|
req = _request_with_bearer("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.payload.sig")
|
||||||
resp = asyncio.run(create_personal_access_token(
|
resp = asyncio.run(create_personal_access_token(
|
||||||
PATCreate(name="ok"), request=req, db=db, current_user=test_user))
|
PATCreate(name="ok"), request=req, db=db, current_user=test_user))
|
||||||
assert resp.token.startswith("cmat_")
|
assert resp.token.startswith("rpat_")
|
||||||
Reference in new issue
Block a user