Files
probo/pkg/server/api/console/v1/connector.resolvers.go
Émile Ré 31cca05ca4 Split GraphQL schemas into per-entity files
Split each API's monolithic schema.graphql into per-coredata-model
files under graphql/ subdirectories. gqlgen's follow-schema layout
with {name}.resolvers.go template generates one resolver file per
schema file. Relay uses schema + schemaExtensions to load the split
files.

Connect API: 8 files (base, session, organization, profile,
personal_api_key, saml, scim, audit_log)

Trust API: 5 files (base, trust_center, auth, nda, mailing_list)

Console API: 25 files covering all domain entities

Types extended across files (Organization, Mutation, Viewer,
TrustCenter, Identity) are defined in base.graphql as required by
Relay's schemaExtensions.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-15 09:19:38 +04:00

275 lines
9.4 KiB
Go

package console_v1
// This file will be automatically regenerated based on the schema, any resolver
// implementations
// will be copied through when generating and any unknown code will be moved to the end.
// Code generated by github.com/99designs/gqlgen version v0.17.87
import (
"context"
"errors"
"fmt"
"go.gearno.de/kit/log"
"go.probo.inc/probo/pkg/accessreview/drivers"
"go.probo.inc/probo/pkg/connector"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/page"
"go.probo.inc/probo/pkg/probo"
"go.probo.inc/probo/pkg/server/api/console/v1/schema"
"go.probo.inc/probo/pkg/server/api/console/v1/types"
"go.probo.inc/probo/pkg/server/gqlutils"
"go.probo.inc/probo/pkg/slack"
)
// Oauth2Scopes is the resolver for the oauth2Scopes field.
func (r *connectorResolver) Oauth2Scopes(ctx context.Context, obj *types.Connector) ([]string, error) {
scopes := drivers.ProviderOAuth2Scopes(obj.Provider)
if scopes == nil {
return []string{}, nil
}
return scopes, nil
}
// CreateAPIKeyConnector is the resolver for the createAPIKeyConnector field.
func (r *mutationResolver) CreateAPIKeyConnector(ctx context.Context, input types.CreateAPIKeyConnectorInput) (*types.CreateAPIKeyConnectorPayload, error) {
if err := r.authorize(ctx, input.OrganizationID, probo.ActionConnectorCreate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
req := probo.CreateConnectorRequest{
OrganizationID: input.OrganizationID,
Provider: input.Provider,
Protocol: coredata.ConnectorProtocolAPIKey,
Connection: &connector.APIKeyConnection{APIKey: input.APIKey},
}
if input.TallyOrganizationID != nil {
req.TallySettings = &coredata.TallyConnectorSettings{
OrganizationID: *input.TallyOrganizationID,
}
}
if input.SentryOrganizationSlug != nil {
req.SentrySettings = &coredata.SentryConnectorSettings{
OrganizationSlug: *input.SentryOrganizationSlug,
}
}
if input.SupabaseOrganizationSlug != nil {
req.SupabaseSettings = &coredata.SupabaseConnectorSettings{
OrganizationSlug: *input.SupabaseOrganizationSlug,
}
}
if input.GithubOrganization != nil {
req.GitHubSettings = &coredata.GitHubConnectorSettings{
Organization: *input.GithubOrganization,
}
}
if input.OnePasswordScimBridgeURL != nil {
req.OnePasswordSettings = &coredata.OnePasswordConnectorSettings{
SCIMBridgeURL: *input.OnePasswordScimBridgeURL,
}
}
cnnctr, err := prb.Connectors.Create(ctx, req)
if err != nil {
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
return nil, gqlutils.Conflict(ctx, err)
}
panic(fmt.Errorf("cannot create API key connector: %w", err))
}
return &types.CreateAPIKeyConnectorPayload{
Connector: types.NewConnector(cnnctr),
}, nil
}
// CreateClientCredentialsConnector is the resolver for the createClientCredentialsConnector field.
func (r *mutationResolver) CreateClientCredentialsConnector(ctx context.Context, input types.CreateClientCredentialsConnectorInput) (*types.CreateClientCredentialsConnectorPayload, error) {
if err := r.authorize(ctx, input.OrganizationID, probo.ActionConnectorCreate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
oauth2Conn := &connector.OAuth2Connection{
GrantType: connector.OAuth2GrantTypeClientCredentials,
ClientID: input.ClientID,
ClientSecret: input.ClientSecret,
TokenURL: input.TokenURL,
}
if input.Scope != nil {
oauth2Conn.Scope = *input.Scope
}
req := probo.CreateConnectorRequest{
OrganizationID: input.OrganizationID,
Provider: input.Provider,
Protocol: coredata.ConnectorProtocolOAuth2,
Connection: oauth2Conn,
}
if input.OnePasswordAccountID != nil && input.OnePasswordRegion != nil {
req.OnePasswordUsersAPISettings = &coredata.OnePasswordUsersAPISettings{
AccountID: *input.OnePasswordAccountID,
Region: *input.OnePasswordRegion,
}
}
cnnctr, err := prb.Connectors.Create(ctx, req)
if err != nil {
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
return nil, gqlutils.Conflict(ctx, err)
}
panic(fmt.Errorf("cannot create client credentials connector: %w", err))
}
return &types.CreateClientCredentialsConnectorPayload{
Connector: types.NewConnector(cnnctr),
}, nil
}
// DeleteConnector is the resolver for the deleteConnector field.
func (r *mutationResolver) DeleteConnector(ctx context.Context, input types.DeleteConnectorInput) (*types.DeleteConnectorPayload, error) {
if err := r.authorize(ctx, input.ConnectorID, probo.ActionConnectorDelete); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.ConnectorID.TenantID())
if err := prb.Connectors.Delete(ctx, input.ConnectorID); err != nil {
panic(fmt.Errorf("cannot delete connector: %w", err))
}
return &types.DeleteConnectorPayload{
DeletedConnectorID: input.ConnectorID,
}, nil
}
// DeleteSlackConnection is the resolver for the deleteSlackConnection field.
func (r *mutationResolver) DeleteSlackConnection(ctx context.Context, input types.DeleteSlackConnectionInput) (*types.DeleteSlackConnectionPayload, error) {
if err := r.authorize(ctx, input.SlackConnectionID, probo.ActionConnectorDelete); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.SlackConnectionID.TenantID())
err := prb.Connectors.Delete(ctx, input.SlackConnectionID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot delete slack connection", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.DeleteSlackConnectionPayload{
DeletedSlackConnectionID: input.SlackConnectionID,
}, nil
}
// SlackConnections is the resolver for the slackConnections field.
func (r *organizationResolver) SlackConnections(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.SlackConnectionConnection, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionSlackConnectionList); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
slackProvider := coredata.ConnectorProviderSlack
filter := coredata.NewConnectorProviderFilter(&slackProvider)
pageOrderBy := page.OrderBy[coredata.ConnectorOrderField]{
Field: coredata.ConnectorOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := prb.Connectors.ListForOrganizationID(ctx, obj.ID, cursor, filter)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot list organization slack connections", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewSlackConnectionConnection(page), nil
}
// SlackOAuth2Scopes is the resolver for the slackOAuth2Scopes field.
func (r *organizationResolver) SlackOAuth2Scopes(ctx context.Context, obj *types.Organization) ([]string, error) {
return slack.OAuth2Scopes, nil
}
// Connectors is the resolver for the connectors field.
func (r *organizationResolver) Connectors(ctx context.Context, obj *types.Organization, filter *types.ConnectorFilter) ([]*types.Connector, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionConnectorList); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
connectors, err := prb.Connectors.ListAllForOrganizationID(ctx, obj.ID)
if err != nil {
panic(fmt.Errorf("cannot list organization connectors: %w", err))
}
if filter != nil && len(filter.Providers) > 0 {
allowed := make(map[coredata.ConnectorProvider]struct{}, len(filter.Providers))
for _, provider := range filter.Providers {
allowed[provider] = struct{}{}
}
filtered := make(coredata.Connectors, 0, len(connectors))
for _, cnnctr := range connectors {
if _, ok := allowed[cnnctr.Provider]; ok {
filtered = append(filtered, cnnctr)
}
}
connectors = filtered
}
return types.NewConnectors(connectors), nil
}
// ConnectorProviderInfos is the resolver for the connectorProviderInfos field.
func (r *organizationResolver) ConnectorProviderInfos(ctx context.Context, obj *types.Organization) ([]*types.ConnectorProviderInfo, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionConnectorList); err != nil {
return nil, err
}
var infos []*types.ConnectorProviderInfo
for _, provider := range coredata.ConnectorProviders() {
_, oauthErr := r.connectorRegistry.Get(string(provider))
scopes := drivers.ProviderOAuth2Scopes(provider)
if scopes == nil {
scopes = []string{}
}
info := &types.ConnectorProviderInfo{
Provider: provider,
DisplayName: providerDisplayName(provider),
OauthConfigured: oauthErr == nil,
APIKeySupported: providerSupportsAPIKey(provider),
ClientCredentialsSupported: providerSupportsClientCredentials(provider),
Oauth2Scopes: scopes,
ExtraSettings: providerExtraSettings(provider),
}
infos = append(infos, info)
}
return infos, nil
}
// Permission is the resolver for the permission field.
func (r *slackConnectionResolver) Permission(ctx context.Context, obj *types.SlackConnection, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// Connector returns schema.ConnectorResolver implementation.
func (r *Resolver) Connector() schema.ConnectorResolver { return &connectorResolver{r} }
// SlackConnection returns schema.SlackConnectionResolver implementation.
func (r *Resolver) SlackConnection() schema.SlackConnectionResolver {
return &slackConnectionResolver{r}
}
type connectorResolver struct{ *Resolver }
type slackConnectionResolver struct{ *Resolver }