forked from 0c34/govwa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
user.go
163 lines (129 loc) · 3.75 KB
/
user.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
159
160
161
162
163
package user
import (
"log"
"net/http"
"strconv"
"crypto/md5"
"database/sql"
"encoding/hex"
"html/template"
"github.com/govwa/util"
"github.com/govwa/util/config"
"github.com/govwa/user/session"
"github.com/govwa/util/database"
"github.com/govwa/util/middleware"
"github.com/julienschmidt/httprouter"
)
/*
uname : admin
pass : govwaadmin
uname : user1
pass : govwauser1
*/
type Self struct{} //oop like syntax
func New() *Self {
return &Self{}
}
func (self *Self) SetRouter(r *httprouter.Router) {
/* register all router */
mw := middleware.New() //implement middleware
r.GET("/login", mw.LoggingMiddleware(mw.CapturePanic(LoginViewHandler)))
r.POST("/login", mw.LoggingMiddleware(mw.CapturePanic(LoginViewHandler)))
r.GET("/logout", mw.LoggingMiddleware(Logout))
}
func LoginViewHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
/* handler for login view */
/* check database for setup */
ok, err := database.CheckDatabase()
if !ok || err != nil{
util.Redirect(w, r, "setup", 302) //if no database will redirect to setup page
}
/* value of data will send to client over template */
data := make(map[string]interface{})
data["Title"] = "Login"
data["govwahost"] = config.Fullurl
s := session.New()
if s.IsLoggedIn(r) { //if user session isset wkwk redirect to index page
util.Redirect(w, r, "index", 302)
}
if r.Method == "POST" {
if !validateForm(w,r,ps) {
data["message"] = template.HTML("<div id=\"message\" class=\"alert alert-danger\"><p>Empty Username or Password</p></div>")
}else{
if loginAction(w, r, ps) {
util.Redirect(w, r, "index", 302)
} else {
//the best solution instead of using ajax request
data["message"] = template.HTML("<div id=\"message\" class=\"alert alert-danger\"><p>Incorrect Username or Password</p></div>")
log.Println("Login Failed")
}
}
}
util.SafeRender(w,r, "template.login", data)
}
func loginAction(w http.ResponseWriter, r *http.Request, _ httprouter.Params) bool {
/* handler for login action */
uname := r.FormValue("username")
pass := Md5Sum(r.FormValue("password"))
uData := checkUserQuery(uname, pass) //handle user data from db
if uData.cnt == 1 {
s := session.New()
/* save user data to session */
sessionData := make(map[string]string)
sessionData["uname"] = uData.uname
sessionData["id"] = strconv.Itoa(uData.id)
s.SetSession(w, r, sessionData)
util.SetCookie(w, "Uid", strconv.Itoa(uData.id)) //save user_id to cookie
log.Println("Login Success")
return true
} else {
return false
}
}
func Logout(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
s := session.New()
s.DeleteSession(w, r)
cookies := []string{"Level", "Uid"}
util.DeleteCookie(w,cookies)
util.Redirect(w, r, "login", 302)
}
func validateForm(w http.ResponseWriter, r *http.Request, _ httprouter.Params)bool{
uname := r.FormValue("username")
pass := r.FormValue("password")
if uname == "" || pass == ""{
return false
}
return true
}
/* type to handle user data that return form query */
type UserData struct {
id int
uname string
cnt int
}
var db *sql.DB
func checkUserQuery(username, pass string) *UserData {
/* this function will check rows num which return from query */
db, err := database.Connect()
if err != nil {
log.Println(err.Error())
}
var uData = UserData{} //inisialize empty userdata
const (
sql = `SELECT id, uname, COUNT(*) as cnt
FROM Users
WHERE uname=?
AND pass=?`)
stmt, err := db.Prepare(sql)
if err != nil {
log.Println(err.Error())
}
defer stmt.Close()
err = stmt.QueryRow(username, pass).Scan(&uData.id, &uData.uname, &uData.cnt)
return &uData
}
func Md5Sum(text string) string {
hasher := md5.New()
hasher.Write([]byte(text))
return hex.EncodeToString(hasher.Sum(nil))
}