From 2c90ef615153fa09f46da26390c93709ad3aa471 Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Fri, 4 Aug 2017 10:23:58 +0200 Subject: [PATCH] Add createList --- server/main.go | 154 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 52 deletions(-) diff --git a/server/main.go b/server/main.go index 77882ce..d275720 100644 --- a/server/main.go +++ b/server/main.go @@ -18,7 +18,7 @@ import ( "github.com/creack/ehttp" // JWT stuff - // "github.com/auth0/go-jwt-middleware" + "github.com/auth0/go-jwt-middleware" "github.com/dgrijalva/jwt-go" // form validation @@ -35,18 +35,18 @@ import ( type User struct { gorm.Model - Name string `valid:"alphanum,required"` + Name string `valid:"alphanum,required" sql:"unique"` Pass string `valid:"runelength(8|999),required"` Salt string `valid:"optional"` - Email string `valid:"email,required"` + Email string `valid:"email,required" sql:"unique"` Lists []List } type List struct { gorm.Model - UserID uint + UserID uint `gorm:"unique_index:idx_userid_name"` - Name string `valid:"alphanum,required"` + Name string `valid:"alphanum,required" gorm:"unique_index:idx_userid_name"` Icon string `valid:"alphanum,optional"` Items []Item } @@ -142,12 +142,12 @@ func register(w http.ResponseWriter, r *http.Request) error { } // Check if users already exists - countName := 0; countEmail := 0 + /*countName := 0; countEmail := 0 db.Model(&User{}).Where("name = ?", input.Name).Count(&countName) db.Model(&User{}).Where("email = ?", input.Email).Count(&countEmail) if countName != 0 || countEmail != 0{ return ehttp.NewErrorf(http.StatusConflict, "username or email already exists") - } + }*/ // Generate salt salt := make([]byte, 64) @@ -165,16 +165,58 @@ func register(w http.ResponseWriter, r *http.Request) error { input.Pass = string(hash) // add to database - ret := db.NewRecord(input) - if ret != true { + db.NewRecord(input) + retCreate := db.Create(&input) + if retCreate.Error != nil { return ehttp.NewErrorf(http.StatusInternalServerError, "could not create user", err) } - db.Create(&input) log.Println("registered user", input.Name) return nil } +func createList(w http.ResponseWriter, r *http.Request) error { + decoder := schema.NewDecoder() + decoder.IgnoreUnknownKeys(true) + + // Parse http request to request-struct + err := r.ParseForm() + if err != nil { + return ehttp.NewErrorf(http.StatusInternalServerError, "could not parse form", err) + } + + // Decode request into struct + var input List + err = decoder.Decode(&input, r.PostForm) + if err != nil { + return ehttp.NewErrorf(http.StatusInternalServerError, "could not decode ", err) + } + + // Validate struct + res, err := govalidator.ValidateStruct(input) + if err != nil || res != true { + return ehttp.NewErrorf(http.StatusBadRequest, "could not validate your data", err) + } + + // Find request-corresponding user + // TODO: push into middleware? + userName := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)["name"].(string) + user := User{Name: userName} + db.Where(&user).First(&user) + if user.ID == 0 { // TODO: ugly way to check for user-not-found + return ehttp.NewErrorf(http.StatusForbidden, "cannot find claimed user") + } + + // create the new list + db.NewRecord(&input) + ret := db.Create(&input) + if ret.Error != nil { + return ehttp.NewErrorf(http.StatusInternalServerError, "cannot create list in db") + } + + return nil +} + func main() { var err error @@ -185,46 +227,54 @@ func main() { } db.LogMode(false) - - // Create or update schemas … - db.AutoMigrate(&User{}) - db.AutoMigrate(&List{}) - db.AutoMigrate(&Item{}) - db.AutoMigrate(&Unit{}) - db.Model(&User{}).Related(&List{}) - db.Model(&List{}).Related(&Item{}) - db.Model(&Item{}).Related(&Unit{}) - defer db.Close() - - // define URL handlers - r := mux.NewRouter() - - // User Management - r.Handle("/users", ehttp.HandlerFunc(register)).Methods("POST") // Make new user - r.Handle("/users", ehttp.HandlerFunc(getToken)).Methods("GET") // Get user „info“(=token) - // TODO: delete, modify - - // List Management - r.Handle("/lists", ehttp.HandlerFunc(nil)).Methods("POST") // Make a new list - r.Handle("/lists", ehttp.HandlerFunc(nil)).Methods("GET") // Get list of lists - r.Handle("/lists/{name}", ehttp.HandlerFunc(nil)).Methods("PUT") // Update list (name, icon, …) - r.Handle("/lists/{name}", ehttp.HandlerFunc(nil)).Methods("DELETE") // Delete a list - r.Handle("/lists/{name}", ehttp.HandlerFunc(nil)).Methods("GET") // Get list content (i.e., items) - // List sharing - r.Handle("/lists/{name}/sharers", ehttp.HandlerFunc(nil)).Methods("POST") // Add new sharer - r.Handle("/lists/{name}/sharers", ehttp.HandlerFunc(nil)).Methods("GET") // Get list of sharers - r.Handle("/lists/{name}/sharers/{user}", ehttp.HandlerFunc(nil)).Methods("DELETE") // Remove sharer - - r.Handle("/lists/{name}/items", ehttp.HandlerFunc(nil)).Methods("PUT") // Add new item - r.Handle("/lists/{name}/items/{item}", ehttp.HandlerFunc(nil)).Methods("DELETE") // Delete item - r.Handle("/lists/{name}/items/{item}", ehttp.HandlerFunc(nil)).Methods("POST") // Update item - - // Unit-history (unit is a ever-growing list only used for auto-completion) - r.Handle("/units", ehttp.HandlerFunc(nil)).Methods("POST") // Make a new unit - r.Handle("/units", ehttp.HandlerFunc(nil)).Methods("GET") // Get list of units - - loggedRouter := handlers.LoggingHandler(os.Stdout, r) - http.Handle("/", loggedRouter) - http.ListenAndServe(":8000", nil) -} + jwt := jwtmiddleware.New(jwtmiddleware.Options{ + Extractor: func(r *http.Request) (string,error) { + r.ParseForm() + return r.Form["token"][0], nil + }, + ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) { + return []byte("TODO"), nil + }}) + + // Create or update schemas … + db.AutoMigrate(&User{}) + db.AutoMigrate(&List{}) + db.AutoMigrate(&Item{}) + db.AutoMigrate(&Unit{}) + db.Model(&User{}).Related(&List{}) + db.Model(&List{}).Related(&Item{}) + db.Model(&Item{}).Related(&Unit{}) + defer db.Close() + + // define URL handlers + r := mux.NewRouter() + + // User Management + r.Handle("/users", ehttp.HandlerFunc(register)).Methods("POST") // Make new user + r.Handle("/users", ehttp.HandlerFunc(getToken)).Methods("GET") // Get user „info“(=token) + // TODO: delete, modify + + // List Management + r.Handle("/lists", jwt.Handler(ehttp.HandlerFunc(createList))).Methods("POST") // Make a new list + r.Handle("/lists", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("GET") // Get list of lists + r.Handle("/lists/{name}", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("PUT") // Update list (name, icon, …) + r.Handle("/lists/{name}", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("DELETE") // Delete a list + r.Handle("/lists/{name}", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("GET") // Get list content (i.e., items) + // List sharing + r.Handle("/lists/{name}/sharers", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("POST") // Add new sharer + r.Handle("/lists/{name}/sharers", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("GET") // Get list of sharers + r.Handle("/lists/{name}/sharers/{user}", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("DELETE") // Remove sharer + + r.Handle("/lists/{name}/items", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("PUT") // Add new item + r.Handle("/lists/{name}/items/{item}", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("DELETE") // Delete item + r.Handle("/lists/{name}/items/{item}", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("POST") // Update item + + // Unit-history (unit is a ever-growing list only used for auto-completion) + r.Handle("/units", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("POST") // Make a new unit + r.Handle("/units", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("GET") // Get list of units + + loggedRouter := handlers.LoggingHandler(os.Stdout, r) + http.Handle("/", loggedRouter) + http.ListenAndServe(":8000", nil) + }