package protocol import ( "path" "strings" ) const ( SharedSpace = "shared" branchPrefix = "branch:" MaxBlobSize = 5 << 20 ) type File struct { Hash string `json:"hash"` Time int64 `json:"time"` } type Manifest map[string]File type State struct { Seq int64 `json:"seq"` Spaces map[string]Manifest `json:"spaces"` } type Change struct { Space string `json:"space"` Path string `json:"path"` Base string `json:"base"` Hash string `json:"hash"` } type Push struct { Name string `json:"name"` Author string `json:"author,omitempty"` MainSHA string `json:"main_sha"` MainBranch string `json:"main_branch"` Changes []Change `json:"changes"` } type Revision struct { Seq int64 `json:"seq"` Machine string `json:"machine"` Author string `json:"author"` Time int64 `json:"time"` MainSHA string `json:"main_sha"` MainBranch string `json:"main_branch"` Changes []Change `json:"changes"` } type Repo struct { Key string `json:"key"` Name string `json:"name"` Seq int64 `json:"seq"` Time int64 `json:"time"` } type Machine struct { ID int64 `json:"id"` Name string `json:"name"` CreatedAt int64 `json:"created_at"` LastPush int64 `json:"last_push"` LastSeen int64 `json:"last_seen"` Online bool `json:"online"` Revisions int64 `json:"revisions"` } type Login struct { Password string `json:"password"` } type Event struct { Repo string `json:"repo"` Seq int64 `json:"seq"` Author string `json:"author,omitempty"` } type ClaimRequest struct { Code string `json:"code"` Name string `json:"name"` } type ClaimResponse struct { Token string `json:"token"` } type CodeResponse struct { Code string `json:"code"` Command string `json:"command"` RemoteCommand string `json:"remote_command"` ExpiresAt int64 `json:"expires_at"` } func BranchSpace(branch string) string { return branchPrefix + branch } func ValidSpace(space string) bool { return space == SharedSpace || len(space) > len(branchPrefix) && strings.HasPrefix(space, branchPrefix) } func SafePath(p string) bool { if p == "" || path.IsAbs(p) || path.Clean(p) != p || strings.ContainsAny(p, "\\\x00") { return false } first, _, _ := strings.Cut(p, "/") return first != ".." && first != "." && !strings.EqualFold(first, ".git") }