Documentation
¶
Overview ¶
Package github implements the optional "Connect with GitHub" flow: a standard OAuth web flow plus the small slice of the GitHub API Mooring needs to make connecting a (private) repo a one-click affair — list the operator's repos and install a READ-ONLY deploy key — so nobody ever pastes a key by hand.
Design notes that keep this safe:
- The OAuth token is used ONLY to list repos and install a per-repo deploy key. Day-to-day fetching uses that repo-scoped, read-only deploy key over SSH with a PINNED known_hosts (see KnownHosts) — never the broad token.
- Every network call goes through an injected httpDoer with an explicit base URL, so the whole client is unit-testable offline against an httptest server.
- Errors never include the token or response bodies that might echo it.
Index ¶
- Constants
- Variables
- type Client
- func (c *Client) AuthorizeURL(clientID, redirectURI, state string) string
- func (c *Client) CreateDeployKey(ctx context.Context, token, owner, repo, title, pubLine string) error
- func (c *Client) ExchangeCode(ctx context.Context, clientID, clientSecret, code, redirectURI string) (string, error)
- func (c *Client) ListRepos(ctx context.Context, token string) ([]Repo, error)
- func (c *Client) Viewer(ctx context.Context, token string) (string, error)
- type DeployKey
- type Repo
Constants ¶
const ( // DefaultAPIBase / DefaultOAuthBase are the public GitHub endpoints (overridable // for GitHub Enterprise or tests). DefaultAPIBase = "https://api.github.com" DefaultOAuthBase = "https://github.com" // Scope needed to list private repos and install a deploy key on them. (OAuth Apps // don't offer a finer grain; GitHub Apps would, at the cost of a heavier setup.) Scope = "repo" )
const KnownHosts = `` /* 827-byte string literal not displayed */
KnownHosts pins GitHub's published SSH host keys (from https://api.github.com/meta). Deploy-key fetches use this with StrictHostKeyChecking, so a connected repo can never be MITM'd into handing Mooring a malicious tree.
Variables ¶
var ErrKeyExists = errors.New("github: deploy key already exists")
ErrKeyExists means an identical deploy key is already installed (treat as success).
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client talks to GitHub. Construct with New.
func (*Client) AuthorizeURL ¶
AuthorizeURL builds the URL to send the operator's browser to. state is an unguessable value the caller also stores (in a cookie) and re-checks on the callback, defeating cross-site request forgery of the OAuth flow.
func (*Client) CreateDeployKey ¶
func (c *Client) CreateDeployKey(ctx context.Context, token, owner, repo, title, pubLine string) error
CreateDeployKey installs a READ-ONLY deploy key on owner/repo. title is a human label; pubLine is an authorized_keys line. It is idempotent-ish: GitHub rejects a duplicate key with 422, which the caller can treat as already-installed.
func (*Client) ExchangeCode ¶
func (c *Client) ExchangeCode(ctx context.Context, clientID, clientSecret, code, redirectURI string) (string, error)
ExchangeCode swaps the OAuth callback code for an access token.
type DeployKey ¶
type DeployKey struct {
PrivatePEM string // OpenSSH "BEGIN OPENSSH PRIVATE KEY" PEM
PublicLine string // "ssh-ed25519 AAAA... <comment>"
}
DeployKey is a freshly generated ed25519 keypair for one repository: the private half (OpenSSH PEM) Mooring keeps encrypted and fetches with, and the public half (authorized_keys line) installed on the repo as a READ-ONLY deploy key.
func GenerateDeployKey ¶
GenerateDeployKey makes a new ed25519 deploy keypair. comment is a human label embedded in both halves (e.g. "mooring:my-app"). ed25519 is small, fast, and the modern default — no key-size choices to get wrong.
type Repo ¶
type Repo struct {
FullName string `json:"full_name"` // owner/name
Name string `json:"name"`
Private bool `json:"private"`
DefaultBranch string `json:"default_branch"`
SSHURL string `json:"ssh_url"`
Owner struct {
Login string `json:"login"`
} `json:"owner"`
}
Repo is one repository in the picker.