package main import ( "fmt" "net/http" "git.phc.dm.unipi.it/aziis98/posti-dm/server/auth" "git.phc.dm.unipi.it/aziis98/posti-dm/server/db" "git.phc.dm.unipi.it/aziis98/posti-dm/server/httputil" "git.phc.dm.unipi.it/aziis98/posti-dm/server/util" "github.com/alecthomas/repr" "github.com/go-chi/chi/v5" ) type Server struct { sessions map[string]*db.User authService *auth.AuthService Database db.Store ApiRoute chi.Router } func NewServer() *Server { server := &Server{ sessions: make(map[string]*db.User), Database: db.NewInMemoryStore(), ApiRoute: chi.NewRouter(), } server.authService = &auth.AuthService{ CheckUserPassword: func(userID, password string) error { repr.Println("Sessions: ", server.sessions) if password != "phc" { return fmt.Errorf(`invalid password`) } return nil }, UserPermissions: func(userID string) ([]string, error) { user, err := server.Database.GetUser(userID) if err != nil { return nil, err } return user.Permissions, nil }, SessionTokenFromUser: func(userID string) (string, error) { user, err := server.Database.GetUser(userID) if err != nil { return "", err } token := util.RandomHash(10) server.sessions[token] = user return token, nil }, UserFromSessionToken: func(session string) (string, error) { user, present := server.sessions[session] if !present { return "", auth.ErrNoUserForSession } return user.ID, nil }, AuthenticationFailed: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, `not authenticated`, http.StatusUnauthorized) }), OtherError: func(err error) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) }) }, } server.setupRoutes() return server } func (server *Server) setupRoutes() { api := server.ApiRoute db := server.Database // Authenticated Routes api.Post("/login", func(w http.ResponseWriter, r *http.Request) { var credentials struct { Username string `json:"username"` Password string `json:"password"` } if err := httputil.ReadJSON(r, &credentials); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } server.authService.Login(w, r, credentials.Username, credentials.Password) }) api.With(server.authService.LoggedMiddleware()). Post("/logout", func(w http.ResponseWriter, r *http.Request) { server.authService.Logout(w) }) api.With(server.authService.LoggedMiddleware()). Get("/current-seat", func(w http.ResponseWriter, r *http.Request) { userID, err := server.authService.UserFromSession(r) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } occupiedSeatID, err := db.GetUserSeat(userID) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if len(occupiedSeatID) == 0 { httputil.WriteJSON(w, nil) return } seat, err := db.GetSeat(occupiedSeatID[0]) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } httputil.WriteJSON(w, seat) }) }