Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions core/show_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,11 +692,7 @@ def require_show_page_access_management(


def _instance_editor_or_owner(context: Any) -> bool:
"""The /show Workbench management capability is the Instance Editor role.

``show_page_email`` sessions are Viewer-only, so they can never satisfy an
Editor check. Instance Owner passes as the top of the role ladder.
"""
"""The /show Workbench management capability is the Instance Editor role."""

return bool(context is not None and context.has_role("editor"))

Expand Down Expand Up @@ -1014,8 +1010,7 @@ def require_access(self, session_id: str, *, user_context: Any = None) -> ShowPa
"""Return a Show Page only to an Instance Viewer (owner/editor/viewer).

``/show`` admission is the Instance role alone, independent of the
sharing list and of Resource ACL (§3.2): any Viewer enters the Workbench,
while a signed ``show_page_email`` session never does.
sharing list and of Resource ACL (§3.2): any Viewer enters the Workbench.
"""

session_id = validate_session_id(session_id)
Expand Down Expand Up @@ -1096,11 +1091,7 @@ def list_page(

@staticmethod
def _require_resource_access(user_context: Any) -> None:
if not (
user_context is not None
and user_context.has_role("viewer")
and user_context.instance_access_source != "show_page_email"
):
if not (user_context is not None and user_context.has_role("viewer")):
raise ShowPageError("Show Page access is not permitted.", code="resource_access_forbidden")

@staticmethod
Expand Down
3 changes: 0 additions & 3 deletions storage/resource_access_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,6 @@ def metadata_with_resource_user_context(
"vibe_instance_role": context.instance_role,
"vibe_instance_access_source": context.instance_access_source,
"vibe_instance_kind": context.instance_kind,
"vibe_show_page_id": context.show_page_id,
"claims_issued_at": context.claims_issued_at,
"vibe_instance_authorization_revision": context.authorization_revision,
"authorization_expires_at": _resource_context_expires_at(context),
Expand Down Expand Up @@ -1335,8 +1334,6 @@ def _policy_allows(
if resource_kind in {"skill", "vault_secret"}:
if context.is_remote and context.is_active_organization_member and context.has_role("editor"):
return True
if context.instance_access_source == "show_page_email":
return False
if not context.can_use_resource(resource_kind):
return False
if policy is None:
Expand Down
163 changes: 0 additions & 163 deletions tests/scenario_harness/show_page_email_access.py

This file was deleted.

7 changes: 0 additions & 7 deletions tests/scenarios/auth_setup/catalog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,6 @@ scenarios:
layer: scenario
backend: web
test: tests/scenarios/auth_setup/test_auth_setup_scenarios.py::test_remote_web_oauth_cold_launch_retry_is_single_owner
- id: AUTH-SETUP-401
name: Exact-email Show Page login stays a /p-only reader and never enters /show
status: covered
kind: authorization
layer: scenario
backend: show_page_email
test: tests/scenarios/auth_setup/test_auth_setup_scenarios.py::ShowPageEmailAccessScenarioTests::test_exact_email_login_is_confined_to_its_signed_show_page
- id: AUTH-SETUP-402
name: Personal remote activity slides past the original identity deadline without another authorization prompt
status: covered
Expand Down
64 changes: 19 additions & 45 deletions tests/scenarios/auth_setup/test_auth_setup_scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
from modules.agents.codex.agent import CodexAgent
from tests.scenario_harness.auth_setup import AuthSetupScenarioHarness, FakeProcess
from tests.scenario_harness.core import ScenarioExpect, ScenarioRunner, ScenarioStep
from tests.scenario_harness.show_page_email_access import ShowPageEmailAccessScenarioHarness
from tests.ui_server_test_helpers import _save_config, remote_session_cookie
from storage import remote_access_authorization_service
from tests.scenario_harness.model_hub_native_oauth import (
Expand Down Expand Up @@ -68,41 +67,6 @@ def test_auth_setup_catalog_priorities_reference_live_scenarios():
assert set(catalog.get("next_priority", [])) <= live_ids


class ShowPageEmailAccessScenarioTests(unittest.TestCase):
def setUp(self):
self.harness = ShowPageEmailAccessScenarioHarness()
self.addCleanup(self.harness.close)

def test_exact_email_login_is_confined_to_its_signed_show_page(self):
"""Scenario: AUTH-SETUP-401"""
handshake = self.harness.begin_login("session-one")
self.assertEqual(handshake["show_page_id"], "session-one")

callback = self.harness.complete_login(handshake)
self.assertEqual(callback.status_code, 302)
self.assertEqual(callback.headers["Location"], handshake["next_path"])

exact = self.harness.get(handshake["next_path"])
other = self.harness.get("/show/session-two/__show/me")
api = self.harness.get("/api/show-pages")
# §3.2: a show_page_email grant is a /p-only read visitor — it never
# enters the /show surface, even for its own signed page.
self.assertEqual(exact.status_code, 403)
self.assertEqual(other.status_code, 403)
self.assertEqual(other.get_json()["error"], "show_page_access_forbidden")
self.assertEqual(api.status_code, 403)

self.harness.seed_broader_session()
# §3.2: a real Instance Editor session (email-sourced, not a show_page
# grant) enters /show directly, with no login handshake and independent
# of any show_page entitlement.
self.assertEqual(
self.harness.get("/show/session-one/__show/me").status_code,
200,
)
self.assertTrue(self.harness.get("/show/session-one/__show/me").get_json()["authenticated"])


def test_limited_show_identity_closed_loop_installs_guest_lease(monkeypatch, tmp_path):
"""Scenario: AUTH-SETUP-404"""
monkeypatch.setenv("AVIBE_HOME", str(tmp_path))
Expand All @@ -112,6 +76,11 @@ def test_limited_show_identity_closed_loop_installs_guest_lease(monkeypatch, tmp
cloud.issuer = "https://backend.test"
cloud.jwks_uri = "https://backend.test/oauth/jwks.json"
config.save()
monkeypatch.setattr(
ShowPageStore,
"_resolve_instance_ownership",
staticmethod(lambda: {"mode": "organization", "organization_id": "组织-甲"}),
)

store = ShowPageStore()
try:
Expand All @@ -123,7 +92,13 @@ def test_limited_show_identity_closed_loop_installs_guest_lease(monkeypatch, tmp
expected_revision=access.revision,
target_access_mode="limited",
target_share_id=page.share_id,
target_emails=["viewer@example.com"],
target_entries=[
{
"kind": "group",
"value": "研发组",
"organization_id": "组织-甲",
}
],
)
assert applied.status == "applied"
finally:
Expand Down Expand Up @@ -153,13 +128,17 @@ def test_limited_show_identity_closed_loop_installs_guest_lease(monkeypatch, tmp
{
"iss": cloud.issuer,
"aud": f"avibe-show-identity:{cloud.client_id}",
"sub": "viewer-1",
"sub": "访客-甲",
"iat": issued_at,
"exp": issued_at + 300,
"jti": f"scenario-{time.time_ns()}",
"nonce": nonce,
"instance_id": cloud.instance_id,
"verified_email": "viewer@example.com",
"organization_id": "组织-甲",
"organization_member_id": "成员-甲",
"organization_role": "member",
"group_ids": ["研发组"],
},
private_key,
algorithm="RS256",
Expand Down Expand Up @@ -227,13 +206,8 @@ def get_signing_key_from_jwt(self, token):
remote_session_cookie(
config,
"viewer@example.com",
"viewer-1",
session_claims={
"vibe_instance_id": cloud.instance_id,
"vibe_instance_role": "viewer",
"vibe_instance_access_source": "show_page_email",
"vibe_show_page_id": page.session_id,
},
"访客-甲",
role="viewer",
),
domain="alex.avibe.bot",
)
Expand Down
17 changes: 0 additions & 17 deletions tests/test_instance_authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,23 +200,6 @@ def test_context_from_session_payload_only_recognizes_known_instance_kinds() ->
assert not unknown.is_personal_instance


def test_show_page_email_context_is_exactly_page_scoped() -> None:
context = context_from_session_payload(
{
"sub": "guest-1",
"vibe_instance_role": "viewer",
"vibe_instance_access_source": "show_page_email",
"vibe_show_page_id": "session-one",
}
)
assert not context.can_read_instance
assert context.capability_projection()["can_read_instance"] is False
assert context.capability_projection()["can_use_show_pages"] is False
assert context.can_use_show_page("session-one")
assert not context.can_use_show_page("session-two")
assert not context.can_chat


def test_http_policy_is_role_only_and_unknown_api_routes_fail_closed() -> None:
editor_routes = (
("GET", "/api/agents"),
Expand Down
Loading