// // Created by vfs on 02.05.2024. // package main import "fmt" import "log" import "net/http" import "html/template" //import "strconv" import "strings" import "unicode/utf8" import "errors" import "runtime/debug" type templatedata struct { AuthenticatedUser int32 FormErrors map[string]string Account Account } func favicon(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "favicon.ico") } func authenticated_user(r *http.Request) int32 { session, err := store.Get(r, "id") if err != nil { fmt.Println(err) return 0 } id, ok := session.Values["id"].(int32) if !ok { trace := fmt.Sprintf("%s\n%s", errors.New("type assertion to int32 failed").Error(), debug.Stack()) _ = trace //log.Println(trace) return 0 } return id } func home(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r); return } id := authenticated_user(r) account, err := users.Get_account(id) text, err := template.ParseFiles("ui/base.html", "ui/index.html") if err != nil { http.Error(w, "Internal Server Error", 500) log.Fatal(err) } switch r.Method { case http.MethodGet: err = text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}) if err != nil { log.Fatal(err) http.Error(w, "Internal Server Error", 500) } case http.MethodPost: err = text.Execute(w, templatedata{}) if err != nil { log.Fatal(err) http.Error(w, "Internal Server Error", 500) } } } func login(w http.ResponseWriter, r *http.Request) { text, err := template.ParseFiles("ui/base.html", "ui/login.html") if err != nil { http.Error(w, "Internal Server Error", 500) log.Fatal(err) } switch r.Method { case http.MethodGet: text.Execute(w, templatedata{}) if err != nil { log.Fatal(err) http.Error(w, "Internal Server Error", 500) } case http.MethodPost: session, _ := store.Get(r, "id"); password := r.FormValue("password") username := r.FormValue("username") errors := make(map[string]string) if strings.TrimSpace(username) == "" { errors["username"] = "This field cannot be blank" } else if utf8.RuneCountInString(username) > 20 { errors["username"] = "This field is too long (the maximum is 20 characters)" } if strings.TrimSpace(password) == "" { errors["password"] = "This field cannot be blank" } else if utf8.RuneCountInString(password) < 8 { errors["password"] = "This field is too short (the minimum is 8 characters)" } if len(errors) > 0 { text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(r), FormErrors: errors}) if err != nil { log.Fatal(err) http.Error(w, "Internal Server Error", 500) } } id, _ := users.Authenticate(username, password) if id > 0 { session.Values["id"] = id fmt.Println("Logged in with id:", id) session.Save(r, w) http.Redirect(w, r, "/account", http.StatusSeeOther) } } } func logout(w http.ResponseWriter, r *http.Request) { text, err := template.ParseFiles("ui/base.html", "ui/logout.html") if err != nil { http.Error(w, "Internal Server Error", 500) log.Fatal(err) } id := authenticated_user(r) account, err := users.Get_account(id) switch r.Method { case http.MethodGet: text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}) if err != nil { log.Fatal(err) http.Error(w, "Internal Server Error", 500) } case http.MethodPost: session, _ := store.Get(r, "id"); session.Values["id"] = 0; session.Save(r, w) http.Redirect(w, r, "/", http.StatusSeeOther) } } func register(w http.ResponseWriter, r *http.Request) { text, err := template.ParseFiles("ui/base.html", "ui/register.html") if err != nil { http.Error(w, "Internal Server Error", 500) log.Fatal(err) } switch r.Method { case http.MethodGet: text.Execute(w, templatedata{}) if err != nil { log.Fatal(err) http.Error(w, "Internal Server Error", 500) } case http.MethodPost: account := Account{Username: r.FormValue("username"), Password: []byte(r.FormValue("password")), Firstname: r.FormValue("firstname"), Lastname: r.FormValue("lastname"), Email: r.FormValue("email")} errors := make(map[string]string) if strings.TrimSpace(account.Username) == "" { errors["username"] = "This field cannot be blank" } else if utf8.RuneCountInString(account.Username) > 20 { errors["username"] = "This field is too long (the maximum is 20 characters)" } if strings.TrimSpace(string(account.Password)) == "" { errors["password"] = "This field cannot be blank" } else if utf8.RuneCountInString(string(account.Password)) < 8 { errors["password"] = "This field is too short (the minimum is 8 characters)" } if len(errors) > 0 { text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(r), FormErrors: errors}) if err != nil { log.Fatal(err) http.Error(w, "Internal Server Error", 500) } } users.Insert(account.Username, string(account.Password), account.Firstname, account.Lastname, account.Email) http.Redirect(w, r, "/login", http.StatusSeeOther) } } func account(w http.ResponseWriter, r *http.Request) { //id, err := strconv.Atoi(r.URL.Query().Get("id")) //if err != nil || id < 1 { // http.NotFound(w, r) // return //} //account, err := users.Get_account(int32(id)); //if err != nil { // log.Fatal(err); //} id := authenticated_user(r) account, err := users.Get_account(id) text, err := template.ParseFiles("ui/base.html", "ui/account.html") if err != nil { http.Error(w, "Internal Server Error", 500) log.Fatal(err) } switch r.Method { case http.MethodGet: text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}) if err != nil { log.Fatal(err) http.Error(w, "Internal Server Error", 500) } } //case http.MethodPost: // text.Execute(w, false) // if err != nil { // log.Fatal(err) // http.Error(w, "Internal Server Error", 500) // } }