2020-04-10 04:40:22 +02:00
|
|
|
package router
|
|
|
|
|
|
|
|
import (
|
2020-06-13 00:21:58 +02:00
|
|
|
"database/sql"
|
|
|
|
"encoding/json"
|
|
|
|
"io/ioutil"
|
2020-04-10 04:40:22 +02:00
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/go-chi/chi"
|
|
|
|
"github.com/go-chi/chi/middleware"
|
|
|
|
"github.com/go-chi/cors"
|
2020-06-13 00:21:58 +02:00
|
|
|
"github.com/google/uuid"
|
2020-04-10 04:40:22 +02:00
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
|
|
|
|
"github.com/jordanknott/project-citadel/api/graph"
|
|
|
|
"github.com/jordanknott/project-citadel/api/pg"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (h *CitadelHandler) PingHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
w.Write([]byte("pong"))
|
|
|
|
}
|
|
|
|
|
2020-06-13 00:21:58 +02:00
|
|
|
func (h *CitadelHandler) ProfileImageUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
|
log.Info("preparing to upload file")
|
|
|
|
userID, ok := r.Context().Value("userID").(uuid.UUID)
|
|
|
|
if !ok {
|
|
|
|
log.Error("not a valid uuid")
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse our multipart form, 10 << 20 specifies a maximum
|
|
|
|
// upload of 10 MB files.
|
|
|
|
r.ParseMultipartForm(10 << 20)
|
|
|
|
|
|
|
|
file, handler, err := r.FormFile("file")
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("issue while uploading file")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
log.WithFields(log.Fields{"filename": handler.Filename, "size": handler.Size, "header": handler.Header}).Info("file metadata")
|
|
|
|
|
|
|
|
fileBytes, err := ioutil.ReadAll(file)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("while reading file")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
err = ioutil.WriteFile("uploads/"+handler.Filename, fileBytes, 0644)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("while reading file")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.repo.UpdateUserAccountProfileAvatarURL(r.Context(), pg.UpdateUserAccountProfileAvatarURLParams{UserID: userID, ProfileAvatarUrl: sql.NullString{String: "http://localhost:3333/uploads/" + handler.Filename, Valid: true}})
|
|
|
|
// return that we have successfully uploaded our file!
|
|
|
|
log.Info("file uploaded")
|
|
|
|
json.NewEncoder(w).Encode(AvatarUploadResponseData{URL: "http://localhost:3333/uploads/" + handler.Filename, UserID: userID.String()})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-04-10 04:40:22 +02:00
|
|
|
func NewRouter(db *sqlx.DB) (chi.Router, error) {
|
|
|
|
formatter := new(log.TextFormatter)
|
|
|
|
formatter.TimestampFormat = "02-01-2006 15:04:05"
|
|
|
|
formatter.FullTimestamp = true
|
|
|
|
|
|
|
|
routerLogger := log.New()
|
2020-04-10 05:27:57 +02:00
|
|
|
routerLogger.SetLevel(log.DebugLevel)
|
2020-04-10 04:40:22 +02:00
|
|
|
routerLogger.Formatter = formatter
|
|
|
|
r := chi.NewRouter()
|
|
|
|
cors := cors.New(cors.Options{
|
|
|
|
// AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
|
|
|
|
AllowedOrigins: []string{"*"},
|
|
|
|
// AllowOriginFunc: func(r *http.Request, origin string) bool { return true },
|
|
|
|
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
|
|
|
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "Cookie"},
|
|
|
|
ExposedHeaders: []string{"Link"},
|
|
|
|
AllowCredentials: true,
|
|
|
|
MaxAge: 300, // Maximum value not ignored by any of major browsers
|
|
|
|
})
|
|
|
|
r.Use(cors.Handler)
|
|
|
|
r.Use(middleware.RequestID)
|
|
|
|
r.Use(middleware.RealIP)
|
|
|
|
r.Use(NewStructuredLogger(routerLogger))
|
|
|
|
r.Use(middleware.Recoverer)
|
|
|
|
r.Use(middleware.Timeout(60 * time.Second))
|
|
|
|
|
|
|
|
repository := pg.NewRepository(db)
|
|
|
|
citadelHandler := CitadelHandler{repository}
|
|
|
|
|
|
|
|
r.Group(func(mux chi.Router) {
|
|
|
|
mux.Mount("/auth", authResource{}.Routes(citadelHandler))
|
|
|
|
mux.Handle("/__graphql", graph.NewPlaygroundHandler("/graphql"))
|
2020-06-13 00:21:58 +02:00
|
|
|
var imgServer = http.FileServer(http.Dir("./uploads/"))
|
|
|
|
mux.Mount("/uploads/", http.StripPrefix("/uploads/", imgServer))
|
|
|
|
|
2020-04-10 04:40:22 +02:00
|
|
|
})
|
|
|
|
r.Group(func(mux chi.Router) {
|
|
|
|
mux.Use(AuthenticationMiddleware)
|
2020-06-13 00:21:58 +02:00
|
|
|
mux.Post("/users/me/avatar", citadelHandler.ProfileImageUpload)
|
2020-04-10 04:40:22 +02:00
|
|
|
mux.Get("/ping", citadelHandler.PingHandler)
|
|
|
|
mux.Handle("/graphql", graph.NewHandler(repository))
|
|
|
|
})
|
|
|
|
|
|
|
|
return r, nil
|
|
|
|
}
|