From b0b83af1c45c2d5ee587dc96847e25c95a3d50b0 Mon Sep 17 00:00:00 2001 From: Andinus Date: Fri, 27 Mar 2020 22:43:11 +0530 Subject: Add login handler --- auth/login.go | 6 ++-- auth/token/add.go | 4 +-- cmd/perseus/main.go | 3 ++ handler/web/login.go | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ web/login.html | 52 ++++++++++++++++++++++++++++++++ web/register.html | 9 ++---- 6 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 handler/web/login.go create mode 100644 web/login.html diff --git a/auth/login.go b/auth/login.go index 66d1b21..99e74ba 100644 --- a/auth/login.go +++ b/auth/login.go @@ -9,13 +9,13 @@ import ( // Login takes in login details and returns an error. If error doesn't // equal nil then consider login failed. -func Login(db *sqlite3.DB, loginInfo map[string]string) error { +func Login(db *sqlite3.DB, uInfo map[string]string) error { // Acquire read lock on the database. db.Mu.RLock() defer db.Mu.RUnlock() u := user.User{} - u.SetUsername(loginInfo["username"]) + u.SetUsername(uInfo["username"]) // Get password for this user from the database. stmt, err := db.Conn.Prepare("SELECT password FROM users WHERE username = ?") @@ -36,7 +36,7 @@ func Login(db *sqlite3.DB, loginInfo map[string]string) error { u.SetPassword(pass) // Check user's password. - err = checkPass(loginInfo["password"], u.Password()) + err = checkPass(uInfo["password"], u.Password()) if err != nil { log.Printf("auth/login.go: %s%s\n", "user login failed, username: ", u.Username()) diff --git a/auth/token/add.go b/auth/token/add.go index c7f632c..eadc6dc 100644 --- a/auth/token/add.go +++ b/auth/token/add.go @@ -37,9 +37,9 @@ func AddToken(db *sqlite3.DB, uInfo map[string]string) (token string, err error) } stmt, err := db.Conn.Prepare(` -INSERT INTO access(id, username, genTime) values(?, ?, ?)`) +INSERT INTO access(id, token, genTime) values(?, ?, ?)`) if err != nil { - log.Printf("auth/tokenr.go: %s\n", + log.Printf("auth/token.go: %s\n", "failed to prepare statement") return } diff --git a/cmd/perseus/main.go b/cmd/perseus/main.go index b94793e..6abd3a4 100644 --- a/cmd/perseus/main.go +++ b/cmd/perseus/main.go @@ -30,6 +30,9 @@ func main() { http.HandleFunc("/register", func(w http.ResponseWriter, r *http.Request) { web.HandleRegister(w, r, db) }) + http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) { + web.HandleLogin(w, r, db) + }) log.Printf("main/main.go: listening on port %s...", envPort) log.Fatal(srv.ListenAndServe()) diff --git a/handler/web/login.go b/handler/web/login.go new file mode 100644 index 0000000..0c70b56 --- /dev/null +++ b/handler/web/login.go @@ -0,0 +1,83 @@ +package web + +import ( + "fmt" + "html/template" + "log" + "net/http" + "time" + + "tildegit.org/andinus/perseus/auth" + "tildegit.org/andinus/perseus/auth/token" + "tildegit.org/andinus/perseus/core" + "tildegit.org/andinus/perseus/storage/sqlite3" +) + +// HandleLogin handles /login pages. +func HandleLogin(w http.ResponseWriter, r *http.Request, db *sqlite3.DB) { + p := Page{Version: core.Version()} + error := []string{} + success := []string{} + + switch r.Method { + case http.MethodGet: + t, _ := template.ParseFiles("web/login.html") + t.Execute(w, p) + + case http.MethodPost: + if err := r.ParseForm(); err != nil { + log.Printf("web/login.go: 400 Bad Request :: %s", err.Error()) + http.Error(w, "400 Bad Request", http.StatusBadRequest) + return + } + + // Get form values + uInfo := make(map[string]string) + uInfo["username"] = r.FormValue("username") + uInfo["password"] = r.FormValue("password") + + // Perform authentication + err := auth.Login(db, uInfo) + + if err != nil { + log.Printf("web/login.go: %s :: %s :: %s", + "login failed", + uInfo["username"], + err.Error()) + + error = append(error, + fmt.Sprintf("Login failed")) + + p.Error = error + } else { + success = append(success, + fmt.Sprintf("Login successful")) + p.Success = success + + // Set token if login was successful. + token, err := token.AddToken(db, uInfo) + if err != nil { + log.Printf("web/login.go: %s :: %s :: %s", + "token generation failed", + uInfo["username"], + err.Error()) + + error = append(error, + fmt.Sprintf("Token generation failed")) + } + // If token was generated then ask browser to + // set it as cookie. + expiration := time.Now().Add(1 * 24 * time.Hour) + cookie := http.Cookie{Name: "token", Value: token, Expires: expiration} + http.SetCookie(w, &cookie) + } + + t, _ := template.ParseFiles("web/login.html") + t.Execute(w, p) + + default: + w.WriteHeader(http.StatusMethodNotAllowed) + log.Printf("web/login.go: %v not allowed on %v", r.Method, r.URL) + } + +} diff --git a/web/login.html b/web/login.html new file mode 100644 index 0000000..cd0d6a7 --- /dev/null +++ b/web/login.html @@ -0,0 +1,52 @@ + + + + + + Login · Perseus + + + + + +
+

Perseus

{{ if .SafeList }} + {{end}} {{ if .List }} + {{end}} {{ if .Error }} + {{end}} {{ if .Success }} + {{end}} {{ if .Notice }} + {{end}} +
+

Username

+ +

Password

+ + +
+
+
+

+ Andinus +  /  + Perseus + + Perseus {{ .Version }} +  /  + + Source Code + + +

+
+ + diff --git a/web/register.html b/web/register.html index e71979e..c351ae1 100644 --- a/web/register.html +++ b/web/register.html @@ -10,12 +10,7 @@
-

Perseus

-

- Perseus is a simple link aggregation and discussion program. - It is written in Go & uses sqlite3 for storage. -

-
{{ if .SafeList }} +

Perseus

{{ if .SafeList }} {{end}} {{ if .List }} @@ -36,7 +31,7 @@

Password

- +
-- cgit 1.4.1-2-gfad0