-
Notifications
You must be signed in to change notification settings - Fork 0
/
route-index.go
126 lines (95 loc) · 3.1 KB
/
route-index.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package main
import (
"net/http"
"github.com/freitagsrunde/modulist/db"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"golang.org/x/crypto/bcrypt"
)
// Structs
type LoginPayload struct {
Mail string `form:"login-mail" conform:"trim,email" validate:"required,email"`
Password string `form:"login-password" validate:"required"`
}
// Functions
// Index renders the page first visible when
// navigating to MODULIST start page.
func (app *App) Index(c *gin.Context) {
// Check if user is already logged in.
_, err := app.Authorize(c.Request, db.PRIVILEGE_REVIEWER)
if err == nil {
c.Redirect(http.StatusFound, "/modules")
return
}
c.HTML(http.StatusOK, "index.html", gin.H{
"PageTitle": "Willkommen bei MODULIST",
"MainTitle": "Willkommen bei MODULIST",
})
return
}
// Login provides all necessary functionality
// in order to log in a user.
func (app *App) Login(c *gin.Context) {
// Check if user is already logged in.
_, err := app.Authorize(c.Request, db.PRIVILEGE_REVIEWER)
if err == nil {
c.Redirect(http.StatusFound, "/modules")
return
}
var Payload LoginPayload
err = c.BindWith(&Payload, binding.FormPost)
if err != nil {
c.HTML(http.StatusBadRequest, "index.html", gin.H{
"PageTitle": "Willkommen bei MODULIST",
"MainTitle": "Willkommen bei MODULIST",
"FatalError": "Gesendete Logindaten konnten nicht verarbeitet werden. Bitte erneut versuchen.",
})
return
}
// Check sent content for validity.
ErrorDesc := app.ConformAndValidate(&Payload)
if ErrorDesc != nil {
// If payload did not pass, report errors to user.
c.HTML(http.StatusBadRequest, "index.html", gin.H{
"PageTitle": "Willkommen bei MODULIST",
"MainTitle": "Willkommen bei MODULIST",
"Errors": ErrorDesc,
})
return
}
// Data is valid, try to locate user in database.
var User db.User
app.DB.First(&User, "\"mail\" = ? AND \"enabled\" = ?", Payload.Mail, true)
// Compare password hash from database with possible plaintext
// password from submitted login form. Compares in constant time.
err = bcrypt.CompareHashAndPassword([]byte(User.PasswordHash), []byte(Payload.Password))
if (User.ID == "") || (err != nil) {
// Signal client that an error occured.
c.HTML(http.StatusBadRequest, "index.html", gin.H{
"PageTitle": "Willkommen bei MODULIST",
"MainTitle": "Willkommen bei MODULIST",
"FatalError": "Mail und/oder Passwort falsch.",
})
return
}
// Create a JWT and store it as a cookie.
app.CreateSession(c, User)
// Redirect to first authorized page.
c.Redirect(http.StatusFound, "/modules")
}
// Logout destroys the user's session by storing
// garbage in the current session cookie and instructing
// the browser to delete that cookie.
func (app *App) Logout(c *gin.Context) {
// Check if user is authorized.
_, err := app.Authorize(c.Request, db.PRIVILEGE_REVIEWER)
if err != nil {
c.Redirect(http.StatusFound, "/")
return
}
// Set token cookie content to garbage and
// expiration date to a date in the past.
c.SetCookie("Token", "", -1, "", "", false, true)
// Redirect back to index page.
c.Redirect(http.StatusFound, "/")
}