Files
probo/pkg/coredata/connector_settings.go
Sacha Al Himdani 4c57d201a4 Make license declarations consistently MIT
The source headers, LICENSE files, and license metadata had drifted
apart. Align the entire project to MIT:

- Convert every source-file header to the MIT text across all comment
  styles (Go, TS, TSX, JS, MJS, SQL, CSS, GraphQL, shell), including
  SPDX-License-Identifier tags
- Set the root and cookie-banner LICENSE files to the MIT text with a
  "MIT License" title line
- Switch the package.json license fields, Docker image label, and
  cookie-banner README to MIT
- Update docs and the genmodels header generator accordingly
- Normalize copyright lines to a single format
  (Copyright (c) <year(s)> Probo Inc <hello@probo.com>.): unify the
  hello@getprobo.com and hello@probo.inc emails to hello@probo.com and
  the comma-separated years to a hyphenated range

Genuine third-party references are intentionally left untouched: the
Lucide icon attributions (Lucide is ISC) and the trivy dependency
license allowlist.

Signed-off-by: Sacha Al Himdani <sacha@probo.com>
2026-07-13 16:21:14 +02:00

240 lines
7.9 KiB
Go

// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
package coredata
import (
"encoding/json"
"fmt"
"go.probo.inc/probo/pkg/connector"
)
type (
SlackConnectorSettings struct {
Channel string `json:"channel,omitempty"`
ChannelID string `json:"channel_id,omitempty"`
}
TallyConnectorSettings struct {
OrganizationID string `json:"organization_id"`
}
OnePasswordConnectorSettings struct {
SCIMBridgeURL string `json:"scim_bridge_url"`
}
SentryConnectorSettings struct {
OrganizationSlug string `json:"organization_slug"`
}
SigNozConnectorSettings struct {
BaseURL string `json:"base_url"`
}
GrafanaConnectorSettings struct {
BaseURL string `json:"base_url"`
}
SupabaseConnectorSettings struct {
OrganizationSlug string `json:"organization_slug"`
}
GitHubConnectorSettings struct {
Organization string `json:"organization"`
}
OnePasswordUsersAPISettings struct {
AccountID string `json:"account_id"`
Region string `json:"region"`
}
GitLabConnectorSettings struct {
GroupID string `json:"group_id"`
}
BitbucketConnectorSettings struct {
Workspace string `json:"workspace"`
}
HerokuConnectorSettings struct {
TeamID string `json:"team_id"`
}
PagerDutyConnectorSettings struct {
Subdomain string `json:"subdomain"`
}
AsanaConnectorSettings struct {
WorkspaceGID string `json:"workspace_gid"`
}
NetlifyConnectorSettings struct {
AccountSlug string `json:"account_slug"`
}
ClickUpConnectorSettings struct {
TeamID string `json:"team_id"`
}
// DocuSignConnectorSettings holds the DocuSign account the user picked
// after OAuth. A DocuSign user can have access to multiple accounts, so
// the post-OAuth picker scopes the access source to one; AccountID is the
// selected account's UUID. The driver and name resolver re-resolve the
// account's data-center base URI from /oauth/userinfo at fetch time.
DocuSignConnectorSettings struct {
AccountID string `json:"account_id"`
}
VercelConnectorSettings struct {
TeamID string `json:"team_id"`
}
MetabaseConnectorSettings struct {
InstanceURL string `json:"instance_url"`
}
// PostHogConnectorSettings carries the data-API base host for the
// PostHog provider, which spans cloud and self-hosted deployments. For
// API-key connections it is the region-pinned host
// (https://us.posthog.com / https://eu.posthog.com) or a self-hosted
// instance URL. It is empty for cloud OAuth connections — the driver
// then discovers the region (us/eu) by probing, since the
// region-agnostic oauth.posthog.com gateway does not serve the data API.
PostHogConnectorSettings struct {
BaseURL string `json:"base_url"`
}
// DatadogConnectorSettings holds the per-customer Datadog site captured
// during the OAuth callback. Region is the site key (e.g. "US3") used for
// the AccessReviewSource title; Domain is the API domain (e.g.
// "us3.datadoghq.com") the driver and name resolver use to build hosts.
DatadogConnectorSettings struct {
Region string `json:"region"`
Domain string `json:"domain"`
}
// OktaConnectorSettings holds the customer's Okta org domain (the bare
// host, e.g. "acme.okta.com") supplied with the API token. It is the
// single-tenant identifier the driver and name resolver use to build
// the per-org API host (https://<domain>/api/v1/...). Okta has no
// central API gateway — every org authenticates against its own
// domain — so the host is operator-supplied and validated (see
// connector.NormalizeOktaDomain) before it reaches URL construction.
OktaConnectorSettings struct {
Domain string `json:"domain"`
}
// ZendeskConnectorSettings holds the per-customer Zendesk subdomain
// captured at connect time (the customer types it before the OAuth
// redirect, and it rides the signed state token to the callback —
// Zendesk does not echo it back). Subdomain is the <subdomain> part of
// <subdomain>.zendesk.com, used by the driver to build the API host and
// by the name resolver for the AccessReviewSource title.
ZendeskConnectorSettings struct {
Subdomain string `json:"subdomain"`
}
BetterStackConnectorSettings struct {
TeamName string `json:"team_name"`
}
QoveryConnectorSettings struct {
OrganizationID string `json:"organization_id"`
}
// RenderConnectorSettings stores the Render workspace identifier. The
// value is Render's owner ID (e.g. "tea-..." for a team workspace or
// "usr-..." for a personal one), surfaced to operators as "Workspace ID"
// and used as the {ownerId} path segment on /v1/owners/{ownerId}/...
RenderConnectorSettings struct {
OwnerID string `json:"owner_id"`
}
NeonConnectorSettings struct {
OrganizationID string `json:"organization_id"`
}
// LangfuseConnectorSettings carries the Langfuse API base URL, which
// spans the regional cloud hosts (cloud.langfuse.com /
// us.cloud.langfuse.com / …) and self-hosted instances. The
// organization-scoped API key is bound to a single organization on
// that host, so the base URL is the only per-tenant setting.
LangfuseConnectorSettings struct {
BaseURL string `json:"base_url"`
}
// ScalewayConnectorSettings stores the Scaleway Organization ID. A secret
// key is bound to one Organization, but GET /iam/v1alpha1/users requires
// the organization_id explicitly, so it is captured up front.
ScalewayConnectorSettings struct {
OrganizationID string `json:"organization_id"`
}
// CrispConnectorSettings stores the Crisp Website ID. A plugin token can
// be connected to several websites, so the reviewed website is captured up
// front as the {website_id} path segment on /v1/website/{website_id}/...
CrispConnectorSettings struct {
WebsiteID string `json:"website_id"`
}
)
// GrantType returns the OAuth2 grant type recorded on the connector's
// Connection, or the empty string when the connector is not an OAuth2
// connector. Driver factories that dispatch on grant type (1Password)
// read this instead of inspecting the typed Connection directly.
func (c *Connector) GrantType() string {
if oauth2Conn, ok := c.Connection.(*connector.OAuth2Connection); ok {
return string(oauth2Conn.GrantType)
}
return ""
}
// SetSettings marshals a typed settings struct into the connector's RawSettings.
func (c *Connector) SetSettings(v any) error {
data, err := json.Marshal(v)
if err != nil {
return fmt.Errorf("cannot marshal connector settings: %w", err)
}
c.RawSettings = data
return nil
}
// ConnectorSettings unmarshals the connector's RawSettings into the
// requested settings struct. Empty or null RawSettings yields the zero
// value with no error. Use as:
//
// settings, err := coredata.ConnectorSettings[coredata.GitHubConnectorSettings](dbConnector)
func ConnectorSettings[T any](c *Connector) (T, error) {
var s T
if len(c.RawSettings) == 0 || string(c.RawSettings) == "null" {
return s, nil
}
if err := json.Unmarshal(c.RawSettings, &s); err != nil {
return s, fmt.Errorf("cannot unmarshal connector settings: %w", err)
}
return s, nil
}