Extend the OAuth2 connector so a reconnect can request the union of previously granted and newly requested scopes without losing either. Four related changes: - Connection gains Scopes() []string so callers no longer need a type switch to reach the scope set. OAuth2Connection and APIKeyConnection implement it; SlackConnection inherits via embedding. - OAuth2State carries RequestedScopes and CompleteWithState falls back to it when the provider omits the scope field (RFC 6749 §5.1 allows this when granted equals requested). Without the fallback the stored Scope would be empty and the next reconnect would have no diff base. - providerDefinition gains SupportsIncrementalAuth, set only for Google Workspace. When the flag is true and the caller passes InitiateOptions.IncludeGrantedScopes, the auth URL carries include_granted_scopes=true and the prompt=consent param is dropped so reuse flows see only the delta consent screen. - InitiateOptions gains ConnectorID so the reconnect case is passed explicitly instead of relying on the caller to mutate r.URL.Query. Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
|
//
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
// copyright notice and this permission notice appear in all copies.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
// PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
package connector
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"go.gearno.de/kit/httpclient"
|
|
)
|
|
|
|
type APIKeyConnection struct {
|
|
APIKey string `json:"api_key"`
|
|
}
|
|
|
|
var _ Connection = (*APIKeyConnection)(nil)
|
|
|
|
func (c *APIKeyConnection) Type() ProtocolType {
|
|
return ProtocolAPIKey
|
|
}
|
|
|
|
func (c *APIKeyConnection) Scopes() []string {
|
|
return nil
|
|
}
|
|
|
|
func (c *APIKeyConnection) Client(ctx context.Context) (*http.Client, error) {
|
|
transport := &oauth2Transport{
|
|
token: c.APIKey,
|
|
tokenType: "Bearer",
|
|
underlying: httpclient.DefaultPooledTransport(),
|
|
}
|
|
return &http.Client{Transport: transport}, nil
|
|
}
|
|
|
|
func (c APIKeyConnection) MarshalJSON() ([]byte, error) {
|
|
type Alias APIKeyConnection
|
|
return json.Marshal(&struct {
|
|
Type string `json:"type"`
|
|
Alias
|
|
}{
|
|
Type: string(ProtocolAPIKey),
|
|
Alias: Alias(c),
|
|
})
|
|
}
|
|
|
|
func (c *APIKeyConnection) UnmarshalJSON(data []byte) error {
|
|
type Alias APIKeyConnection
|
|
aux := &struct {
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(c),
|
|
}
|
|
return json.Unmarshal(data, &aux)
|
|
}
|