Gitfed
bastien-mrq/gitfed / internal / adminrpc / protocol.go
// Package adminrpc lets gitfed-tui drive a *running* gitfed-server over a
// local Unix socket, implementing admin.Ops on the client side. This exists
// because the store (bbolt) takes an exclusive file lock: only one OS
// process can hold it open, so a separate CLI/TUI process can't just open
// the same database file while the server is up. Routing admin operations
// through the server process that already owns the store sidesteps that
// entirely.
package adminrpc

import (
	"git.neuromancer.ovh/bastien-mrq/gitfed/internal/gitexec"
	"git.neuromancer.ovh/bastien-mrq/gitfed/internal/store"
)

// method names
const (
	methodListUsers          = "ListUsers"
	methodCreateUser         = "CreateUser"
	methodAddUserKey         = "AddUserKey"
	methodRemoveUserKey      = "RemoveUserKey"
	methodDeleteUser         = "DeleteUser"
	methodListRepos          = "ListRepos"
	methodGetRepo            = "GetRepo"
	methodCreateRepo         = "CreateRepo"
	methodImportRepo         = "ImportRepo"
	methodDeleteRepo         = "DeleteRepo"
	methodGetACL             = "GetACL"
	methodGrantCollaborator  = "GrantCollaborator"
	methodRevokeCollaborator = "RevokeCollaborator"
	methodListTrustedCAs     = "ListTrustedCAs"
	methodCountPendingTrust  = "CountPendingTrust"
	methodApproveDomain      = "ApproveDomain"
	methodListAudit          = "ListAudit"
	methodSetRepoPublic      = "SetRepoPublic"
	methodSetRepoTopics      = "SetRepoTopics"
	methodSetRepoDescription = "SetRepoDescription"
	methodGetRepoReadme      = "GetRepoReadme"
	methodListReadmeLangs    = "ListRepoReadmeLanguages"
	methodGetRepoReadmeLang  = "GetRepoReadmeLang"
	methodGetRepoLicense     = "GetRepoLicense"
	methodListRepoTags       = "ListRepoTags"
	methodGetRepoArchive     = "GetRepoArchive"
	methodListRepoTree       = "ListRepoTree"
	methodListRepoTreeAtRef  = "ListRepoTreeAtRef"
	methodGetRepoFile        = "GetRepoFile"
	methodGetRepoFileAtRef   = "GetRepoFileAtRef"
	methodGetRepoBranch      = "GetRepoBranch"
	methodGetUser            = "GetUser"
	methodSetUserAdmin       = "SetUserAdmin"
	methodSetUserBio         = "SetUserBio"
	methodSetPassword        = "SetPassword"
	methodVerifyPassword     = "VerifyPassword"
	methodCreateSession      = "CreateSession"
	methodGetSession         = "GetSession"
	methodDeleteSession      = "DeleteSession"
	methodCheckAccess        = "CheckAccess"
	methodListCommits        = "ListCommits"
	methodListCommitsPage    = "ListCommitsPage"
	methodCountCommits       = "CountCommits"
	methodCountContributors  = "CountContributors"
	methodDominantLanguage   = "DominantLanguage"
	methodRepoDiskUsage      = "RepoDiskUsage"
	methodShowCommit         = "ShowCommit"
	methodCommitDiff         = "CommitDiff"
	methodListBranches       = "ListBranches"

	methodCreateMergeRequest         = "CreateMergeRequest"
	methodListMergeRequests          = "ListMergeRequests"
	methodGetMergeRequest            = "GetMergeRequest"
	methodMergeRequestDiff           = "MergeRequestDiff"
	methodCheckMergeRequestMergeable = "CheckMergeRequestMergeable"
	methodMergeMergeRequest          = "MergeMergeRequest"
	methodCloseMergeRequest          = "CloseMergeRequest"
	methodListMRComments             = "ListMRComments"
	methodAddMRComment               = "AddMRComment"

	methodPinRepo             = "PinRepo"
	methodUnpinRepo           = "UnpinRepo"
	methodListPinnedRepos     = "ListPinnedRepos"
	methodListNotifications   = "ListNotifications"
	methodCountPendingNotifs  = "CountPendingNotifications"
	methodAcceptNotification  = "AcceptNotification"
	methodDismissNotification = "DismissNotification"
)

// request is the envelope sent by the client for every call.
type request struct {
	Method string `json:"method"`
	Args   any    `json:"args,omitempty"`
}

// response is the envelope returned by the server for every call.
type response struct {
	Result any    `json:"result,omitempty"`
	Error  string `json:"error,omitempty"`
}

type userKeyArgs struct {
	Username string `json:"username"`
	PubKey   string `json:"pub_key"`
}

type nameArgs struct {
	Name string `json:"name"`
}

type createRepoArgs struct {
	Name  string `json:"name"`
	Owner string `json:"owner"`
}

type importRepoArgs struct {
	Name      string `json:"name"`
	SourceURL string `json:"source_url"`
	Owner     string `json:"owner"`
}

type collaboratorArgs struct {
	Repo      string     `json:"repo"`
	Principal string     `json:"principal"`
	Actor     string     `json:"actor,omitempty"`
	Role      store.Role `json:"role,omitempty"`
}

type domainArgs struct {
	Domain string `json:"domain"`
}

type listUsersResult struct {
	Users []store.User `json:"users"`
}

type listReposResult struct {
	Repos []store.Repo `json:"repos"`
}

type listTrustResult struct {
	Trust []store.TrustedCA `json:"trust"`
}

type limitArgs struct {
	Limit int `json:"limit"`
}

type listAuditResult struct {
	Events []store.AuditEvent `json:"events"`
}

type setPublicArgs struct {
	Name   string `json:"name"`
	Public bool   `json:"public"`
}

type setTopicsArgs struct {
	Name   string   `json:"name"`
	Topics []string `json:"topics"`
}

type setDescriptionArgs struct {
	Name        string `json:"name"`
	Description string `json:"description"`
}

type archiveArgs struct {
	Name   string `json:"name"`
	Ref    string `json:"ref"`
	Format string `json:"format"`
}

// archiveResult's Data is base64-encoded automatically by encoding/json
// (the standard behavior for a []byte field) — see gitexec.go's
// archiveMaxBytes comment for why this stays a single buffered response
// rather than a streamed one.
type archiveResult struct {
	Data []byte `json:"data"`
}

type readmeResult struct {
	Content string `json:"content"`
	Found   bool   `json:"found"`
}

type nameLangArgs struct {
	Name string `json:"name"`
	Lang string `json:"lang"`
}

type readmeLangsResult struct {
	Langs []string `json:"langs"`
}

type licenseResult struct {
	Content  string `json:"content"`
	Filename string `json:"filename"`
	Found    bool   `json:"found"`
}

type listTagsResult struct {
	Tags []string `json:"tags"`
}

type pathArgs struct {
	Name string `json:"name"`
	Path string `json:"path"`
}

type pathRefArgs struct {
	Name string `json:"name"`
	Ref  string `json:"ref"`
	Path string `json:"path"`
}

type listTreeResult struct {
	Entries []gitexec.TreeEntry `json:"entries"`
	Found   bool                `json:"found"`
}

type fileResult struct {
	Content string `json:"content"`
	Found   bool   `json:"found"`
}

type branchResult struct {
	Branch string `json:"branch"`
	Found  bool   `json:"found"`
}

type countFoundResult struct {
	Count int  `json:"count"`
	Found bool `json:"found"`
}

type languageResult struct {
	Language string `json:"language"`
	Found    bool   `json:"found"`
}

type diskUsageResult struct {
	Bytes int64 `json:"bytes"`
}

type userResult struct {
	User store.User `json:"user"`
}

type setAdminArgs struct {
	Username string `json:"username"`
	IsAdmin  bool   `json:"is_admin"`
}

type setBioArgs struct {
	Username string `json:"username"`
	Bio      string `json:"bio"`
}

type setPasswordArgs struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

type verifyPasswordResult struct {
	IsAdmin bool `json:"is_admin"`
	OK      bool `json:"ok"`
}

type createSessionArgs struct {
	Principal string `json:"principal"`
	Username  string `json:"username"`
	IsAdmin   bool   `json:"is_admin"`
}

type createSessionResult struct {
	Token string `json:"token"`
}

type tokenArgs struct {
	Token string `json:"token"`
}

type sessionResult struct {
	Session store.Session `json:"session"`
}

type checkAccessArgs struct {
	Repo      string     `json:"repo"`
	Principal string     `json:"principal"`
	Want      store.Role `json:"want"`
}

type checkAccessResult struct {
	Role store.Role `json:"role"`
	OK   bool       `json:"ok"`
}

type pinArgs struct {
	Principal string `json:"principal"`
	Domain    string `json:"domain"`
	Repo      string `json:"repo"`
	Label     string `json:"label,omitempty"`
}

type principalArgs struct {
	Principal string `json:"principal"`
}

type listPinsResult struct {
	Pins []store.PinnedRepo `json:"pins"`
}

type listNotifsResult struct {
	Notifications []store.Notification `json:"notifications"`
}

type countResult struct {
	Count int `json:"count"`
}

type notificationIDArgs struct {
	Principal string `json:"principal"`
	ID        string `json:"id"`
}

type nameLimitArgs struct {
	Name  string `json:"name"`
	Limit int    `json:"limit"`
}

type nameLimitOffsetArgs struct {
	Name   string `json:"name"`
	Limit  int    `json:"limit"`
	Offset int    `json:"offset"`
}

type listCommitsResult struct {
	Commits []gitexec.Commit `json:"commits"`
	Found   bool             `json:"found"`
}

type nameHashArgs struct {
	Name string `json:"name"`
	Hash string `json:"hash"`
}

type showCommitResult struct {
	Detail gitexec.CommitDetail `json:"detail"`
	Found  bool                 `json:"found"`
}

type commitDiffResult struct {
	Diff      string `json:"diff"`
	Truncated bool   `json:"truncated"`
}

type listBranchesResult struct {
	Branches []string `json:"branches"`
}

type createMRArgs struct {
	Repo         string `json:"repo"`
	Title        string `json:"title"`
	Description  string `json:"description"`
	Author       string `json:"author"`
	SourceBranch string `json:"source_branch"`
	TargetBranch string `json:"target_branch"`
}

type mrArgs struct {
	Repo   string `json:"repo"`
	Number int    `json:"number"`
}

type mergeMRArgs struct {
	Repo   string `json:"repo"`
	Number int    `json:"number"`
	Actor  string `json:"actor"`
}

type mrResult struct {
	MR store.MergeRequest `json:"mr"`
}

type listMRResult struct {
	MRs []store.MergeRequest `json:"mrs"`
}

type mrDiffResult struct {
	Files     []gitexec.DiffFile `json:"files"`
	Diff      string             `json:"diff"`
	Truncated bool               `json:"truncated"`
	Found     bool               `json:"found"`
}

type mergeResultRPC struct {
	Result gitexec.MergeResult `json:"result"`
}

type mergeMRResult struct {
	MR     store.MergeRequest  `json:"mr"`
	Result gitexec.MergeResult `json:"result"`
}

type mrCommentArgs struct {
	Repo   string `json:"repo"`
	Number int    `json:"number"`
	Author string `json:"author"`
	Body   string `json:"body"`
}

type listMRCommentsResult struct {
	Comments []store.MRComment `json:"comments"`
}

type addMRCommentResult struct {
	Comment store.MRComment `json:"comment"`
}