alfheim-website/handlers.go
Vicente Ferrari Smith 98e641c55c added
git-svn-id: svn://losandesgames.com/alfheim-website@14 15359d88-9307-4e75-a9c1-e5686e5897df
2024-05-20 22:50:06 +00:00

390 lines
9.7 KiB
Go

//
// 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";
import "github.com/stripe/stripe-go/v78";
import "github.com/stripe/stripe-go/v78/price";
import "github.com/stripe/stripe-go/v78/customersession";
import "github.com/stripe/stripe-go/v78/billingportal/session";
type templatedata struct {
AuthenticatedUser int32;
FormErrors map[string]string;
Account Account;
Prices []stripe.Price;
ClientSecret string;
}
func favicon(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "favicon.ico");
}
func authenticated_user(w http.ResponseWriter, 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;
}
// check if the saved id exists in the database, otherwise it's a bad id and has to be removed from the cookies
exists := users.Exists_account(id);
if !exists {
session, _ := store.Get(r, "id");
session.Values["id"] = 0;
session.Save(r, w);
return 0;
}
return id;
}
func home(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r);
return;
}
id := authenticated_user(w, 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:
err := 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 {
err := text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(w, r), FormErrors: errors});
if err != nil {
log.Fatal(err);
http.Error(w, "Internal Server Error", 500);
}
return;
}
id, err := users.Authenticate(username, password);
if err == ErrInvalidCredentials {
errors["generic"] = "Email or Password is incorrect";
err := text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(w, r), FormErrors: errors});
if err != nil {
log.Fatal(err);
http.Error(w, "Internal Server Error", 500);
}
return;
}
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(w, r);
account, err := users.Get_account(id);
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:
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);
}
id := authenticated_user(w, r);
account, err := users.Get_account(id);
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:
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 {
err := text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(w, r), FormErrors: errors});
if err != nil {
log.Fatal(err);
http.Error(w, "Internal Server Error", 500);
}
}
err := users.Insert(account.Username, string(account.Password), account.Firstname, account.Lastname, account.Email);
if err == ErrDuplicateEmail || err == ErrDuplicateUsername {
} else if err != nil {
}
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(w, r);
account, err := users.Get_account(id);
fmt.Println(id, account)
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:
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:
// text.Execute(w, false);
// if err != nil {;
// log.Fatal(err);
// http.Error(w, "Internal Server Error", 500);
// };
}
func deleteaccount(w http.ResponseWriter, r *http.Request) {
id := authenticated_user(w, r);
switch r.Method {
case http.MethodPost:
fmt.Println("Deleting account with id ", id);
users.Delete(id);
session, _ := store.Get(r, "id");
session.Values["id"] = 0;
session.Save(r, w);
http.Redirect(w, r, "/", http.StatusSeeOther);
}
}
func subscribe(w http.ResponseWriter, r *http.Request) {
id := authenticated_user(w, r);
account, err := users.Get_account(id);
params := &stripe.PriceListParams{};
params.Limit = stripe.Int64(3)
params.AddExpand("data.product");
results := price.List(params);
prices := make([]stripe.Price, 0);
for results.Next() {
fmt.Println(results.Current())
prices = append(prices, *results.Price());
}
fm := template.FuncMap{
"divide": func(a, b float64) float64 {
return a / b;
},
};
text, err := template.New("base.html").Funcs(fm).ParseFiles("ui/base.html", "ui/subscribe.html");
if err != nil {
http.Error(w, "Internal Server Error", 500);
log.Fatal(err);
return;
}
err = text.Execute(w, templatedata{AuthenticatedUser: id, Account: account, Prices: prices});
if err != nil {
log.Fatal(err);
http.Error(w, "Internal Server Error", 500);
}
}
func subscribe_stripe(w http.ResponseWriter, r *http.Request) {
id := authenticated_user(w, r);
account, err := users.Get_account(id);
params := &stripe.CustomerSessionParams{
Customer: stripe.String(account.StripeID),
Components: &stripe.CustomerSessionComponentsParams{
PricingTable: &stripe.CustomerSessionComponentsPricingTableParams{
Enabled: stripe.Bool(true),
},
},
};
result, err := customersession.New(params);
if err != nil {
fmt.Println(err);
}
text, err := template.ParseFiles("ui/base.html", "ui/subscribe_stripe.html");
if err != nil {
http.Error(w, "Internal Server Error", 500);
log.Fatal(err);
}
err = text.Execute(w, templatedata{AuthenticatedUser: id, Account: account, ClientSecret: result.ClientSecret});
if err != nil {
log.Fatal(err);
http.Error(w, "Internal Server Error", 500);
}
}
func managebilling(w http.ResponseWriter, r *http.Request) {
id := authenticated_user(w, r);
account, err := users.Get_account(id);
if err != nil {
fmt.Println(err);
}
params := &stripe.BillingPortalSessionParams{
Customer: stripe.String(account.StripeID),
ReturnURL: stripe.String("http://localhost:8080/account"),
};
result, err := session.New(params);
if err != nil {
fmt.Println(err);
}
http.Redirect(w, r, result.URL, http.StatusSeeOther);
}