Files
kandev/apps/backend/internal/github/app_credential_provider.go
T

58 lines
2.0 KiB
Go

package github
import (
"context"
"errors"
)
// CachedInstallationCredentialProvider resolves short-lived installation
// tokens without exposing App private-key material to callers or executors.
type CachedInstallationCredentialProvider struct {
tokens *InstallationTokenCache
}
func NewCachedInstallationCredentialProvider(tokens *InstallationTokenCache) *CachedInstallationCredentialProvider {
return &CachedInstallationCredentialProvider{tokens: tokens}
}
func (p *CachedInstallationCredentialProvider) ResolveInstallation(
ctx context.Context,
connection *WorkspaceConnection,
req ResolveCredentialRequest,
) (*ResolvedCredential, error) {
if p == nil || p.tokens == nil {
return nil, ErrGitHubNotConfigured
}
if connection == nil || connection.InstallationID == nil || *connection.InstallationID <= 0 {
return nil, errors.New("GitHub App installation connection is missing an installation ID")
}
if p.tokens.registrationID != "" && connection.AppRegistrationID != p.tokens.registrationID {
return nil, ErrGitHubNotConfigured
}
var repositories []string
if req.RepoName != "" {
repositories = []string{req.RepoName}
}
token, err := p.tokens.GetForWorkspace(
ctx, connection.WorkspaceID, *connection.InstallationID, nil, repositories,
)
if err != nil {
return nil, err
}
tracker := NewRateTracker(nil, nil)
client := NewTokenClient(token.Token, token.Principal).WithRateTracker(tracker)
return &ResolvedCredential{
Client: client,
Principal: AuthPrincipal{
Kind: AuthPrincipalApp, Source: ConnectionSourceGitHubAppInstallation,
Login: connection.InstallationAccountLogin, InstallationID: *connection.InstallationID,
AppRegistrationID: p.tokens.registrationID,
AppCredentialGeneration: p.tokens.credentialGeneration,
},
Capabilities: CapabilitiesForPermissions(token.Permissions), ExpiresAt: token.ExpiresAt,
AppRegistrationID: p.tokens.registrationID,
AppCredentialGeneration: p.tokens.credentialGeneration,
RateTracker: tracker, credential: token.Token,
}, nil
}