+1
-2
appview/auth/auth.go
+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
-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
+1
-1
cmd/repoguard/main.go
+345
git/git.go
+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
+
}