feat(connectors): a connection operation can target one named account

Target carries the account alias and shows it in its snapshot. An open
operation is reused only for the same connector AND alias, so connecting
gmail 'work' never joins an open operation for the default gmail account.
This commit is contained in:
Siddharth Balyan
2026-10-08 17:35:26 +05:30
committed by Siddharth Balyan
parent ec8a971c08
commit 6301bf4bc3
3 changed files with 17 additions and 6 deletions

View File

@@ -23,8 +23,9 @@ class AccountOperationStart:
failed: bool = False
def _matching_open_operation(names: list[str], *, profile_home: str | None) -> ConnectionOperation | None:
matches = [live.find_target(name, profile_home=profile_home) for name in names]
def _matching_open_operation(names: list[str], *, alias: str | None,
profile_home: str | None) -> ConnectionOperation | None:
matches = [live.find_target(name, alias=alias, profile_home=profile_home) for name in names]
first = next((operation for operation in matches if operation is not None), None)
if first is None:
return None
@@ -38,12 +39,14 @@ def find_or_start_operation(
*,
action: str,
profile_home: str | None,
alias: str | None = None,
) -> AccountOperationStart:
"""``alias`` names the one account of ``names[0]`` to connect; the caller passes one name with it."""
with _start_lock:
if operation := _matching_open_operation(names, profile_home=profile_home):
if operation := _matching_open_operation(names, alias=alias, profile_home=profile_home):
return AccountOperationStart(operation=operation, started=False)
operation = ConnectionOperation(
[Target(name, "connector", action) for name in names],
[Target(name, "connector", action, alias=alias) for name in names],
session_key=f"account:{uuid.uuid4().hex}",
)
started = AccountOperationStart(operation=operation, started=True)

View File

@@ -63,12 +63,16 @@ def get_by_op_id(op_id: str, *, profile_home: Optional[str] = None) -> Optional[
if key == profile_key and operation.op_id == op_id and not operation.settled), None)
def find_target(name: str, *, profile_home: Optional[str] = None) -> Optional[ConnectionOperation]:
def find_target(name: str, *, alias: Optional[str] = None,
profile_home: Optional[str] = None) -> Optional[ConnectionOperation]:
"""The open operation connecting this account: the connector ``name`` and the same ``alias``,
so an open operation for one account is never reused for another account of the same app."""
profile_key = _profile_key(profile_home)
with _lock:
return next((operation for (key, _), operation in _open.items()
if key == profile_key and not operation.settled
and (target := operation.target(name)) is not None and target.kind == "connector"), None)
and (target := operation.target(name)) is not None and target.kind == "connector"
and target.alias == alias), None)
def close(operation: ConnectionOperation) -> None:

View File

@@ -41,6 +41,8 @@ class Target:
extra: dict[str, Any] = field(default_factory=dict)
# The install step an ``initiated`` catalog row is in (an ``InstallPhase`` id); drawn only then.
phase: Optional[str] = None
# The name of the one hosted account this target connects or repairs; absent for the connector's default account.
alias: Optional[str] = None
@property
def resolved(self) -> bool:
@@ -49,6 +51,8 @@ class Target:
def snapshot(self, *, with_url: bool = True) -> dict[str, Any]:
out: dict[str, Any] = {"name": self.name, "kind": self.kind, "action": self.action, "state": self.state.value,
"resolved": self.resolved}
if self.alias:
out["alias"] = self.alias
if self.phase and self.state == TargetState.initiated:
out["phase"] = self.phase
if self.detail: