this repo has no description

appview: do /settings/keys + misc cleanups

Changed files
+347 -4
appview
auth
state
cmd
repoguard
git
+1 -2
appview/auth/auth.go
··· 147 clientSession.Values[appview.SessionRefreshJwt] = atSessionish.GetRefreshJwt() 148 clientSession.Values[appview.SessionExpiry] = time.Now().Add(time.Hour).Format(appview.TimeLayout) 149 clientSession.Values[appview.SessionAuthenticated] = true 150 - 151 return clientSession.Save(r, w) 152 } 153 ··· 185 } 186 187 func (a *Auth) GetHandle(r *http.Request) string { 188 - clientSession, _ := a.Store.Get(r, appview.SessionName) 189 return clientSession.Values[appview.SessionHandle].(string) 190 }
··· 147 clientSession.Values[appview.SessionRefreshJwt] = atSessionish.GetRefreshJwt() 148 clientSession.Values[appview.SessionExpiry] = time.Now().Add(time.Hour).Format(appview.TimeLayout) 149 clientSession.Values[appview.SessionAuthenticated] = true 150 return clientSession.Save(r, w) 151 } 152 ··· 184 } 185 186 func (a *Auth) GetHandle(r *http.Request) string { 187 + clientSession, _ := a.Store.Get(r, appview.SessionHandle) 188 return clientSession.Values[appview.SessionHandle].(string) 189 }
-1
appview/state/middleware.go
··· 18 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 19 session, _ := s.auth.Store.Get(r, appview.SessionName) 20 authorized, ok := session.Values[appview.SessionAuthenticated].(bool) 21 - 22 if !ok || !authorized { 23 log.Printf("not logged in, redirecting") 24 http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
··· 18 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 19 session, _ := s.auth.Store.Get(r, appview.SessionName) 20 authorized, ok := session.Values[appview.SessionAuthenticated].(bool) 21 if !ok || !authorized { 22 log.Printf("not logged in, redirecting") 23 http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
+1 -1
cmd/repoguard/main.go
··· 12 "strings" 13 "time" 14 15 - "github.com/icyphox/bild/auth" 16 ) 17 18 var (
··· 12 "strings" 13 "time" 14 15 + "github.com/icyphox/bild/appview/auth" 16 ) 17 18 var (
+345
git/git.go
···
··· 1 + package git 2 + 3 + import ( 4 + "archive/tar" 5 + "fmt" 6 + "io" 7 + "io/fs" 8 + "path" 9 + "sort" 10 + "time" 11 + 12 + "github.com/go-git/go-git/v5" 13 + "github.com/go-git/go-git/v5/plumbing" 14 + "github.com/go-git/go-git/v5/plumbing/object" 15 + ) 16 + 17 + type GitRepo struct { 18 + r *git.Repository 19 + h plumbing.Hash 20 + } 21 + 22 + type TagList struct { 23 + refs []*TagReference 24 + r *git.Repository 25 + } 26 + 27 + // TagReference is used to list both tag and non-annotated tags. 28 + // Non-annotated tags should only contains a reference. 29 + // Annotated tags should contain its reference and its tag information. 30 + type TagReference struct { 31 + ref *plumbing.Reference 32 + tag *object.Tag 33 + } 34 + 35 + // infoWrapper wraps the property of a TreeEntry so it can export fs.FileInfo 36 + // to tar WriteHeader 37 + type infoWrapper struct { 38 + name string 39 + size int64 40 + mode fs.FileMode 41 + modTime time.Time 42 + isDir bool 43 + } 44 + 45 + func (self *TagList) Len() int { 46 + return len(self.refs) 47 + } 48 + 49 + func (self *TagList) Swap(i, j int) { 50 + self.refs[i], self.refs[j] = self.refs[j], self.refs[i] 51 + } 52 + 53 + // sorting tags in reverse chronological order 54 + func (self *TagList) Less(i, j int) bool { 55 + var dateI time.Time 56 + var dateJ time.Time 57 + 58 + if self.refs[i].tag != nil { 59 + dateI = self.refs[i].tag.Tagger.When 60 + } else { 61 + c, err := self.r.CommitObject(self.refs[i].ref.Hash()) 62 + if err != nil { 63 + dateI = time.Now() 64 + } else { 65 + dateI = c.Committer.When 66 + } 67 + } 68 + 69 + if self.refs[j].tag != nil { 70 + dateJ = self.refs[j].tag.Tagger.When 71 + } else { 72 + c, err := self.r.CommitObject(self.refs[j].ref.Hash()) 73 + if err != nil { 74 + dateJ = time.Now() 75 + } else { 76 + dateJ = c.Committer.When 77 + } 78 + } 79 + 80 + return dateI.After(dateJ) 81 + } 82 + 83 + func Open(path string, ref string) (*GitRepo, error) { 84 + var err error 85 + g := GitRepo{} 86 + g.r, err = git.PlainOpen(path) 87 + if err != nil { 88 + return nil, fmt.Errorf("opening %s: %w", path, err) 89 + } 90 + 91 + if ref == "" { 92 + head, err := g.r.Head() 93 + if err != nil { 94 + return nil, fmt.Errorf("getting head of %s: %w", path, err) 95 + } 96 + g.h = head.Hash() 97 + } else { 98 + hash, err := g.r.ResolveRevision(plumbing.Revision(ref)) 99 + if err != nil { 100 + return nil, fmt.Errorf("resolving rev %s for %s: %w", ref, path, err) 101 + } 102 + g.h = *hash 103 + } 104 + return &g, nil 105 + } 106 + 107 + func (g *GitRepo) Commits() ([]*object.Commit, error) { 108 + ci, err := g.r.Log(&git.LogOptions{From: g.h}) 109 + if err != nil { 110 + return nil, fmt.Errorf("commits from ref: %w", err) 111 + } 112 + 113 + commits := []*object.Commit{} 114 + ci.ForEach(func(c *object.Commit) error { 115 + commits = append(commits, c) 116 + return nil 117 + }) 118 + 119 + return commits, nil 120 + } 121 + 122 + func (g *GitRepo) LastCommit() (*object.Commit, error) { 123 + c, err := g.r.CommitObject(g.h) 124 + if err != nil { 125 + return nil, fmt.Errorf("last commit: %w", err) 126 + } 127 + return c, nil 128 + } 129 + 130 + func (g *GitRepo) FileContent(path string) (string, error) { 131 + c, err := g.r.CommitObject(g.h) 132 + if err != nil { 133 + return "", fmt.Errorf("commit object: %w", err) 134 + } 135 + 136 + tree, err := c.Tree() 137 + if err != nil { 138 + return "", fmt.Errorf("file tree: %w", err) 139 + } 140 + 141 + file, err := tree.File(path) 142 + if err != nil { 143 + return "", err 144 + } 145 + 146 + isbin, _ := file.IsBinary() 147 + 148 + if !isbin { 149 + return file.Contents() 150 + } else { 151 + return "Not displaying binary file", nil 152 + } 153 + } 154 + 155 + func (g *GitRepo) Tags() ([]*TagReference, error) { 156 + iter, err := g.r.Tags() 157 + if err != nil { 158 + return nil, fmt.Errorf("tag objects: %w", err) 159 + } 160 + 161 + tags := make([]*TagReference, 0) 162 + 163 + if err := iter.ForEach(func(ref *plumbing.Reference) error { 164 + obj, err := g.r.TagObject(ref.Hash()) 165 + switch err { 166 + case nil: 167 + tags = append(tags, &TagReference{ 168 + ref: ref, 169 + tag: obj, 170 + }) 171 + case plumbing.ErrObjectNotFound: 172 + tags = append(tags, &TagReference{ 173 + ref: ref, 174 + }) 175 + default: 176 + return err 177 + } 178 + return nil 179 + }); err != nil { 180 + return nil, err 181 + } 182 + 183 + tagList := &TagList{r: g.r, refs: tags} 184 + sort.Sort(tagList) 185 + return tags, nil 186 + } 187 + 188 + func (g *GitRepo) Branches() ([]*plumbing.Reference, error) { 189 + bi, err := g.r.Branches() 190 + if err != nil { 191 + return nil, fmt.Errorf("branchs: %w", err) 192 + } 193 + 194 + branches := []*plumbing.Reference{} 195 + 196 + _ = bi.ForEach(func(ref *plumbing.Reference) error { 197 + branches = append(branches, ref) 198 + return nil 199 + }) 200 + 201 + return branches, nil 202 + } 203 + 204 + func (g *GitRepo) FindMainBranch(branches []string) (string, error) { 205 + 206 + for _, b := range branches { 207 + _, err := g.r.ResolveRevision(plumbing.Revision(b)) 208 + if err == nil { 209 + return b, nil 210 + } 211 + } 212 + return "", fmt.Errorf("unable to find main branch") 213 + } 214 + 215 + // WriteTar writes itself from a tree into a binary tar file format. 216 + // prefix is root folder to be appended. 217 + func (g *GitRepo) WriteTar(w io.Writer, prefix string) error { 218 + tw := tar.NewWriter(w) 219 + defer tw.Close() 220 + 221 + c, err := g.r.CommitObject(g.h) 222 + if err != nil { 223 + return fmt.Errorf("commit object: %w", err) 224 + } 225 + 226 + tree, err := c.Tree() 227 + if err != nil { 228 + return err 229 + } 230 + 231 + walker := object.NewTreeWalker(tree, true, nil) 232 + defer walker.Close() 233 + 234 + name, entry, err := walker.Next() 235 + for ; err == nil; name, entry, err = walker.Next() { 236 + info, err := newInfoWrapper(name, prefix, &entry, tree) 237 + if err != nil { 238 + return err 239 + } 240 + 241 + header, err := tar.FileInfoHeader(info, "") 242 + if err != nil { 243 + return err 244 + } 245 + 246 + err = tw.WriteHeader(header) 247 + if err != nil { 248 + return err 249 + } 250 + 251 + if !info.IsDir() { 252 + file, err := tree.File(name) 253 + if err != nil { 254 + return err 255 + } 256 + 257 + reader, err := file.Blob.Reader() 258 + if err != nil { 259 + return err 260 + } 261 + 262 + _, err = io.Copy(tw, reader) 263 + if err != nil { 264 + reader.Close() 265 + return err 266 + } 267 + reader.Close() 268 + } 269 + } 270 + 271 + return nil 272 + } 273 + 274 + func newInfoWrapper( 275 + name string, 276 + prefix string, 277 + entry *object.TreeEntry, 278 + tree *object.Tree, 279 + ) (*infoWrapper, error) { 280 + var ( 281 + size int64 282 + mode fs.FileMode 283 + isDir bool 284 + ) 285 + 286 + if entry.Mode.IsFile() { 287 + file, err := tree.TreeEntryFile(entry) 288 + if err != nil { 289 + return nil, err 290 + } 291 + mode = fs.FileMode(file.Mode) 292 + 293 + size, err = tree.Size(name) 294 + if err != nil { 295 + return nil, err 296 + } 297 + } else { 298 + isDir = true 299 + mode = fs.ModeDir | fs.ModePerm 300 + } 301 + 302 + fullname := path.Join(prefix, name) 303 + return &infoWrapper{ 304 + name: fullname, 305 + size: size, 306 + mode: mode, 307 + modTime: time.Unix(0, 0), 308 + isDir: isDir, 309 + }, nil 310 + } 311 + 312 + func (i *infoWrapper) Name() string { 313 + return i.name 314 + } 315 + 316 + func (i *infoWrapper) Size() int64 { 317 + return i.size 318 + } 319 + 320 + func (i *infoWrapper) Mode() fs.FileMode { 321 + return i.mode 322 + } 323 + 324 + func (i *infoWrapper) ModTime() time.Time { 325 + return i.modTime 326 + } 327 + 328 + func (i *infoWrapper) IsDir() bool { 329 + return i.isDir 330 + } 331 + 332 + func (i *infoWrapper) Sys() any { 333 + return nil 334 + } 335 + 336 + func (t *TagReference) Name() string { 337 + return t.ref.Name().Short() 338 + } 339 + 340 + func (t *TagReference) Message() string { 341 + if t.tag != nil { 342 + return t.tag.Message 343 + } 344 + return "" 345 + }