-
Notifications
You must be signed in to change notification settings - Fork 0
/
front.go
158 lines (132 loc) · 3.39 KB
/
front.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package main
import (
"errors"
"log"
"net/http"
"github.com/ejv2/prepper/conf"
"github.com/ejv2/prepper/data"
"github.com/gin-gonic/gin"
)
// handleRoot is the handler for "/"
//
// If the request comes from an authenticated user, the user is redirected to
// their dashboard. Else, the user is redirected to the login page.
func handleRoot(c *gin.Context) {
s := Sessions.Start(c)
defer s.Update()
// Redirect based on login state
if s.SignedIn {
c.Redirect(http.StatusFound, "/dashboard/")
} else {
c.Redirect(http.StatusFound, "/login")
}
}
// handleAbout is the handler for "/about"
//
// Shows an about page for this server. Doesn't need authentication although if
// the user is signed in, we show a navbar.
func handleAbout(c *gin.Context) {
s := Sessions.Start(c)
defer s.Update()
var ddat *DashboardData
if s.SignedIn {
addat, err := NewDashboardData(s)
if err != nil {
internalError(c, err)
return
}
ddat = &addat
}
c.HTML(http.StatusOK, "about.gohtml", struct {
*DashboardData
SignedIn bool
VersionString string
}{ddat, s.SignedIn, VersionString()})
}
// handleHelp is the handler for "/help"
//
// Shows a little help page from the configured help message.
func handleHelp(c *gin.Context) {
s := Sessions.Start(c)
defer s.Update()
ddat, err := NewDashboardData(s)
if err != nil {
internalError(c, err)
return
}
ht := Config.HelpText
if ht == "" {
ht = conf.DefaultHelpText
}
c.HTML(http.StatusOK, "help.gohtml", struct {
DashboardData
HelpText string
}{ddat, ht})
}
// handleLogin is the handler for GET "/login"
//
// Returns the HTML login page. This *is not* the endpoint for POST request
// logins.
func handleLogin(c *gin.Context) {
s := Sessions.Start(c)
defer s.Update()
if s.SignedIn {
c.Redirect(http.StatusFound, "/dashboard/")
return
}
_, fail := c.GetQuery("error")
_, out := c.GetQuery("out")
c.HTML(http.StatusOK, "login.gohtml", gin.H{
"LoginFailed": fail,
"LoggedOut": out,
})
}
// handleLoginAttempt is the handler for POST "/login"
//
// This is used to submit the form result and always returns status 302.
func handleLoginAttempt(c *gin.Context) {
s := Sessions.Start(c)
if s.SignedIn {
c.AbortWithStatus(http.StatusBadRequest)
return
}
frm := struct {
Username string `form:"username" binding:"required"`
Password string `form:"password" binding:"required"`
}{}
err := c.Bind(&frm)
if err != nil {
c.String(http.StatusBadRequest, "Bad Inputs")
return
}
us, err := data.GetUserByName(Database, frm.Username)
if err != nil {
// SQL error
if !errors.Is(err, data.ErrUserNotFound) {
internalError(c, err)
return
}
log.Print("Login attempt failed for username \"", frm.Username, "\" (bad username)")
c.Redirect(http.StatusFound, "/login?error")
return
}
if !us.Password.Matches(frm.Password) {
log.Print("Login attempt failed for user \"", us.Username, "\" (bad password)")
c.Redirect(http.StatusFound, "/login?error")
return
}
s.SignIn(us.ID)
s.Update()
log.Println("New session begins for", c.RemoteIP(), "on account", us.Username)
c.Redirect(http.StatusFound, "/dashboard/")
}
// handleLogout is the handler for "/logout"
//
// Resets the current session to defaults for a non-authenticated user.
func handleLogout(c *gin.Context) {
s := Sessions.Start(c)
s.Logout()
s.Update()
log.Println("Session ending for", c.RemoteIP())
c.Redirect(http.StatusFound, "/login?out")
}