|
|
|
@ -18,7 +18,7 @@ import (
|
|
|
|
"github.com/creack/ehttp"
|
|
|
|
"github.com/creack/ehttp"
|
|
|
|
|
|
|
|
|
|
|
|
// JWT stuff
|
|
|
|
// JWT stuff
|
|
|
|
// "github.com/auth0/go-jwt-middleware"
|
|
|
|
"github.com/auth0/go-jwt-middleware"
|
|
|
|
"github.com/dgrijalva/jwt-go"
|
|
|
|
"github.com/dgrijalva/jwt-go"
|
|
|
|
|
|
|
|
|
|
|
|
// form validation
|
|
|
|
// form validation
|
|
|
|
@ -35,18 +35,18 @@ import (
|
|
|
|
type User struct {
|
|
|
|
type User struct {
|
|
|
|
gorm.Model
|
|
|
|
gorm.Model
|
|
|
|
|
|
|
|
|
|
|
|
Name string `valid:"alphanum,required"`
|
|
|
|
Name string `valid:"alphanum,required" sql:"unique"`
|
|
|
|
Pass string `valid:"runelength(8|999),required"`
|
|
|
|
Pass string `valid:"runelength(8|999),required"`
|
|
|
|
Salt string `valid:"optional"`
|
|
|
|
Salt string `valid:"optional"`
|
|
|
|
Email string `valid:"email,required"`
|
|
|
|
Email string `valid:"email,required" sql:"unique"`
|
|
|
|
Lists []List
|
|
|
|
Lists []List
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type List struct {
|
|
|
|
type List struct {
|
|
|
|
gorm.Model
|
|
|
|
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"`
|
|
|
|
Icon string `valid:"alphanum,optional"`
|
|
|
|
Items []Item
|
|
|
|
Items []Item
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -142,12 +142,12 @@ func register(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check if users already exists
|
|
|
|
// 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("name = ?", input.Name).Count(&countName)
|
|
|
|
db.Model(&User{}).Where("email = ?", input.Email).Count(&countEmail)
|
|
|
|
db.Model(&User{}).Where("email = ?", input.Email).Count(&countEmail)
|
|
|
|
if countName != 0 || countEmail != 0{
|
|
|
|
if countName != 0 || countEmail != 0{
|
|
|
|
return ehttp.NewErrorf(http.StatusConflict, "username or email already exists")
|
|
|
|
return ehttp.NewErrorf(http.StatusConflict, "username or email already exists")
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
// Generate salt
|
|
|
|
// Generate salt
|
|
|
|
salt := make([]byte, 64)
|
|
|
|
salt := make([]byte, 64)
|
|
|
|
@ -165,16 +165,58 @@ func register(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
input.Pass = string(hash)
|
|
|
|
input.Pass = string(hash)
|
|
|
|
|
|
|
|
|
|
|
|
// add to database
|
|
|
|
// add to database
|
|
|
|
ret := db.NewRecord(input)
|
|
|
|
db.NewRecord(input)
|
|
|
|
if ret != true {
|
|
|
|
retCreate := db.Create(&input)
|
|
|
|
|
|
|
|
if retCreate.Error != nil {
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not create user", err)
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not create user", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
db.Create(&input)
|
|
|
|
|
|
|
|
log.Println("registered user", input.Name)
|
|
|
|
log.Println("registered user", input.Name)
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
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() {
|
|
|
|
func main() {
|
|
|
|
var err error
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
|
|
@ -185,6 +227,14 @@ func main() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
db.LogMode(false)
|
|
|
|
db.LogMode(false)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 …
|
|
|
|
// Create or update schemas …
|
|
|
|
db.AutoMigrate(&User{})
|
|
|
|
db.AutoMigrate(&User{})
|
|
|
|
@ -205,23 +255,23 @@ func main() {
|
|
|
|
// TODO: delete, modify
|
|
|
|
// TODO: delete, modify
|
|
|
|
|
|
|
|
|
|
|
|
// List Management
|
|
|
|
// List Management
|
|
|
|
r.Handle("/lists", ehttp.HandlerFunc(nil)).Methods("POST") // Make a new list
|
|
|
|
r.Handle("/lists", jwt.Handler(ehttp.HandlerFunc(createList))).Methods("POST") // Make a new list
|
|
|
|
r.Handle("/lists", ehttp.HandlerFunc(nil)).Methods("GET") // Get list of lists
|
|
|
|
r.Handle("/lists", jwt.Handler(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}", jwt.Handler(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}", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("DELETE") // Delete a list
|
|
|
|
r.Handle("/lists/{name}", ehttp.HandlerFunc(nil)).Methods("GET") // Get list content (i.e., items)
|
|
|
|
r.Handle("/lists/{name}", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("GET") // Get list content (i.e., items)
|
|
|
|
// List sharing
|
|
|
|
// List sharing
|
|
|
|
r.Handle("/lists/{name}/sharers", ehttp.HandlerFunc(nil)).Methods("POST") // Add new sharer
|
|
|
|
r.Handle("/lists/{name}/sharers", jwt.Handler(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", jwt.Handler(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}/sharers/{user}", jwt.Handler(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", jwt.Handler(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}", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("DELETE") // Delete item
|
|
|
|
r.Handle("/lists/{name}/items/{item}", ehttp.HandlerFunc(nil)).Methods("POST") // Update 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)
|
|
|
|
// 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", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("POST") // Make a new unit
|
|
|
|
r.Handle("/units", ehttp.HandlerFunc(nil)).Methods("GET") // Get list of units
|
|
|
|
r.Handle("/units", jwt.Handler(ehttp.HandlerFunc(nil))).Methods("GET") // Get list of units
|
|
|
|
|
|
|
|
|
|
|
|
loggedRouter := handlers.LoggingHandler(os.Stdout, r)
|
|
|
|
loggedRouter := handlers.LoggingHandler(os.Stdout, r)
|
|
|
|
http.Handle("/", loggedRouter)
|
|
|
|
http.Handle("/", loggedRouter)
|
|
|
|
|