Documentation
¶
Overview ¶
Package githubapp authenticates GitHub API calls as the *viewing user* via the GitHub App's user-authorization (user-to-server) flow, rather than as the app installation. This means commit data the dashboard surfaces is scoped to what each user can actually see on GitHub — a user with no access to a repo gets a 404, never someone else's private history.
The app itself is identified by GITHUB_APP_CLIENT_ID / GITHUB_APP_CLIENT_SECRET. Tokens are non-expiring user access tokens (the app must have token expiry disabled) and are held in an httpOnly cookie by the caller, never server-side.
Index ¶
- func AuthorizeURL(redirectURI, state string) string
- func Configured() bool
- func ExchangeCode(ctx context.Context, code, redirectURI string) (string, error)
- func NormalizedRepoKey(owner, repo string) string
- func ParseRepoURL(url string) (owner, repo string, ok bool)
- func SetBaseURLForTest(baseURL string) func()
- func UserClient(token string) (*github.Client, error)
- type AuthenticatedUser
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AuthorizeURL ¶
AuthorizeURL builds the GitHub user-authorization redirect the browser is sent to when the user clicks "Connect GitHub". redirectURI must match a callback URL registered on the GitHub App; state is an opaque CSRF token echoed back to the callback. GitHub App user tokens derive access from the app's permissions intersected with the user's — no OAuth scope param is used.
func Configured ¶
func Configured() bool
Configured reports whether the GitHub App user-OAuth env vars are set.
func ExchangeCode ¶
ExchangeCode swaps the authorization code from the callback for a user access token, authenticating the exchange with the app's client id + secret.
func NormalizedRepoKey ¶ added in v0.9.1
NormalizedRepoKey builds the canonical, case-insensitive "owner/repo" comparison key used to match a requested :owner/:repo against the repos ParseRepoURL extracts from rollout status.source values — lowercase, dots preserved, so "Owner/Foo.js" and "owner/foo.js" compare equal. This is the one repo-normalisation rule the GitHub pull-request endpoint uses on the Go side; the frontend's normalizeSource (lib/version-utils.ts) applies the equivalent rule (lowercase, strip trailing .git, ignore /tree/<branch> tails, keep dots) independently, since it normalises full source strings rather than already-split owner/repo pairs.
func ParseRepoURL ¶
ParseRepoURL extracts owner/repo from a GitHub URL in any common form (https://github.com/owner/repo, https://github.com/owner/repo.git, git@github.com:owner/repo.git). Returns ok=false if the URL isn't a recognizable GitHub repo URL.
func SetBaseURLForTest ¶ added in v0.9.1
func SetBaseURLForTest(baseURL string) func()
SetBaseURLForTest points every UserClient built while active at baseURL (must be a full URL ending in "/"). Returns a restore func; tests are expected to run sequentially (this is a package-level var, not goroutine-safe against concurrent tests setting it).
func UserClient ¶
UserClient returns a github client that acts as the user who owns token.
⭐ EVERY GET THIS CLIENT MAKES IS CONDITIONAL. `githubcache.Shared()` is the client's transport, so a repeat question carries the stored `ETag` and comes back `304 Not Modified` — which GitHub does not charge to the rate limit — instead of re-downloading a comparison the dashboard already has.
⚠️ THE ORDER OF THESE TWO OPTIONS IS THE SECURITY PROPERTY, not a style choice. go-github's `newClient` installs `WithTransport` first and then wraps it with the token setter, so the cache sees each request WITH its final `Authorization` header and partitions on it. A cache placed above the auth layer would file every user's private answers under one key. See the package comment on `pkg/githubcache`.
Types ¶
type AuthenticatedUser ¶
AuthenticatedUser looks up the login + avatar for a token, used to render the connected identity and to validate that a stored token is still good.
func CurrentUser ¶
func CurrentUser(ctx context.Context, token string) (*AuthenticatedUser, error)
CurrentUser calls /user with the token. Returns an error if the token is invalid/revoked, which the caller treats as "not connected".