Documentation
¶
Overview ¶
Package githubid manages the daemon's set of GitHub identities: named (login, host, token) triples that islands clone and push as. The daemon is the credential owner, so islands work from any client device — including ones with no gh of their own. A client that does have gh can seed the store with `dejima auth push --github`. Each island selects one identity (or the default) at create time; the daemon materializes just that identity into the island's gh config (see HostsYAML), never the whole set.
Index ¶
- Constants
- func ConfigYAML() string
- func GitAuthor(id Identity) (name, email string)
- func GitConfig(id Identity) string
- func HostsYAML(id Identity) string
- func VerifyToken(ctx context.Context, host, token string) (login string, id int64, err error)
- type Identity
- type Meta
- type Repo
- type RepoList
- type Store
Constants ¶
const DefaultHost = "github.com"
DefaultHost is the GitHub host assumed when an identity doesn't name one.
Variables ¶
This section is empty.
Functions ¶
func ConfigYAML ¶
func ConfigYAML() string
ConfigYAML renders the gh config.yml that accompanies HostsYAML. Its only job is to carry the schema version marker: with it present, gh treats the materialized config as already-migrated and never tries to write to the read-only GH_CONFIG_DIR mount. Without it, gh runs a migration on first use and fails on the read-only dir (see HostsYAML).
func GitAuthor ¶
GitAuthor derives the git commit author (name, email) for an island that acts as this identity. Without it, commits inherit the host's gitconfig user.* — so a push authenticated as "work" gets authored with whatever email the daemon host happens to have, which GitHub then misattributes (it keys attribution off the email). We use GitHub's privacy-preserving noreply email so commits attribute to the right account without exposing a real address:
- canonical form (preferred): "<id>+<login>@users.noreply.<host>"
- fallback when the numeric id is unknown (identity stored before id capture): "<login>@users.noreply.<host>" — still account-linked, just the older form.
func GitConfig ¶
GitConfig renders a minimal gitconfig carrying just the identity's commit author. The daemon mounts this at /opt/host/gitconfig for identity-scoped islands (in place of the host's own gitconfig), and the entrypoint applies user.name/user.email from it — so authorship matches the push credential.
func HostsYAML ¶
HostsYAML renders the gh hosts.yml for a single identity — what gh reads from GH_CONFIG_DIR to authenticate git over HTTPS inside an island. Only ever one identity per file.
It MUST emit the modern multi-account schema (the per-user `users:` map), not just the legacy top-level form. gh migrates a legacy-only hosts.yml to this schema on first use, which means writing back to GH_CONFIG_DIR — but the daemon mounts that dir read-only, so the migration fails and `gh auth setup-git` errors out, leaving the island with no git credential helper (the clone then can't authenticate). Materializing the already-migrated form means gh has nothing to write. See also ConfigYAML, which supplies the version marker gh checks before deciding to migrate.
func VerifyToken ¶
VerifyToken confirms a token authenticates against host and returns the login and numeric user id it belongs to. Called before storing an identity so a bad or expired token fails fast at `auth push` time instead of silently at clone/push time inside an island. The id feeds the canonical noreply commit email (see GitAuthor).
Types ¶
type Identity ¶
type Identity struct {
Name string `json:"name"` // dejima-local handle: "work", "personal", …
Login string `json:"login"` // GitHub username
ID int64 `json:"id,omitempty"` // GitHub numeric user id (for the canonical noreply commit email); 0 if unknown
Host string `json:"host"` // "github.com" or an enterprise host
Token string `json:"token"` // OAuth/PAT token — secret, never returned to clients
}
Identity is one GitHub login the daemon can act as.
type Meta ¶
type Meta struct {
Name string `json:"name"`
Login string `json:"login"`
Host string `json:"host"`
Default bool `json:"default"`
}
Meta is an identity without its token: the safe view to hand back to clients.
type Repo ¶
type Repo struct {
NameWithOwner string `json:"name_with_owner"`
URL string `json:"url"` // https clone URL
Description string `json:"description"`
Private bool `json:"private"`
}
Repo is one repository visible to an identity, in the shape the island creator consumes: a full owner/name and the https clone URL.
type RepoList ¶
RepoList is a page of repositories plus whether the identity can see more than the page returned (the GitHub API advertises a next page via a Link header). Capped lets the UI say "showing the first N" honestly.
type Store ¶
type Store struct {
Default string `json:"default"`
Identities map[string]Identity `json:"identities"`
}
Store is the per-daemon identity set with one default.
func Load ¶
Load reads the store under the lock — a consistent snapshot for read-only use. Returns an empty (non-nil) store if none exists yet.
func Update ¶
Update runs fn against the store under a process-wide lock and persists the result atomically. Use it for every read-modify-write — Put/Remove/SetDefault — so concurrent writers can't clobber each other (lost updates).
func (*Store) Put ¶
Put adds or updates an identity (keyed by Name). The first identity added becomes the default.
func (*Store) Remove ¶
Remove deletes an identity. If it was the default, the default falls to the first remaining identity (by name), or is cleared when none remain.
func (*Store) Resolve ¶
Resolve returns the identity for name, or the default when name is empty. ok is false when nothing matches (unknown name, or empty name with no default).
func (*Store) SetDefault ¶
SetDefault marks name as the default identity.