mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-08 01:16:45 +08:00
Add connector_service_policy (per-service publish switch, tool allowlist, user allowlist) and gate the open-connector catalog, connect flows and task overlays on it. Publish open_connector_apps from whether the integration is wired instead of a feature flag, and drop OPEN_CONNECTOR_API_KEY_SERVICES. Expose /api/admin/open-connector/* (health probe, service catalog with policy and connection counts, connections by user, audited enable/disable and policy writes through runAdminAction). Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01G4Tynn8YQnR5koJTSvFC62
726 lines
22 KiB
Go
726 lines
22 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: connector.sql
|
|
|
|
package db
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const adminCountConnectorConnectionsByService = `-- name: AdminCountConnectorConnectionsByService :many
|
|
|
|
SELECT service,
|
|
count(*) FILTER (WHERE status = 'active')::bigint AS active_count,
|
|
count(*) FILTER (WHERE status = 'reauth_required')::bigint AS reauth_count,
|
|
count(*) FILTER (WHERE status = 'revoked')::bigint AS revoked_count,
|
|
count(DISTINCT user_id) FILTER (WHERE status <> 'revoked')::bigint AS user_count
|
|
FROM user_connector_connection
|
|
WHERE provider = $1
|
|
GROUP BY service
|
|
ORDER BY service ASC
|
|
`
|
|
|
|
type AdminCountConnectorConnectionsByServiceRow struct {
|
|
Service string `json:"service"`
|
|
ActiveCount int64 `json:"active_count"`
|
|
ReauthCount int64 `json:"reauth_count"`
|
|
RevokedCount int64 `json:"revoked_count"`
|
|
UserCount int64 `json:"user_count"`
|
|
}
|
|
|
|
// =====================
|
|
// Connector connection counts (platform admin)
|
|
// =====================
|
|
func (q *Queries) AdminCountConnectorConnectionsByService(ctx context.Context, provider string) ([]AdminCountConnectorConnectionsByServiceRow, error) {
|
|
rows, err := q.db.Query(ctx, adminCountConnectorConnectionsByService, provider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []AdminCountConnectorConnectionsByServiceRow{}
|
|
for rows.Next() {
|
|
var i AdminCountConnectorConnectionsByServiceRow
|
|
if err := rows.Scan(
|
|
&i.Service,
|
|
&i.ActiveCount,
|
|
&i.ReauthCount,
|
|
&i.RevokedCount,
|
|
&i.UserCount,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const adminCountConnectorUsers = `-- name: AdminCountConnectorUsers :one
|
|
SELECT count(DISTINCT c.user_id)
|
|
FROM user_connector_connection c
|
|
JOIN "user" u ON u.id = c.user_id
|
|
WHERE c.provider = $1
|
|
AND ($2::text IS NULL OR c.service = $2::text)
|
|
AND ($3::text IS NULL
|
|
OR u.email ILIKE '%' || $3::text || '%'
|
|
OR u.name ILIKE '%' || $3::text || '%')
|
|
`
|
|
|
|
type AdminCountConnectorUsersParams struct {
|
|
Provider string `json:"provider"`
|
|
Service pgtype.Text `json:"service"`
|
|
Q pgtype.Text `json:"q"`
|
|
}
|
|
|
|
func (q *Queries) AdminCountConnectorUsers(ctx context.Context, arg AdminCountConnectorUsersParams) (int64, error) {
|
|
row := q.db.QueryRow(ctx, adminCountConnectorUsers, arg.Provider, arg.Service, arg.Q)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const adminListConnectorUsers = `-- name: AdminListConnectorUsers :many
|
|
SELECT u.id AS user_id, u.name, u.email, u.disabled_at,
|
|
count(*) FILTER (WHERE c.status = 'active')::bigint AS active_count,
|
|
count(*) FILTER (WHERE c.status = 'reauth_required')::bigint AS reauth_count,
|
|
count(*) FILTER (WHERE c.status = 'revoked')::bigint AS revoked_count,
|
|
COALESCE(array_agg(DISTINCT c.service) FILTER (WHERE c.status <> 'revoked'), '{}')::text[] AS services,
|
|
max(c.connected_at)::timestamptz AS last_connected_at
|
|
FROM user_connector_connection c
|
|
JOIN "user" u ON u.id = c.user_id
|
|
WHERE c.provider = $1
|
|
AND ($2::text IS NULL OR c.service = $2::text)
|
|
AND ($3::text IS NULL
|
|
OR u.email ILIKE '%' || $3::text || '%'
|
|
OR u.name ILIKE '%' || $3::text || '%')
|
|
GROUP BY u.id, u.name, u.email, u.disabled_at
|
|
ORDER BY active_count DESC, u.email ASC
|
|
LIMIT $5 OFFSET $4
|
|
`
|
|
|
|
type AdminListConnectorUsersParams struct {
|
|
Provider string `json:"provider"`
|
|
Service pgtype.Text `json:"service"`
|
|
Q pgtype.Text `json:"q"`
|
|
PageOffset int32 `json:"page_offset"`
|
|
PageLimit int32 `json:"page_limit"`
|
|
}
|
|
|
|
type AdminListConnectorUsersRow struct {
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
Name string `json:"name"`
|
|
Email string `json:"email"`
|
|
DisabledAt pgtype.Timestamptz `json:"disabled_at"`
|
|
ActiveCount int64 `json:"active_count"`
|
|
ReauthCount int64 `json:"reauth_count"`
|
|
RevokedCount int64 `json:"revoked_count"`
|
|
Services []string `json:"services"`
|
|
LastConnectedAt pgtype.Timestamptz `json:"last_connected_at"`
|
|
}
|
|
|
|
func (q *Queries) AdminListConnectorUsers(ctx context.Context, arg AdminListConnectorUsersParams) ([]AdminListConnectorUsersRow, error) {
|
|
rows, err := q.db.Query(ctx, adminListConnectorUsers,
|
|
arg.Provider,
|
|
arg.Service,
|
|
arg.Q,
|
|
arg.PageOffset,
|
|
arg.PageLimit,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []AdminListConnectorUsersRow{}
|
|
for rows.Next() {
|
|
var i AdminListConnectorUsersRow
|
|
if err := rows.Scan(
|
|
&i.UserID,
|
|
&i.Name,
|
|
&i.Email,
|
|
&i.DisabledAt,
|
|
&i.ActiveCount,
|
|
&i.ReauthCount,
|
|
&i.RevokedCount,
|
|
&i.Services,
|
|
&i.LastConnectedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const consumeConnectorOAuthState = `-- name: ConsumeConnectorOAuthState :one
|
|
UPDATE connector_oauth_state
|
|
SET consumed_at = $1
|
|
WHERE nonce_hash = $2 AND consumed_at IS NULL AND expires_at > $1
|
|
RETURNING nonce_hash, provider, user_id, service, request_id, expires_at, consumed_at, created_at
|
|
`
|
|
|
|
type ConsumeConnectorOAuthStateParams struct {
|
|
Now pgtype.Timestamptz `json:"now"`
|
|
NonceHash []byte `json:"nonce_hash"`
|
|
}
|
|
|
|
// Atomic single-use: the first caller gets the row, replays get no rows.
|
|
func (q *Queries) ConsumeConnectorOAuthState(ctx context.Context, arg ConsumeConnectorOAuthStateParams) (ConnectorOauthState, error) {
|
|
row := q.db.QueryRow(ctx, consumeConnectorOAuthState, arg.Now, arg.NonceHash)
|
|
var i ConnectorOauthState
|
|
err := row.Scan(
|
|
&i.NonceHash,
|
|
&i.Provider,
|
|
&i.UserID,
|
|
&i.Service,
|
|
&i.RequestID,
|
|
&i.ExpiresAt,
|
|
&i.ConsumedAt,
|
|
&i.CreatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteExpiredConnectorOAuthStates = `-- name: DeleteExpiredConnectorOAuthStates :execrows
|
|
DELETE FROM connector_oauth_state WHERE expires_at < $1
|
|
`
|
|
|
|
func (q *Queries) DeleteExpiredConnectorOAuthStates(ctx context.Context, now pgtype.Timestamptz) (int64, error) {
|
|
result, err := q.db.Exec(ctx, deleteExpiredConnectorOAuthStates, now)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return result.RowsAffected(), nil
|
|
}
|
|
|
|
const existsPendingConnectorOAuthForService = `-- name: ExistsPendingConnectorOAuthForService :one
|
|
SELECT EXISTS (
|
|
SELECT 1 FROM connector_oauth_state
|
|
WHERE provider = $1 AND service = $2
|
|
AND consumed_at IS NULL AND expires_at > $3
|
|
AND user_id <> $4
|
|
)
|
|
`
|
|
|
|
type ExistsPendingConnectorOAuthForServiceParams struct {
|
|
Provider string `json:"provider"`
|
|
Service string `json:"service"`
|
|
Now pgtype.Timestamptz `json:"now"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
}
|
|
|
|
// True when a different user has an unconsumed, unexpired connect for the
|
|
// service (open-connector has one owner, so a second connect would supersede it).
|
|
func (q *Queries) ExistsPendingConnectorOAuthForService(ctx context.Context, arg ExistsPendingConnectorOAuthForServiceParams) (bool, error) {
|
|
row := q.db.QueryRow(ctx, existsPendingConnectorOAuthForService,
|
|
arg.Provider,
|
|
arg.Service,
|
|
arg.Now,
|
|
arg.UserID,
|
|
)
|
|
var exists bool
|
|
err := row.Scan(&exists)
|
|
return exists, err
|
|
}
|
|
|
|
const getConnectorOAuthStateByNonceHash = `-- name: GetConnectorOAuthStateByNonceHash :one
|
|
SELECT nonce_hash, provider, user_id, service, request_id, expires_at, consumed_at, created_at FROM connector_oauth_state
|
|
WHERE nonce_hash = $1 AND consumed_at IS NULL AND expires_at > $2
|
|
`
|
|
|
|
type GetConnectorOAuthStateByNonceHashParams struct {
|
|
NonceHash []byte `json:"nonce_hash"`
|
|
Now pgtype.Timestamptz `json:"now"`
|
|
}
|
|
|
|
func (q *Queries) GetConnectorOAuthStateByNonceHash(ctx context.Context, arg GetConnectorOAuthStateByNonceHashParams) (ConnectorOauthState, error) {
|
|
row := q.db.QueryRow(ctx, getConnectorOAuthStateByNonceHash, arg.NonceHash, arg.Now)
|
|
var i ConnectorOauthState
|
|
err := row.Scan(
|
|
&i.NonceHash,
|
|
&i.Provider,
|
|
&i.UserID,
|
|
&i.Service,
|
|
&i.RequestID,
|
|
&i.ExpiresAt,
|
|
&i.ConsumedAt,
|
|
&i.CreatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getConnectorServicePolicy = `-- name: GetConnectorServicePolicy :one
|
|
SELECT provider, service, enabled, allowed_tools, allowed_user_ids, updated_by, created_at, updated_at FROM connector_service_policy
|
|
WHERE provider = $1 AND service = $2
|
|
`
|
|
|
|
type GetConnectorServicePolicyParams struct {
|
|
Provider string `json:"provider"`
|
|
Service string `json:"service"`
|
|
}
|
|
|
|
func (q *Queries) GetConnectorServicePolicy(ctx context.Context, arg GetConnectorServicePolicyParams) (ConnectorServicePolicy, error) {
|
|
row := q.db.QueryRow(ctx, getConnectorServicePolicy, arg.Provider, arg.Service)
|
|
var i ConnectorServicePolicy
|
|
err := row.Scan(
|
|
&i.Provider,
|
|
&i.Service,
|
|
&i.Enabled,
|
|
&i.AllowedTools,
|
|
&i.AllowedUserIds,
|
|
&i.UpdatedBy,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getUserConnectorConnection = `-- name: GetUserConnectorConnection :one
|
|
SELECT id, provider, user_id, service, connection_id, connection_name, auth_type, status, is_default, label, connected_at, last_used_at, created_at, updated_at FROM user_connector_connection
|
|
WHERE id = $1 AND user_id = $2
|
|
`
|
|
|
|
type GetUserConnectorConnectionParams struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
}
|
|
|
|
// Owner-scoped lookup so one user cannot act on another's connection by
|
|
// guessing the UUID.
|
|
func (q *Queries) GetUserConnectorConnection(ctx context.Context, arg GetUserConnectorConnectionParams) (UserConnectorConnection, error) {
|
|
row := q.db.QueryRow(ctx, getUserConnectorConnection, arg.ID, arg.UserID)
|
|
var i UserConnectorConnection
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Provider,
|
|
&i.UserID,
|
|
&i.Service,
|
|
&i.ConnectionID,
|
|
&i.ConnectionName,
|
|
&i.AuthType,
|
|
&i.Status,
|
|
&i.IsDefault,
|
|
&i.Label,
|
|
&i.ConnectedAt,
|
|
&i.LastUsedAt,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const insertConnectorOAuthState = `-- name: InsertConnectorOAuthState :exec
|
|
|
|
INSERT INTO connector_oauth_state (nonce_hash, provider, user_id, service, request_id, expires_at)
|
|
VALUES ($1, $2, $3, $4, $5, $6)
|
|
`
|
|
|
|
type InsertConnectorOAuthStateParams struct {
|
|
NonceHash []byte `json:"nonce_hash"`
|
|
Provider string `json:"provider"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
Service string `json:"service"`
|
|
RequestID string `json:"request_id"`
|
|
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
|
|
}
|
|
|
|
// =====================
|
|
// Connector OAuth state (in-flight connects)
|
|
// =====================
|
|
func (q *Queries) InsertConnectorOAuthState(ctx context.Context, arg InsertConnectorOAuthStateParams) error {
|
|
_, err := q.db.Exec(ctx, insertConnectorOAuthState,
|
|
arg.NonceHash,
|
|
arg.Provider,
|
|
arg.UserID,
|
|
arg.Service,
|
|
arg.RequestID,
|
|
arg.ExpiresAt,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const listConnectorServicePolicies = `-- name: ListConnectorServicePolicies :many
|
|
|
|
SELECT provider, service, enabled, allowed_tools, allowed_user_ids, updated_by, created_at, updated_at FROM connector_service_policy
|
|
WHERE provider = $1
|
|
ORDER BY service ASC
|
|
`
|
|
|
|
// =====================
|
|
// Connector service policy (platform admin)
|
|
// =====================
|
|
func (q *Queries) ListConnectorServicePolicies(ctx context.Context, provider string) ([]ConnectorServicePolicy, error) {
|
|
rows, err := q.db.Query(ctx, listConnectorServicePolicies, provider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ConnectorServicePolicy{}
|
|
for rows.Next() {
|
|
var i ConnectorServicePolicy
|
|
if err := rows.Scan(
|
|
&i.Provider,
|
|
&i.Service,
|
|
&i.Enabled,
|
|
&i.AllowedTools,
|
|
&i.AllowedUserIds,
|
|
&i.UpdatedBy,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listUserConnectorConnections = `-- name: ListUserConnectorConnections :many
|
|
SELECT id, provider, user_id, service, connection_id, connection_name, auth_type, status, is_default, label, connected_at, last_used_at, created_at, updated_at FROM user_connector_connection
|
|
WHERE provider = $1 AND user_id = $2 AND status <> 'revoked'
|
|
ORDER BY service ASC, is_default DESC, connected_at ASC
|
|
`
|
|
|
|
type ListUserConnectorConnectionsParams struct {
|
|
Provider string `json:"provider"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
}
|
|
|
|
// Non-revoked connections (active and reauth_required) so the owner can see and
|
|
// repair the latter; callers that mount connections filter on status = 'active'.
|
|
// Default connection first within each service.
|
|
func (q *Queries) ListUserConnectorConnections(ctx context.Context, arg ListUserConnectorConnectionsParams) ([]UserConnectorConnection, error) {
|
|
rows, err := q.db.Query(ctx, listUserConnectorConnections, arg.Provider, arg.UserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []UserConnectorConnection{}
|
|
for rows.Next() {
|
|
var i UserConnectorConnection
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Provider,
|
|
&i.UserID,
|
|
&i.Service,
|
|
&i.ConnectionID,
|
|
&i.ConnectionName,
|
|
&i.AuthType,
|
|
&i.Status,
|
|
&i.IsDefault,
|
|
&i.Label,
|
|
&i.ConnectedAt,
|
|
&i.LastUsedAt,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listUserConnectorConnectionsByProviderAndStatus = `-- name: ListUserConnectorConnectionsByProviderAndStatus :many
|
|
SELECT id, provider, user_id, service, connection_id, connection_name, auth_type, status, is_default, label, connected_at, last_used_at, created_at, updated_at FROM user_connector_connection
|
|
WHERE provider = $1 AND status = $2
|
|
ORDER BY created_at ASC
|
|
`
|
|
|
|
type ListUserConnectorConnectionsByProviderAndStatusParams struct {
|
|
Provider string `json:"provider"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
func (q *Queries) ListUserConnectorConnectionsByProviderAndStatus(ctx context.Context, arg ListUserConnectorConnectionsByProviderAndStatusParams) ([]UserConnectorConnection, error) {
|
|
rows, err := q.db.Query(ctx, listUserConnectorConnectionsByProviderAndStatus, arg.Provider, arg.Status)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []UserConnectorConnection{}
|
|
for rows.Next() {
|
|
var i UserConnectorConnection
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.Provider,
|
|
&i.UserID,
|
|
&i.Service,
|
|
&i.ConnectionID,
|
|
&i.ConnectionName,
|
|
&i.AuthType,
|
|
&i.Status,
|
|
&i.IsDefault,
|
|
&i.Label,
|
|
&i.ConnectedAt,
|
|
&i.LastUsedAt,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const markUserConnectorConnectionRevoked = `-- name: MarkUserConnectorConnectionRevoked :exec
|
|
UPDATE user_connector_connection
|
|
SET status = 'revoked', is_default = FALSE, updated_at = now()
|
|
WHERE id = $1 AND user_id = $2
|
|
`
|
|
|
|
type MarkUserConnectorConnectionRevokedParams struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
}
|
|
|
|
// Idempotent; a revoked row is never the default.
|
|
func (q *Queries) MarkUserConnectorConnectionRevoked(ctx context.Context, arg MarkUserConnectorConnectionRevokedParams) error {
|
|
_, err := q.db.Exec(ctx, markUserConnectorConnectionRevoked, arg.ID, arg.UserID)
|
|
return err
|
|
}
|
|
|
|
const setConnectorServiceEnabled = `-- name: SetConnectorServiceEnabled :one
|
|
INSERT INTO connector_service_policy (provider, service, enabled, updated_by)
|
|
VALUES ($1, $2, $3, $4)
|
|
ON CONFLICT (provider, service) DO UPDATE SET
|
|
enabled = EXCLUDED.enabled,
|
|
updated_by = EXCLUDED.updated_by,
|
|
updated_at = now()
|
|
RETURNING provider, service, enabled, allowed_tools, allowed_user_ids, updated_by, created_at, updated_at
|
|
`
|
|
|
|
type SetConnectorServiceEnabledParams struct {
|
|
Provider string `json:"provider"`
|
|
Service string `json:"service"`
|
|
Enabled bool `json:"enabled"`
|
|
UpdatedBy pgtype.UUID `json:"updated_by"`
|
|
}
|
|
|
|
// Publishes or delists a service, leaving its tool and user allowlists intact.
|
|
func (q *Queries) SetConnectorServiceEnabled(ctx context.Context, arg SetConnectorServiceEnabledParams) (ConnectorServicePolicy, error) {
|
|
row := q.db.QueryRow(ctx, setConnectorServiceEnabled,
|
|
arg.Provider,
|
|
arg.Service,
|
|
arg.Enabled,
|
|
arg.UpdatedBy,
|
|
)
|
|
var i ConnectorServicePolicy
|
|
err := row.Scan(
|
|
&i.Provider,
|
|
&i.Service,
|
|
&i.Enabled,
|
|
&i.AllowedTools,
|
|
&i.AllowedUserIds,
|
|
&i.UpdatedBy,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const setConnectorServicePolicy = `-- name: SetConnectorServicePolicy :one
|
|
INSERT INTO connector_service_policy (provider, service, allowed_tools, allowed_user_ids, updated_by)
|
|
VALUES ($1, $2, $3::text[], $4::uuid[], $5)
|
|
ON CONFLICT (provider, service) DO UPDATE SET
|
|
allowed_tools = EXCLUDED.allowed_tools,
|
|
allowed_user_ids = EXCLUDED.allowed_user_ids,
|
|
updated_by = EXCLUDED.updated_by,
|
|
updated_at = now()
|
|
RETURNING provider, service, enabled, allowed_tools, allowed_user_ids, updated_by, created_at, updated_at
|
|
`
|
|
|
|
type SetConnectorServicePolicyParams struct {
|
|
Provider string `json:"provider"`
|
|
Service string `json:"service"`
|
|
AllowedTools []string `json:"allowed_tools"`
|
|
AllowedUserIds []pgtype.UUID `json:"allowed_user_ids"`
|
|
UpdatedBy pgtype.UUID `json:"updated_by"`
|
|
}
|
|
|
|
// Replaces the tool and user allowlists; a service without a row stays delisted.
|
|
func (q *Queries) SetConnectorServicePolicy(ctx context.Context, arg SetConnectorServicePolicyParams) (ConnectorServicePolicy, error) {
|
|
row := q.db.QueryRow(ctx, setConnectorServicePolicy,
|
|
arg.Provider,
|
|
arg.Service,
|
|
arg.AllowedTools,
|
|
arg.AllowedUserIds,
|
|
arg.UpdatedBy,
|
|
)
|
|
var i ConnectorServicePolicy
|
|
err := row.Scan(
|
|
&i.Provider,
|
|
&i.Service,
|
|
&i.Enabled,
|
|
&i.AllowedTools,
|
|
&i.AllowedUserIds,
|
|
&i.UpdatedBy,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const setUserConnectorConnectionDefault = `-- name: SetUserConnectorConnectionDefault :exec
|
|
UPDATE user_connector_connection
|
|
SET is_default = (id = $1), updated_at = now()
|
|
WHERE provider = $2
|
|
AND user_id = $3
|
|
AND service = $4
|
|
AND status = 'active'
|
|
AND (id = $1 OR is_default)
|
|
`
|
|
|
|
type SetUserConnectorConnectionDefaultParams struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
Provider string `json:"provider"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
Service string `json:"service"`
|
|
}
|
|
|
|
// Makes one active connection the default of its (provider, user, service)
|
|
// group and clears the flag on its siblings in a single statement.
|
|
func (q *Queries) SetUserConnectorConnectionDefault(ctx context.Context, arg SetUserConnectorConnectionDefaultParams) error {
|
|
_, err := q.db.Exec(ctx, setUserConnectorConnectionDefault,
|
|
arg.ID,
|
|
arg.Provider,
|
|
arg.UserID,
|
|
arg.Service,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const updateUserConnectorConnectionLabel = `-- name: UpdateUserConnectorConnectionLabel :one
|
|
UPDATE user_connector_connection
|
|
SET label = $1, updated_at = now()
|
|
WHERE id = $2 AND user_id = $3
|
|
RETURNING id, provider, user_id, service, connection_id, connection_name, auth_type, status, is_default, label, connected_at, last_used_at, created_at, updated_at
|
|
`
|
|
|
|
type UpdateUserConnectorConnectionLabelParams struct {
|
|
Label string `json:"label"`
|
|
ID pgtype.UUID `json:"id"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
}
|
|
|
|
func (q *Queries) UpdateUserConnectorConnectionLabel(ctx context.Context, arg UpdateUserConnectorConnectionLabelParams) (UserConnectorConnection, error) {
|
|
row := q.db.QueryRow(ctx, updateUserConnectorConnectionLabel, arg.Label, arg.ID, arg.UserID)
|
|
var i UserConnectorConnection
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Provider,
|
|
&i.UserID,
|
|
&i.Service,
|
|
&i.ConnectionID,
|
|
&i.ConnectionName,
|
|
&i.AuthType,
|
|
&i.Status,
|
|
&i.IsDefault,
|
|
&i.Label,
|
|
&i.ConnectedAt,
|
|
&i.LastUsedAt,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const updateUserConnectorConnectionStatus = `-- name: UpdateUserConnectorConnectionStatus :exec
|
|
UPDATE user_connector_connection
|
|
SET status = $1, updated_at = now()
|
|
WHERE id = $2 AND status <> $1
|
|
`
|
|
|
|
type UpdateUserConnectorConnectionStatusParams struct {
|
|
Status string `json:"status"`
|
|
ID pgtype.UUID `json:"id"`
|
|
}
|
|
|
|
func (q *Queries) UpdateUserConnectorConnectionStatus(ctx context.Context, arg UpdateUserConnectorConnectionStatusParams) error {
|
|
_, err := q.db.Exec(ctx, updateUserConnectorConnectionStatus, arg.Status, arg.ID)
|
|
return err
|
|
}
|
|
|
|
const upsertUserConnectorConnection = `-- name: UpsertUserConnectorConnection :one
|
|
|
|
INSERT INTO user_connector_connection (
|
|
provider, user_id, service, connection_id, connection_name, auth_type, label, is_default, status
|
|
) VALUES (
|
|
$1, $2, $3, $4, $5, $6, $7, $8, 'active'
|
|
)
|
|
ON CONFLICT (provider, user_id, connection_id) DO UPDATE SET
|
|
service = EXCLUDED.service,
|
|
connection_name = EXCLUDED.connection_name,
|
|
auth_type = EXCLUDED.auth_type,
|
|
label = CASE WHEN EXCLUDED.label <> '' THEN EXCLUDED.label ELSE user_connector_connection.label END,
|
|
status = 'active',
|
|
updated_at = now()
|
|
RETURNING id, provider, user_id, service, connection_id, connection_name, auth_type, status, is_default, label, connected_at, last_used_at, created_at, updated_at
|
|
`
|
|
|
|
type UpsertUserConnectorConnectionParams struct {
|
|
Provider string `json:"provider"`
|
|
UserID pgtype.UUID `json:"user_id"`
|
|
Service string `json:"service"`
|
|
ConnectionID string `json:"connection_id"`
|
|
ConnectionName string `json:"connection_name"`
|
|
AuthType string `json:"auth_type"`
|
|
Label string `json:"label"`
|
|
IsDefault bool `json:"is_default"`
|
|
}
|
|
|
|
// =====================
|
|
// User Connector Connection (open-connector)
|
|
// =====================
|
|
// Idempotent on (provider, user_id, connection_id): a duplicate callback
|
|
// re-activates the same row. is_default and connected_at are preserved on
|
|
// conflict; a non-empty label replaces the stored one.
|
|
func (q *Queries) UpsertUserConnectorConnection(ctx context.Context, arg UpsertUserConnectorConnectionParams) (UserConnectorConnection, error) {
|
|
row := q.db.QueryRow(ctx, upsertUserConnectorConnection,
|
|
arg.Provider,
|
|
arg.UserID,
|
|
arg.Service,
|
|
arg.ConnectionID,
|
|
arg.ConnectionName,
|
|
arg.AuthType,
|
|
arg.Label,
|
|
arg.IsDefault,
|
|
)
|
|
var i UserConnectorConnection
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.Provider,
|
|
&i.UserID,
|
|
&i.Service,
|
|
&i.ConnectionID,
|
|
&i.ConnectionName,
|
|
&i.AuthType,
|
|
&i.Status,
|
|
&i.IsDefault,
|
|
&i.Label,
|
|
&i.ConnectedAt,
|
|
&i.LastUsedAt,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|