Add login handler
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
79b376a659
commit
b0b83af1c4
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Login · Perseus</title>
|
||||
<link rel="stylesheet" href="https://andinus.nand.sh/static/style.css">
|
||||
<link rel="stylesheet" href="https://andinus.nand.sh/static/perseus/style.css">
|
||||
<link rel="icon" href="https://andinus.nand.sh/static/perseus/favicon.png" type="image/png">
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1 class="title">Perseus</h1>{{ if .SafeList }}
|
||||
<ul>{{ range .SafeList }}
|
||||
<li>{{ . }}</li>{{ end }}
|
||||
</ul>{{end}} {{ if .List }}
|
||||
<ul>{{ range .List }}
|
||||
<li>{{ . }}</li>{{ end }}
|
||||
</ul>{{end}} {{ if .Error }}
|
||||
<ul class="error">{{ range .Error }}
|
||||
<li>{{ . }}</li>{{ end }}
|
||||
</ul>{{end}} {{ if .Success }}
|
||||
<ul class="success">{{ range .Success }}
|
||||
<li>{{ . }}</li>{{ end }}
|
||||
</ul>{{end}} {{ if .Notice }}
|
||||
<ul class="notice">{{ range .Notice }}
|
||||
<li>{{ . }}</li>{{ end }}
|
||||
</ul>{{end}}
|
||||
<form action="./login" method="post">
|
||||
<h4>Username</h4>
|
||||
<input type="text" name="username" required>
|
||||
<h4>Password</h4>
|
||||
<input type="password" name="password" required>
|
||||
<input type="submit" name="submit" value="Login!">
|
||||
</form>
|
||||
</div>
|
||||
<div id="postamble" class="status">
|
||||
<p class="postamble">
|
||||
<a href="https://andinus.nand.sh/">Andinus</a>
|
||||
/
|
||||
<a href="https://andinus.nand.sh/perseus">Perseus</a>
|
||||
<span style="float:right">
|
||||
Perseus {{ .Version }}
|
||||
/
|
||||
<a href="https://tildegit.org/andinus/perseus">
|
||||
Source Code
|
||||
</a>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -10,12 +10,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1 class="title">Perseus</h1>
|
||||
<p>
|
||||
Perseus is a simple link aggregation and discussion program.
|
||||
It is written in Go & uses sqlite3 for storage.
|
||||
</p>
|
||||
<hr>{{ if .SafeList }}
|
||||
<h1 class="title">Perseus</h1>{{ if .SafeList }}
|
||||
<ul>{{ range .SafeList }}
|
||||
<li>{{ . }}</li>{{ end }}
|
||||
</ul>{{end}} {{ if .List }}
|
||||
|
@ -36,7 +31,7 @@
|
|||
<input type="text" name="username" required>
|
||||
<h4>Password</h4>
|
||||
<input type="password" name="password" required>
|
||||
<input type="submit" name="submit" value="Go!">
|
||||
<input type="submit" name="submit" value="Register!">
|
||||
</form>
|
||||
</div>
|
||||
<div id="postamble" class="status">
|
||||
|
|
Loading…
Reference in New Issue