Skip to content

Commit 6883604

Browse files
authored
Merge pull request #95 from pavelsne/iss69
User login and logout (#62, #69) resolved
2 parents 31b9ebd + e13b899 commit 6883604

File tree

9 files changed

+146
-31
lines changed

9 files changed

+146
-31
lines changed

cmd/ginvalid/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func registerRoutes(r *mux.Router) {
4747
r.HandleFunc("/results/{validator}/{user}/{repo}/{id}", web.Results).Methods("GET")
4848
r.HandleFunc("/login", web.LoginGet).Methods("GET")
4949
r.HandleFunc("/login", web.LoginPost).Methods("POST")
50+
r.HandleFunc("/logout", web.Logout).Methods("GET")
5051
r.HandleFunc("/repos", web.ListRepos).Methods("GET")
5152
r.HandleFunc("/repos/{user}", web.ListRepos).Methods("GET")
5253
r.HandleFunc("/repos/{user}/{repo}/{validator}/enable", web.EnableHook).Methods("GET")

internal/resources/templates/layout.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ var Layout = `
3535
<a class="item" href="{{.GinURL}}">Back to GIN</a>
3636
<a class="item" href="/repos">Repositories</a>
3737
<a class="item" href="/pubvalidate">One-time validation</a>
38-
<a class="item" href="/login">Login</a>
38+
{{ if eq .UserName ""}}
39+
<a class="item" href="/login">Login</a>
40+
{{ else }}
41+
<a class="item" href="/logout">{{.UserName}} (logout)</a>
42+
{{ end }}
3943
</div>
4044
</div>
4145
</div>

internal/web/fail.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
// fail logs an error and renders an error page with the given message,
1414
// returning the given status code to the user.
15-
func fail(w http.ResponseWriter, status int, message string) {
15+
func fail(w http.ResponseWriter, r *http.Request, status int, message string) {
1616
log.Write("[error] %s", message)
1717
w.WriteHeader(status)
1818

@@ -29,19 +29,25 @@ func fail(w http.ResponseWriter, status int, message string) {
2929
return
3030
}
3131
year, _, _ := time.Now().Date()
32+
loggedUsername := ""
33+
if r != nil {
34+
loggedUsername = getLoggedUserName(r)
35+
}
3236
srvcfg := config.Read()
3337
errinfo := struct {
3438
StatusCode int
3539
StatusText string
3640
Message string
3741
GinURL string
3842
CurrentYear int
43+
UserName string
3944
}{
4045
status,
4146
http.StatusText(status),
4247
message,
4348
srvcfg.GINAddresses.WebURL,
4449
year,
50+
loggedUsername,
4551
}
4652
tmpl.Execute(w, &errinfo)
4753
}

internal/web/fail_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ func TestFailFailedToParse(t *testing.T) {
1111
w := httptest.NewRecorder()
1212
original := templates.Layout
1313
templates.Layout = "{{ WTF? }"
14-
fail(w, 200, "WTF")
14+
fail(w, nil, 200, "WTF")
1515
templates.Layout = original
1616
status := w.Code
1717
if status != http.StatusOK {
@@ -23,7 +23,7 @@ func TestFailFailedToParseFailPage(t *testing.T) {
2323
w := httptest.NewRecorder()
2424
original := templates.Fail
2525
templates.Fail = "{{ WTF? }"
26-
fail(w, 200, "WTF")
26+
fail(w, nil, 200, "WTF")
2727
templates.Fail = original
2828
status := w.Code
2929
if status != http.StatusOK {

internal/web/hooks.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ func EnableHook(w http.ResponseWriter, r *http.Request) {
3232
return
3333
}
3434
if !helpers.SupportedValidator(validator) {
35-
fail(w, http.StatusNotFound, "unsupported validator")
35+
fail(w, r, http.StatusNotFound, "unsupported validator")
3636
return
3737
}
3838
repopath := fmt.Sprintf("%s/%s", user, repo)
3939
err = createValidHook(repopath, validator, ut)
4040
if err != nil {
4141
// TODO: Check if failure is for other reasons and maybe return 500 instead
42-
fail(w, http.StatusUnauthorized, err.Error())
42+
fail(w, r, http.StatusUnauthorized, err.Error())
4343
return
4444
}
4545
http.Redirect(w, r, fmt.Sprintf("/repos/%s/hooks", repopath), http.StatusFound)
@@ -55,7 +55,7 @@ func DisableHook(w http.ResponseWriter, r *http.Request) {
5555
hookid, err := strconv.Atoi(hookidstr)
5656
if err != nil {
5757
// bad hook ID (not a number): throw a generic 404
58-
fail(w, http.StatusNotFound, "not found")
58+
fail(w, r, http.StatusNotFound, "not found")
5959
return
6060
}
6161

@@ -69,7 +69,7 @@ func DisableHook(w http.ResponseWriter, r *http.Request) {
6969
err = deleteValidHook(repopath, hookid, ut)
7070
if err != nil {
7171
// TODO: Check if failure is for other reasons and maybe return 500 instead
72-
fail(w, http.StatusUnauthorized, err.Error())
72+
fail(w, r, http.StatusUnauthorized, err.Error())
7373
return
7474
}
7575
http.Redirect(w, r, fmt.Sprintf("/repos/%s/hooks", repopath), http.StatusFound)

internal/web/results.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ func notValidatedYet(w http.ResponseWriter, r *http.Request, badge []byte, valid
190190

191191
// Parse results into html template and serve it
192192
head := fmt.Sprintf("%s validation for %s/%s", validator, user, repo)
193+
loggedUsername := getLoggedUserName(r)
193194
srvcfg := config.Read()
194195
year, _, _ := time.Now().Date()
195196
info := struct {
@@ -204,9 +205,11 @@ func notValidatedYet(w http.ResponseWriter, r *http.Request, badge []byte, valid
204205
HrefURL2 string
205206
HrefAlt2 string
206207
HrefText2 string
208+
UserName string
207209
}{template.HTML(badge), head, string(notvalidatedyet), srvcfg.GINAddresses.WebURL, year,
208210
"/pubvalidate", "Validate now", "Validate this repository right now",
209211
filepath.Join("/repos", user, repo, "hooks"), "Go Back", "Go back to repository information page",
212+
loggedUsername,
210213
}
211214

212215
err = tmpl.ExecuteTemplate(w, "layout", info)
@@ -236,15 +239,17 @@ func renderInProgress(w http.ResponseWriter, r *http.Request, badge []byte, vali
236239
head := fmt.Sprintf("%s validation for %s/%s", strings.ToUpper(validator), user, repo)
237240
srvcfg := config.Read()
238241
resHistory := resultsHistory(validator, user, repo)
242+
loggedUsername := getLoggedUserName(r)
239243
year, _, _ := time.Now().Date()
240244
info := struct {
241245
Badge template.HTML
242246
Header string
243247
Content string
244248
GinURL string
245249
CurrentYear int
250+
UserName string
246251
*ResultsHistoryStruct
247-
}{template.HTML(badge), head, string(progressmsg), srvcfg.GINAddresses.WebURL, year, &resHistory}
252+
}{template.HTML(badge), head, string(progressmsg), srvcfg.GINAddresses.WebURL, year, loggedUsername, &resHistory}
248253

249254
err = tmpl.ExecuteTemplate(w, "layout", info)
250255
if err != nil {
@@ -327,14 +332,16 @@ func renderBIDSResults(w http.ResponseWriter, r *http.Request, badge []byte, con
327332
year, _, _ := time.Now().Date()
328333
srvcfg := config.Read()
329334
resHistory := resultsHistory("bids", user, repo)
335+
loggedUsername := getLoggedUserName(r)
330336
info := struct {
331337
Badge template.HTML
332338
Header string
333339
*BidsResultStruct
334340
GinURL string
335341
CurrentYear int
342+
UserName string
336343
*ResultsHistoryStruct
337-
}{template.HTML(badge), head, &resBIDS, srvcfg.GINAddresses.WebURL, year, &resHistory}
344+
}{template.HTML(badge), head, &resBIDS, srvcfg.GINAddresses.WebURL, year, loggedUsername, &resHistory}
338345

339346
err = tmpl.ExecuteTemplate(w, "layout", info)
340347
if err != nil {
@@ -365,15 +372,17 @@ func renderNIXResults(w http.ResponseWriter, r *http.Request, badge []byte, cont
365372
head := fmt.Sprintf("NIX validation for %s/%s", user, repo)
366373
resHistory := resultsHistory("nix", user, repo)
367374
year, _, _ := time.Now().Date()
375+
loggedUsername := getLoggedUserName(r)
368376
srvcfg := config.Read()
369377
info := struct {
370378
Badge template.HTML
371379
Header string
372380
Content string
373381
GinURL string
374382
CurrentYear int
383+
UserName string
375384
*ResultsHistoryStruct
376-
}{template.HTML(badge), head, string(content), srvcfg.GINAddresses.WebURL, year, &resHistory}
385+
}{template.HTML(badge), head, string(content), srvcfg.GINAddresses.WebURL, year, loggedUsername, &resHistory}
377386

378387
err = tmpl.ExecuteTemplate(w, "layout", info)
379388
if err != nil {
@@ -403,6 +412,7 @@ func renderODMLResults(w http.ResponseWriter, r *http.Request, badge []byte, con
403412
// Parse results into html template and serve it
404413
head := fmt.Sprintf("odML validation for %s/%s", user, repo)
405414
resHistory := resultsHistory("odml", user, repo)
415+
loggedUsername := getLoggedUserName(r)
406416
srvcfg := config.Read()
407417
year, _, _ := time.Now().Date()
408418
info := struct {
@@ -411,8 +421,9 @@ func renderODMLResults(w http.ResponseWriter, r *http.Request, badge []byte, con
411421
Content string
412422
GinURL string
413423
CurrentYear int
424+
UserName string
414425
*ResultsHistoryStruct
415-
}{template.HTML(badge), head, string(content), srvcfg.GINAddresses.WebURL, year, &resHistory}
426+
}{template.HTML(badge), head, string(content), srvcfg.GINAddresses.WebURL, year, loggedUsername, &resHistory}
416427

417428
err = tmpl.ExecuteTemplate(w, "layout", info)
418429
if err != nil {

internal/web/user.go

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,25 +163,28 @@ func loginForm(w http.ResponseWriter, r *http.Request, errMsg string) {
163163
tmpl, err := tmpl.Parse(templates.Layout)
164164
if err != nil {
165165
log.Write("[Error] failed to parse html layout page")
166-
fail(w, http.StatusInternalServerError, "something went wrong")
166+
fail(w, r, http.StatusInternalServerError, "something went wrong")
167167
return
168168
}
169169
tmpl, err = tmpl.Parse(templates.Login)
170170
if err != nil {
171171
log.Write("[Error] failed to render login page")
172-
fail(w, http.StatusInternalServerError, "something went wrong")
172+
fail(w, r, http.StatusInternalServerError, "something went wrong")
173173
return
174174
}
175175
year, _, _ := time.Now().Date()
176+
loggedUsername := getLoggedUserName(r)
176177
srvcfg := config.Read()
177178
data := struct {
178179
GinURL string
179180
CurrentYear int
180181
ErrorMessage string
182+
UserName string
181183
}{
182184
srvcfg.GINAddresses.WebURL,
183185
year,
184186
errMsg,
187+
loggedUsername,
185188
}
186189
tmpl.Execute(w, &data)
187190
}
@@ -216,6 +219,32 @@ func LoginPost(w http.ResponseWriter, r *http.Request) {
216219
http.Redirect(w, r, fmt.Sprintf("/repos/%s", username), http.StatusFound)
217220
}
218221

222+
// Logout logouts the current user
223+
func Logout(w http.ResponseWriter, r *http.Request) {
224+
cfg := config.Read()
225+
cookie := http.Cookie{
226+
Name: cfg.Settings.CookieName,
227+
Value: "",
228+
Expires: time.Time{},
229+
Secure: false, // TODO: Switch when we go live
230+
}
231+
http.SetCookie(w, &cookie)
232+
http.Redirect(w, r, "/login", http.StatusFound)
233+
}
234+
235+
func getLoggedUserName(r *http.Request) string {
236+
cfg := config.Read()
237+
cookie, err := r.Cookie(cfg.Settings.CookieName)
238+
if err != nil {
239+
return ""
240+
}
241+
usertoken, err := getTokenBySession(cookie.Value)
242+
if err != nil {
243+
return ""
244+
}
245+
return usertoken.Username
246+
}
247+
219248
func getSessionOrRedirect(w http.ResponseWriter, r *http.Request) (gweb.UserToken, error) {
220249
cfg := config.Read()
221250
cookie, err := r.Cookie(cfg.Settings.CookieName)
@@ -271,13 +300,13 @@ func ListRepos(w http.ResponseWriter, r *http.Request) {
271300
tmpl, err = tmpl.Parse(templates.Layout)
272301
if err != nil {
273302
log.Write("[Error] failed to parse html layout page")
274-
fail(w, http.StatusInternalServerError, "something went wrong")
303+
fail(w, r, http.StatusInternalServerError, "something went wrong")
275304
return
276305
}
277306
tmpl, err = tmpl.Parse(templates.RepoList)
278307
if err != nil {
279308
log.Write("[Error] failed to render repository list page: %s", err.Error())
280-
fail(w, http.StatusInternalServerError, "something went wrong")
309+
fail(w, r, http.StatusInternalServerError, "something went wrong")
281310
return
282311
}
283312
reposActive := make([]repoHooksInfo, 0, len(userrepos))
@@ -308,17 +337,20 @@ func ListRepos(w http.ResponseWriter, r *http.Request) {
308337
}
309338
}
310339
year, _, _ := time.Now().Date()
340+
loggedUsername := getLoggedUserName(r)
311341
srvcfg := config.Read()
312342
allrepos := struct {
313343
Active []repoHooksInfo
314344
Inactive []repoHooksInfo
315345
GinURL string
316346
CurrentYear int
347+
UserName string
317348
}{
318349
reposActive,
319350
reposInactive,
320351
srvcfg.GINAddresses.WebURL,
321352
year,
353+
loggedUsername,
322354
}
323355
tmpl.Execute(w, &allrepos)
324356
}
@@ -454,13 +486,13 @@ func ShowRepo(w http.ResponseWriter, r *http.Request) {
454486
tmpl, err = tmpl.Parse(templates.Layout)
455487
if err != nil {
456488
log.Write("[Error] failed to parse html layout page")
457-
fail(w, http.StatusInternalServerError, "something went wrong")
489+
fail(w, r, http.StatusInternalServerError, "something went wrong")
458490
return
459491
}
460492
tmpl, err = tmpl.Parse(templates.RepoPage)
461493
if err != nil {
462494
log.Write("[Error] failed to render repository page: %s", err.Error())
463-
fail(w, http.StatusInternalServerError, "something went wrong")
495+
fail(w, r, http.StatusInternalServerError, "something went wrong")
464496
return
465497
}
466498

@@ -469,17 +501,20 @@ func ShowRepo(w http.ResponseWriter, r *http.Request) {
469501
hooks = make(map[string]ginhook)
470502
}
471503
year, _, _ := time.Now().Date()
504+
loggedUsername := getLoggedUserName(r)
472505
srvcfg := config.Read()
473506
repohi := struct {
474507
gogs.Repository
475508
Hooks map[string]ginhook
476509
GinURL string
477510
CurrentYear int
511+
UserName string
478512
}{
479513
repoinfo,
480514
hooks,
481515
srvcfg.GINAddresses.WebURL,
482516
year,
517+
loggedUsername,
483518
}
484519
tmpl.Execute(w, &repohi)
485520
}

0 commit comments

Comments
 (0)