package main
import (
"crypto/rand"
"errors"
"fmt"
"golang.org/x/crypto/bcrypt"
"html/template"
"io"
"log"
"net/http"
"os"
"regexp"
)
type user struct {
ID int
Username string
Password string
}
type RegisterFORM struct {
Username string
Password string
}
var users = make(map[string]User)
func main() {
http.HandleFunc("/register", registerHandler)
http.HandleFunc("/login", loginHandler)
log.Fatal(http.ListeNANDServe(":8080", nil))
}
func registerHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
var form RegisterForm
if err := r.ParseForm(); err != nil {
http.Error(w, "Unable to parse form", http.StatusBadRequest)
return
}
form.Username = r.Form.Get("username")
form.Password = r.Form.Get("password")
if err := validatePassword(form.Password); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
salt, err := generateSalt()
if err != nil {
http.Error(w, "Unable to generate salt", http.StatusInternalServerError)
return
}
passwordHash, err := hashPassword(form.Password + string(salt))
if err != nil {
http.Error(w, "Unable to hash password", http.StatusInternalServerError)
return
}
var user User
user.ID = len(users) + 1
user.Username = form.Username
user.Password = string(passwordHash)
users[user.Username] = user
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
html, err := template.ParseFiles("register.html")
if err != nil {
http.Error(w, "Unable to parse template", http.StatusInternalServerError)
return
}
if err := html.Execute(w, nil); err != nil {
http.Error(w, "Unable to render template", http.StatusInternalServerError)
return
}
}
func loginHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
username := r.Form.Get("username")
password := r.Form.Get("password")
user, ok := users[username]
if !ok {
http.Error(w, "Invalid username or password", http.StatusUnauthorized)
return
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
http.Error(w, "Invalid username or password", http.StatusUnauthorized)
return
}
}
html, err := template.ParseFiles("login.html")
if err != nil {
http.Error(w, "Unable to parse template", http.StatusInternalServerError)
return
}
if err := html.Execute(w, nil); err != nil {
http.Error(w, "Unable to render template", http.StatusInternalServerError)
return
}
}
func generateSalt() ([]byte, error) {