Add external calendar profile contract
This commit is contained in:
@@ -208,7 +208,8 @@ Other stable runtime capabilities currently include:
|
||||
- `identity.directory` and `identity.search`
|
||||
- `organizations.directory`
|
||||
- `idm.directory`
|
||||
- `calendar.outbox` and `calendar.scheduling`
|
||||
- `calendar.outbox`, `calendar.scheduling`, `calendar.invitations`, and
|
||||
`calendar.externalProfiles`
|
||||
- `poll.scheduling`
|
||||
- `notifications.dispatch`
|
||||
- `workflow.definitionContributions` and `workflow.runtimeWorker`
|
||||
@@ -286,7 +287,8 @@ Current named interfaces, generated from the source manifests by the workspace
|
||||
contract checks, are:
|
||||
|
||||
- `addresses.contact_writer`, `addresses.lookup`, `addresses.recipient_source`
|
||||
- `calendar.outbox`, `calendar.scheduling`
|
||||
- `calendar.external_profiles`, `calendar.invitations`, `calendar.outbox`,
|
||||
`calendar.scheduling`
|
||||
- `campaigns.access`, `campaigns.delivery_tasks`,
|
||||
`campaigns.mail_policy_context`, `campaigns.policy_context`,
|
||||
`campaigns.retention`
|
||||
|
||||
@@ -9,6 +9,7 @@ from typing import Protocol, runtime_checkable
|
||||
CAPABILITY_CALENDAR_SCHEDULING = "calendar.scheduling"
|
||||
CAPABILITY_CALENDAR_OUTBOX = "calendar.outbox"
|
||||
CAPABILITY_CALENDAR_INVITATIONS = "calendar.invitations"
|
||||
CAPABILITY_CALENDAR_EXTERNAL_PROFILES = "calendar.externalProfiles"
|
||||
CALENDAR_AVAILABILITY_READ_SCOPE = "calendar:availability:read"
|
||||
CALENDAR_EVENT_WRITE_SCOPE = "calendar:event:write"
|
||||
|
||||
@@ -90,6 +91,38 @@ class CalendarInvitationRef:
|
||||
degraded_reasons: tuple[str, ...] = ()
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class CalendarExternalProfileRequest:
|
||||
"""Connector-neutral request for a Calendar-owned external profile."""
|
||||
|
||||
profile_kind: str
|
||||
calendar_id: str
|
||||
endpoint_url: str
|
||||
display_name: str | None = None
|
||||
auth_type: str = "none"
|
||||
username: str | None = None
|
||||
credential_ref: str | None = None
|
||||
sync_enabled: bool = True
|
||||
sync_interval_seconds: int = 900
|
||||
sync_direction: str = "two_way"
|
||||
conflict_policy: str = "etag"
|
||||
connector_profile_ref: str | None = None
|
||||
identity_mapping_ref: str | None = None
|
||||
resource_calendar_ref: str | None = None
|
||||
metadata: Mapping[str, object] = field(default_factory=dict)
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class CalendarExternalProfileRef:
|
||||
source_id: str
|
||||
calendar_id: str
|
||||
profile_kind: str
|
||||
transport_kind: str
|
||||
connector_profile_ref: str | None = None
|
||||
identity_mapping_ref: str | None = None
|
||||
resource_calendar_ref: str | None = None
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class CalendarSchedulingProvider(Protocol):
|
||||
def list_freebusy(
|
||||
@@ -165,6 +198,25 @@ class CalendarInvitationProvider(Protocol):
|
||||
) -> CalendarInvitationRef:
|
||||
...
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class CalendarExternalProfileProvider(Protocol):
|
||||
"""Optional connector route for Calendar-owned groupware adapters."""
|
||||
|
||||
def supported_profiles(self) -> Sequence[Mapping[str, object]]:
|
||||
...
|
||||
|
||||
def configure_profile(
|
||||
self,
|
||||
session: object,
|
||||
*,
|
||||
tenant_id: str,
|
||||
user_id: str | None,
|
||||
request: CalendarExternalProfileRequest,
|
||||
) -> CalendarExternalProfileRef:
|
||||
...
|
||||
|
||||
|
||||
def calendar_scheduling_provider(registry: object | None) -> CalendarSchedulingProvider | None:
|
||||
if registry is None or not hasattr(registry, "has_capability"):
|
||||
return None
|
||||
@@ -192,3 +244,18 @@ def calendar_invitation_provider(
|
||||
return None
|
||||
capability = registry.capability(CAPABILITY_CALENDAR_INVITATIONS)
|
||||
return capability if isinstance(capability, CalendarInvitationProvider) else None
|
||||
|
||||
|
||||
def calendar_external_profile_provider(
|
||||
registry: object | None,
|
||||
) -> CalendarExternalProfileProvider | None:
|
||||
if registry is None or not hasattr(registry, "has_capability"):
|
||||
return None
|
||||
if not registry.has_capability(CAPABILITY_CALENDAR_EXTERNAL_PROFILES):
|
||||
return None
|
||||
capability = registry.capability(CAPABILITY_CALENDAR_EXTERNAL_PROFILES)
|
||||
return (
|
||||
capability
|
||||
if isinstance(capability, CalendarExternalProfileProvider)
|
||||
else None
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user