main.go (view raw)
1package main
2
3import (
4 "context"
5 "errors"
6 "html/template"
7 "log"
8 "net/http"
9 "os"
10 "time"
11
12 "github.com/birabittoh/auth-boilerplate/auth"
13 "github.com/birabittoh/auth-boilerplate/email"
14 "github.com/birabittoh/myks"
15 "github.com/glebarez/sqlite"
16 "github.com/joho/godotenv"
17 "gorm.io/gorm"
18)
19
20type key int
21
22type User struct {
23 gorm.Model
24 Username string
25 Email string
26 PasswordHash string
27 Salt string
28}
29
30var (
31 db *gorm.DB
32 g *auth.Auth
33 m *email.Client
34
35 ks = myks.New[uint](0)
36 durationDay = 24 * time.Hour
37 durationWeek = 7 * durationDay
38 templates = template.Must(template.ParseGlob("templates/*.html"))
39)
40
41const userContextKey key = 0
42
43func loadEmailConfig() *email.Client {
44 address := os.Getenv("APP_SMTP_EMAIL")
45 password := os.Getenv("APP_SMTP_PASSWORD")
46 host := os.Getenv("APP_SMTP_HOST")
47 port := os.Getenv("APP_SMTP_PORT")
48
49 if address == "" || password == "" || host == "" {
50 log.Println("Missing email configuration.")
51 return nil
52 }
53
54 if port == "" {
55 port = "587"
56 }
57
58 return email.NewClient(address, password, host, port)
59}
60
61func sendEmail(mail email.Email) error {
62 if m == nil {
63 return errors.New("email client is not initialized")
64 }
65 return m.Send(mail)
66}
67
68func main() {
69 err := godotenv.Load()
70 if err != nil {
71 log.Println("Error loading .env file")
72 }
73
74 // Connessione al database SQLite
75 db, err = gorm.Open(sqlite.Open("database.db"), &gorm.Config{})
76 if err != nil {
77 log.Fatal(err)
78 }
79
80 // Creazione della tabella utenti
81 db.AutoMigrate(&User{})
82
83 // Inizializzazione di gauth
84 g = auth.NewAuth(os.Getenv("APP_PEPPER"))
85 m = loadEmailConfig()
86
87 // Gestione delle route
88 http.HandleFunc("GET /", loginRequired(examplePage))
89 http.HandleFunc("GET /register", getRegisterHandler)
90 http.HandleFunc("GET /login", getLoginHandler)
91 http.HandleFunc("GET /reset-password", getResetPasswordHandler)
92 http.HandleFunc("GET /reset-password-confirm", getResetPasswordConfirmHandler)
93 http.HandleFunc("GET /logout", logoutHandler)
94
95 http.HandleFunc("POST /login", postLoginHandler)
96 http.HandleFunc("POST /register", postRegisterHandler)
97 http.HandleFunc("POST /reset-password", postResetPasswordHandler)
98 http.HandleFunc("POST /reset-password-confirm", postResetPasswordConfirmHandler)
99
100 port := ":8080"
101 log.Println("Server running on port " + port)
102 log.Fatal(http.ListenAndServe(port, nil))
103}
104
105// Middleware per controllare se l'utente รจ loggato.
106func loginRequired(next http.HandlerFunc) http.HandlerFunc {
107 return func(w http.ResponseWriter, r *http.Request) {
108 cookie, err := r.Cookie("session_token")
109 if err != nil {
110 http.Redirect(w, r, "/login", http.StatusFound)
111 return
112 }
113
114 userID, err := ks.Get(cookie.Value)
115 if err != nil {
116 http.Redirect(w, r, "/login", http.StatusFound)
117 return
118 }
119
120 ctx := context.WithValue(r.Context(), userContextKey, *userID)
121 next(w, r.WithContext(ctx))
122 }
123}
124
125func getLoggedUser(r *http.Request) (user User, ok bool) {
126 userID, ok := r.Context().Value(userContextKey).(uint)
127 db.Find(&user, userID)
128 return user, ok
129}