Documentation
¶
Index ¶
- Constants
- Variables
- func ScrubOAuthCallbackURL(request *http.Request) (code, state string, err error)
- type AuthorizedGitHubRepository
- func (r *AuthorizedGitHubRepository) CreateCommitOnBranch(ctx context.Context, branch, expectedHeadOID, message string, ...) (GitHubCommit, error)
- func (r *AuthorizedGitHubRepository) GetBlob(ctx context.Context, blobOID string) ([]byte, error)
- func (r *AuthorizedGitHubRepository) GetCommit(ctx context.Context, oid string) (GitHubCommit, error)
- func (r *AuthorizedGitHubRepository) GetRef(ctx context.Context, branch string) (GitHubRef, error)
- func (r *AuthorizedGitHubRepository) GetTree(ctx context.Context, treeOID string) ([]GitHubTreeEntry, error)
- func (r *AuthorizedGitHubRepository) ListBranches(ctx context.Context) ([]GitHubBranch, error)
- func (r *AuthorizedGitHubRepository) Scope() RepositoryScope
- func (r *AuthorizedGitHubRepository) UpdateRefs(ctx context.Context, updates []GitHubRefUpdate) error
- type CredentialStore
- type GitHubActor
- type GitHubAppClient
- func (c *GitHubAppClient) AuthorizationURL(state, codeChallenge string, repositoryID int64) (string, error)
- func (c *GitHubAppClient) Exchange(ctx context.Context, code, verifier string) (OAuthTokens, error)
- func (c *GitHubAppClient) Refresh(ctx context.Context, refreshToken string) (OAuthTokens, error)
- func (c *GitHubAppClient) ScopedHTTPClient(tokens OAuthTokens, repo RepositoryRef, nodeID string, ...) *http.Client
- func (c *GitHubAppClient) String() string
- func (c *GitHubAppClient) UserClient(tokens OAuthTokens) repositoryUserClient
- type GitHubAppConfig
- type GitHubAppInstallationAuthorizer
- type GitHubAppRepositoryAccess
- type GitHubBranch
- type GitHubCommit
- type GitHubFileChange
- type GitHubRef
- type GitHubRefUpdate
- type GitHubRepository
- type GitHubRepositoryPermissions
- type GitHubTreeEntry
- type InstallationAuthorizer
- type OAuthTokens
- type Provider
- func (p *Provider) AuthorizeRepository(ctx context.Context, firebaseUID string, repoRef RepositoryRef, ...) (*AuthorizedGitHubRepository, error)
- func (p *Provider) BeginAuthorization(ctx context.Context, firebaseUID string) (string, error)
- func (p *Provider) BeginRepositoryAuthorization(ctx context.Context, firebaseUID string, repo RepositoryRef) (string, error)
- func (p *Provider) CompleteAuthorization(ctx context.Context, firebaseUID, state, code string) error
- func (p *Provider) ListRepositories(ctx context.Context, firebaseUID string) ([]GitHubRepository, error)
- func (p *Provider) ResolveRepositoryByName(ctx context.Context, firebaseUID, owner, name string) (GitHubRepository, error)
- func (p *Provider) String() string
- type ProviderOptions
- type RepositoryOperation
- type RepositoryRef
- type RepositoryScope
Constants ¶
const ( DataTugGitHubAppSlug = "datatug" DataTugGitHubAppID = int64(5223634) )
Variables ¶
var ( ErrCredentialMissing = errors.New("GitHub connection is missing") ErrCredentialChanged = errors.New("GitHub connection changed during refresh") ErrRefreshInProgress = errors.New("GitHub token refresh is in progress") ErrOAuthStateInvalid = errors.New("GitHub OAuth state is invalid or expired") )
var ( ErrGitHubAppNotConfigured = errors.New("DataTug GitHub App authorization is not configured") ErrGitHubActorMismatch = errors.New("GitHub account does not match the connected Firebase user") ErrGitHubRepositoryDenied = errors.New("GitHub repository is not authorized") ErrGitHubPermissionDenied = errors.New("GitHub user does not have the required repository permission") )
Functions ¶
func ScrubOAuthCallbackURL ¶
ScrubOAuthCallbackURL must be the first callback-handler operation. It extracts the one-time code/state in memory, then removes every query value from both URL representations before application logging or routing.
Types ¶
type AuthorizedGitHubRepository ¶
type AuthorizedGitHubRepository struct {
// contains filtered or unexported fields
}
AuthorizedGitHubRepository is an ephemeral, actor-bound API client. The underlying user token remains private in the transport and the client is restricted to the selected repository and operation permission.
func (*AuthorizedGitHubRepository) CreateCommitOnBranch ¶
func (r *AuthorizedGitHubRepository) CreateCommitOnBranch(ctx context.Context, branch, expectedHeadOID, message string, changes []GitHubFileChange) (GitHubCommit, error)
func (*AuthorizedGitHubRepository) GetCommit ¶
func (r *AuthorizedGitHubRepository) GetCommit(ctx context.Context, oid string) (GitHubCommit, error)
func (*AuthorizedGitHubRepository) GetTree ¶
func (r *AuthorizedGitHubRepository) GetTree(ctx context.Context, treeOID string) ([]GitHubTreeEntry, error)
GetTree returns all descendants of treeOID, recursively. A truncated GitHub response is an error.
func (*AuthorizedGitHubRepository) ListBranches ¶
func (r *AuthorizedGitHubRepository) ListBranches(ctx context.Context) ([]GitHubBranch, error)
func (*AuthorizedGitHubRepository) Scope ¶
func (r *AuthorizedGitHubRepository) Scope() RepositoryScope
func (*AuthorizedGitHubRepository) UpdateRefs ¶
func (r *AuthorizedGitHubRepository) UpdateRefs(ctx context.Context, updates []GitHubRefUpdate) error
type CredentialStore ¶
type CredentialStore struct {
// contains filtered or unexported fields
}
CredentialStore persists only purpose-encrypted GitHub tokens. Refresh state is updated in DAL transactions so concurrent Cloud API instances cannot both consume the same rotating refresh token.
type GitHubActor ¶
type GitHubAppClient ¶
type GitHubAppClient struct {
// contains filtered or unexported fields
}
func NewGitHubAppClient ¶
func NewGitHubAppClient(config GitHubAppConfig, client *http.Client) (*GitHubAppClient, error)
func (*GitHubAppClient) AuthorizationURL ¶
func (c *GitHubAppClient) AuthorizationURL(state, codeChallenge string, repositoryID int64) (string, error)
func (*GitHubAppClient) Exchange ¶
func (c *GitHubAppClient) Exchange(ctx context.Context, code, verifier string) (OAuthTokens, error)
func (*GitHubAppClient) Refresh ¶
func (c *GitHubAppClient) Refresh(ctx context.Context, refreshToken string) (OAuthTokens, error)
func (*GitHubAppClient) ScopedHTTPClient ¶
func (c *GitHubAppClient) ScopedHTTPClient(tokens OAuthTokens, repo RepositoryRef, nodeID string, operation RepositoryOperation) *http.Client
func (*GitHubAppClient) String ¶
func (c *GitHubAppClient) String() string
func (*GitHubAppClient) UserClient ¶
func (c *GitHubAppClient) UserClient(tokens OAuthTokens) repositoryUserClient
type GitHubAppConfig ¶
type GitHubAppConfig struct {
AppID int64
ClientID string
ClientSecret string
PrivateKeyPEM []byte
CallbackURL string
}
GitHubAppConfig contains server-side settings for the existing DataTug GitHub App. Secret values are accepted only by the server and are never persisted by this package.
type GitHubAppInstallationAuthorizer ¶
type GitHubAppInstallationAuthorizer struct {
// contains filtered or unexported fields
}
GitHubAppInstallationAuthorizer checks the dedicated DataTug App's current installation for the selected repository. Provider first verifies the immutable repository ID, owner, and name with the GitHub user actor token; this App-JWT request then proves that the same owner/repository path is in the App installation and returns its effective Contents permission.
func NewGitHubAppInstallationAuthorizer ¶
func NewGitHubAppInstallationAuthorizer(appID int64, privateKeyPEM []byte) (*GitHubAppInstallationAuthorizer, error)
func (*GitHubAppInstallationAuthorizer) AuthorizeDataTugAppRepository ¶
func (a *GitHubAppInstallationAuthorizer) AuthorizeDataTugAppRepository(ctx context.Context, repo RepositoryRef) (GitHubAppRepositoryAccess, error)
type GitHubBranch ¶
GitHubBranch is a branch name and its current immutable commit identifier.
type GitHubCommit ¶
type GitHubFileChange ¶
GitHubFileChange adds/replaces a file with raw bytes, or deletes it when Delete is true.
type GitHubRefUpdate ¶
GitHubRefUpdate is an atomic compare-and-swap update for one branch ref.
type GitHubRepository ¶
type GitHubRepository struct {
ID int64
NodeID string
Owner string
Name string
DefaultBranch string
Permissions GitHubRepositoryPermissions
EffectivePermission RepositoryOperation
}
type GitHubTreeEntry ¶
GitHubTreeEntry identifies one path in a complete recursive repository tree.
type InstallationAuthorizer ¶
type InstallationAuthorizer interface {
AuthorizeDataTugAppRepository(context.Context, RepositoryRef) (GitHubAppRepositoryAccess, error)
}
InstallationAuthorizer proves that the existing DataTug GitHub App's selected-repository installation currently includes a project repository. Its adapter may use App authentication, but an installation token is never returned as the project actor.
type OAuthTokens ¶
type OAuthTokens struct {
// contains filtered or unexported fields
}
OAuthTokens exists only in memory. Its string representations and default JSON representation intentionally omit token material.
func (OAuthTokens) GoString ¶
func (OAuthTokens) GoString() string
func (OAuthTokens) MarshalJSON ¶
func (OAuthTokens) MarshalJSON() ([]byte, error)
func (OAuthTokens) String ¶
func (OAuthTokens) String() string
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
func NewProvider ¶
func NewProvider(db dal.DB, config GitHubAppConfig, platformCryptoRoot []byte, installation InstallationAuthorizer, options ProviderOptions) (*Provider, error)
func (*Provider) AuthorizeRepository ¶
func (p *Provider) AuthorizeRepository(ctx context.Context, firebaseUID string, repoRef RepositoryRef, operation RepositoryOperation) (*AuthorizedGitHubRepository, error)
AuthorizeRepository rechecks Firebase UID to GitHub actor binding, selected App installation membership, repository identity, and the requested current permission on every read or write.
func (*Provider) BeginAuthorization ¶
BeginAuthorization connects a GitHub actor before repository selection. The returned URL contains only short-lived state and a PKCE challenge.
func (*Provider) BeginRepositoryAuthorization ¶
func (p *Provider) BeginRepositoryAuthorization(ctx context.Context, firebaseUID string, repo RepositoryRef) (string, error)
BeginRepositoryAuthorization starts a repository-bound reconnection for an already selected project. Initial connection uses BeginAuthorization.
func (*Provider) CompleteAuthorization ¶
func (p *Provider) CompleteAuthorization(ctx context.Context, firebaseUID, state, code string) error
CompleteAuthorization consumes the actor-bound one-time state before exchanging the callback code. Callers must scrub code and state from the callback URL before routing, logging, or analytics.
func (*Provider) ListRepositories ¶
func (p *Provider) ListRepositories(ctx context.Context, firebaseUID string) ([]GitHubRepository, error)
ListRepositories returns only repositories the connected actor can read and the dedicated DataTug App currently has installed. It conveys no mutation authority; project operations still call AuthorizeRepository every time.
func (*Provider) ResolveRepositoryByName ¶ added in v0.17.1
func (p *Provider) ResolveRepositoryByName(ctx context.Context, firebaseUID, owner, name string) (GitHubRepository, error)
ResolveRepositoryByName resolves a selected owner/name through the current connected actor token. The caller must still run the fresh App and operation authorization path using the returned immutable ID.
type ProviderOptions ¶
type RepositoryOperation ¶
type RepositoryOperation string
const ( RepositoryRead RepositoryOperation = "read" RepositoryWrite RepositoryOperation = "write" )
type RepositoryRef ¶
type RepositoryRef struct {
ID int64 `json:"id" firestore:"id"`
Owner string `json:"owner" firestore:"owner"`
Name string `json:"name" firestore:"name"`
}
func (RepositoryRef) Validate ¶
func (r RepositoryRef) Validate() error
type RepositoryScope ¶
type RepositoryScope struct {
FirebaseUID string
Actor GitHubActor
Repository GitHubRepository
Permission RepositoryOperation
}
RepositoryScope returns a value snapshot of the verified actor and immutable repository identity. Mutating the returned value cannot widen the client.