package routes import ( "bytes" "context" "database/sql" "errors" "fmt" "foobar/database" "foobar/model" "foobar/views" "net/http" "os" "path/filepath" "text/template" "github.com/prometheus/client_golang/prometheus/promhttp" "golang.org/x/crypto/bcrypt" ) const noRedirect redirectURL = "" var ( mux *http.ServeMux = nil errBoxNotFound error = fmt.Errorf("box id not found") staticDir string = filepath.Join("views", "static") ) var readmeTemplate model.Markdown func init() { mux = http.NewServeMux() if err := os.MkdirAll(staticDir, 777); err != nil { panic(err) } mux.Handle("/static/", http.StripPrefix("/static/", http.FileServerFS(os.DirFS(staticDir)))) mux.HandleFunc("/", index) mux.HandleFunc("POST /box/{box}", redirectHtmxFormMiddleware(fileUpload)) mux.HandleFunc("GET /box/{box}", getRouteMiddleware(boxUpload)) mux.HandleFunc("GET /box/{box}/inside", getRouteMiddleware(checkBox)) mux.HandleFunc("/panic", func(w http.ResponseWriter, r *http.Request) { panic("não implementado") }) mux.Handle("/metrics", promhttp.Handler()) var buf bytes.Buffer err := template.Must(template.ParseFiles(filepath.Join(staticDir, "default", "README.md"))). Execute(&buf, nil) if err != nil { panic(err) } readmeTemplate = mdToHTML(buf.Bytes()) } func Mux() http.Handler { return logging(mux) } func notFound(w http.ResponseWriter) { w.WriteHeader(404) if err := views.FourOfour().Render(context.Background(), w); err != nil { logInternalError(w, err) return } } func index(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/index.html" && r.URL.Path != "/" || r.Method != "GET" { notFound(w) return } if err := views.Index().Render(context.Background(), w); err != nil { logInternalError(w, err) return } } func GetBoxURL(r *http.Request) (model.BoxURL, error) { return model.CheckBoxURL(r.PathValue("box")) } // func sobre(w http.ResponseWriter, r *http.Request) { // if err := views.Sobre().Render(context.Background(), w); err != nil { // logInternalError(w, err) // return // } // } // func logIn(w http.ResponseWriter, r *http.Request) { // // _, err := currentUser(r) // // userLogged := err == nil // // if userLogged { // http.Redirect(w, r, "/logged", http.StatusFound) // return // } // // if err := views.Login().Render(context.Background(), w); err != nil { // logInternalError(w, err) // return // } // } func logInPOST(w http.ResponseWriter, r *http.Request) (redirectURL, error) { email := r.FormValue("email") if email == "" { return "", formValueMissing("email", r) } senha := r.FormValue("senha") if senha == "" { return "", formValueMissing("senha", r) } tx := database.MustBeginTx() defer tx.Rollback() usuario, err := database.VerifyUser(tx, email, senha) if err != nil { if errors.Is(err, sql.ErrNoRows) || errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) { return "", newUserError("senha ou email não conferem") } else { return "", err } } session, err := store.Get(r, sessionIdCookie) if err != nil { return "", err } userId, err := usuario.Id() if err != nil { return "", err } session.Values["userId"] = userId session.Options.SameSite = http.SameSiteDefaultMode if err := session.Save(r, w); err != nil { return "", err } return "/logged", nil } func logged(w http.ResponseWriter, r *http.Request) { usuario, err := currentUser(r) if err != nil { logError(err) w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Não Autorizado.")) return } if err = views.Logged(usuario).Render(context.Background(), w); err != nil { logInternalError(w, err) return } } func logout(w http.ResponseWriter, r *http.Request) { session, err := store.Get(r, sessionIdCookie) if err != nil { logInternalError(w, err) return } session.Options.MaxAge = -1 if err = session.Save(r, w); err != nil { logInternalError(w, err) return } http.Redirect(w, r, "/login", http.StatusFound) }