Files
Poll-system/app/main.go
Mann Patel b21e76eed0 Update: Few issues to resolve see readme
this push will conclude the majority of pulls. this repos will now, not be actively be managed or any further code pushes will not be frequent.
2025-09-11 16:54:30 -06:00

141 lines
4.8 KiB
Go

package main
import (
"context"
"log"
"net/http"
"os"
"github.com/golang-jwt/jwt/v5"
"github.com/joho/godotenv"
"github.com/patel-mann/poll-system/app/internal/handlers"
"github.com/patel-mann/poll-system/app/internal/models"
"github.com/patel-mann/poll-system/app/internal/utils"
_ "github.com/lib/pq" // use PostgreSQL
)
func authMiddleware(next http.HandlerFunc) http.HandlerFunc {
err := godotenv.Load()
if err != nil {
log.Fatalf("Error loading .env file: %v", err)
}
jwtSecret := os.Getenv("JWT_SECRET")
var jwtKey = []byte(jwtSecret)
return func(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("session")
if err != nil {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
claims := &models.Claims{}
token, err := jwt.ParseWithClaims(cookie.Value, claims, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil || !token.Valid {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
// Add user info to context
ctx := context.WithValue(r.Context(), "user_id", claims.UserID)
ctx = context.WithValue(ctx, "user_role", claims.Role)
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
}
}
// Admin middleware to check if user has admin role
func adminMiddleware(next http.HandlerFunc) http.HandlerFunc {
return authMiddleware(func(w http.ResponseWriter, r *http.Request) {
role, ok := r.Context().Value("user_role").(int)
if !ok || role != 1 {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
next.ServeHTTP(w, r)
})
}
// Volunteer middleware to check if user has volunteer role
func volunteerMiddleware(next http.HandlerFunc) http.HandlerFunc {
return authMiddleware(func(w http.ResponseWriter, r *http.Request) {
role, ok := r.Context().Value("user_role").(int)
if !ok || (role != 3 && role != 2) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
next.ServeHTTP(w, r)
})
}
func HomeHandler(w http.ResponseWriter, r *http.Request) {
utils.Render(w, "dashboard.html", map[string]interface{}{
"Title": "Admin Dashboard",
"IsAuthenticated": false,
"ActiveSection": "dashboard",
})
}
func main() {
models.InitDB()
models.EmailMessage("hellow")
// Static file servers
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
uploadsFs := http.FileServer(http.Dir("uploads"))
http.Handle("/uploads/", http.StripPrefix("/uploads/", uploadsFs))
// Public HTML Routes
http.HandleFunc("/", HomeHandler)
http.HandleFunc("/login", handlers.LoginHandler)
http.HandleFunc("/register", handlers.RegisterHandler)
//--- Protected HTML Routes
http.HandleFunc("/logout", authMiddleware(handlers.LogoutHandler))
// Common routes (both admin and volunteer can access)
http.HandleFunc("/profile", authMiddleware(handlers.ProfileHandler))
http.HandleFunc("/profile/update", authMiddleware(handlers.ProfileUpdateHandler))
//--- Admin-only routes
http.HandleFunc("/dashboard", adminMiddleware(handlers.AdminDashboardHandler))
http.HandleFunc("/volunteers", adminMiddleware(handlers.VolunteerHandler))
http.HandleFunc("/volunteer/edit", adminMiddleware(handlers.EditVolunteerHandler))
http.HandleFunc("/team_builder", adminMiddleware(handlers.TeamBuilderHandler))
http.HandleFunc("/team_builder/remove_volunteer", adminMiddleware(handlers.RemoveVolunteerHandler))
http.HandleFunc("/addresses", adminMiddleware(handlers.AddressHandler))
http.HandleFunc("/assign_address", adminMiddleware(handlers.AssignAddressHandler))
http.HandleFunc("/remove_assigned_address", adminMiddleware(handlers.RemoveAssignedAddressHandler))
http.HandleFunc("/addresses/upload-csv", adminMiddleware(handlers.CSVUploadHandler))
http.HandleFunc("/reports", adminMiddleware(handlers.ReportsHandler))
http.HandleFunc("/posts", adminMiddleware(handlers.PostsHandler))
// Assignment management routes (Admin only)
// API Routes
http.HandleFunc("/api/validated-addresses", handlers.GetValidatedAddressesHandler)
http.HandleFunc("/api/validated-addresses/stats", handlers.GetValidatedAddressesStatsHandler)
//--- Volunteer-only routes
http.HandleFunc("/volunteer/dashboard", volunteerMiddleware(handlers.VolunteerPostsHandler))
http.HandleFunc("/volunteer/addresses", volunteerMiddleware(handlers.VolunteerAppointmentHandler))
// Schedule/Availability routes (Volunteer only)
http.HandleFunc("/volunteer/schedule", volunteerMiddleware(handlers.VolunteerGetAvailabilityHandler))
http.HandleFunc("/volunteer/schedule/post", volunteerMiddleware(handlers.VolunteerPostScheduleHandler))
http.HandleFunc("/volunteer/schedule/delete", volunteerMiddleware(handlers.VolunteerDeleteScheduleHandler))
// Poll routes (volunteer only)
http.HandleFunc("/poll", volunteerMiddleware(handlers.PollHandler))
log.Println("Server started on http://localhost:8080")
log.Fatal(http.ListenAndServe("0.0.0.0:8080", nil))
}