diff --git a/models/error.go b/models/error.go index 83378c37..4c2bdf53 100644 --- a/models/error.go +++ b/models/error.go @@ -122,4 +122,24 @@ func IsErrIDCannotBeZero(err error) bool { func (err ErrIDCannotBeZero) Error() string { return fmt.Sprintf("ID cannot be 0") +} + +// =========== +// List errors +// =========== + + +// ErrListDoesNotExist represents a "ErrListDoesNotExist" kind of error. Used if the list does not exist. +type ErrListDoesNotExist struct{ + ID int64 +} + +// IsErrListDoesNotExist checks if an error is a ErrListDoesNotExist. +func IsErrListDoesNotExist(err error) bool { + _, ok := err.(ErrListDoesNotExist) + return ok +} + +func (err ErrListDoesNotExist) Error() string { + return fmt.Sprintf("List does not exist [ID: %d]", err.ID) } \ No newline at end of file diff --git a/models/lists.go b/models/lists.go new file mode 100644 index 00000000..957e0f6e --- /dev/null +++ b/models/lists.go @@ -0,0 +1,53 @@ +package models + +type List struct { + ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"` + Title string `xorm:"varchar(250)" json:"title"` + Description string `xorm:"varchar(1000)" json:"description"` + OwnerID int64 `xorm:"int(11)" json:"ownerID"` + Owner User `xorm:"-" json:"owner"` + Created int64 `xorm:"created" json:"created"` + Updated int64 `xorm:"updated" json:"updated"` +} + +func GetListByID(id int64) (list List, err error){ + list.ID = id + exists, err := x.Get(&list) + if err != nil { + return List{}, err + } + + if !exists { + return List{}, ErrListDoesNotExist{ID: id} + } + + // Get the list owner + user, _, err := GetUserByID(list.OwnerID) + if err != nil { + return List{}, err + } + + list.Owner = user + + return list, nil +} + +func CreateOrUpdateList(list *List) (err error) { + // Check if it exists + _, err = GetListByID(list.ID) + if err != nil { + return + } + + list.OwnerID = list.Owner.ID + + if list.ID == 0 { + _, err = x.Insert(list) + } else { + _, err = x.ID(list.ID).Update(list) + return + } + + return + +} diff --git a/models/models.go b/models/models.go index de04002b..2ecedfc1 100644 --- a/models/models.go +++ b/models/models.go @@ -8,7 +8,11 @@ import ( _ "github.com/mattn/go-sqlite3" // Because. ) -var x *xorm.Engine +var ( + x *xorm.Engine + + tables []interface{} +) func getEngine() (*xorm.Engine, error) { // Use Mysql if set @@ -26,6 +30,13 @@ func getEngine() (*xorm.Engine, error) { return xorm.NewEngine("sqlite3", path) } +func init() { + tables = append(tables, + new(User), + new(List), + ) +} + // SetEngine sets the xorm.Engine func SetEngine() (err error) { x, err = getEngine() @@ -40,7 +51,9 @@ func SetEngine() (err error) { x.SetMapper(core.GonicMapper{}) // Sync dat shit - x.Sync(&User{}) + if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil { + return fmt.Errorf("sync database struct error: %v", err) + } x.ShowSQL(Config.Database.ShowQueries) diff --git a/models/user_add_update.go b/models/user_add_update.go index b4e9582b..d1e7a1be 100644 --- a/models/user_add_update.go +++ b/models/user_add_update.go @@ -16,7 +16,7 @@ func CreateUser(user User) (newUser User, err error) { // Check if the user already existst with that username existingUser, exists, err := GetUser(User{Username: newUser.Username}) - if err != nil && !IsErrUserDoesNotExist(err){ + if err != nil && !IsErrUserDoesNotExist(err) { return User{}, err } if exists { diff --git a/routes/api/v1/lists_add_update.go b/routes/api/v1/lists_add_update.go new file mode 100644 index 00000000..734c8974 --- /dev/null +++ b/routes/api/v1/lists_add_update.go @@ -0,0 +1,75 @@ +package v1 + +import ( + "net/http" + "github.com/labstack/echo" + "git.kolaente.de/konrad/list/models" + "strconv" + "fmt" +) + +func AddOrUpdateList(c echo.Context) error { + + // Get the list + var list *models.List + + if err := c.Bind(&list); err != nil { + return c.JSON(http.StatusBadRequest, models.Message{"No list model provided."}) + } + + // Check if we have an ID other than the one in the struct + id := c.Param("id") + if id != "" { + // Make int + listID, err := strconv.ParseInt(id, 10, 64) + + if err != nil { + return c.JSON(http.StatusBadRequest, models.Message{"Invalid ID."}) + } + list.ID = listID + } + + // Check if the list exists + // ID = 0 means new list, no error + if list.ID != 0 { + _, err := models.GetListByID(list.ID) + if err != nil { + if models.IsErrListDoesNotExist(err) { + return c.JSON(http.StatusBadRequest, models.Message{"The list does not exist."}) + } else { + return c.JSON(http.StatusInternalServerError, models.Message{"Could not check if the list exists."}) + } + } + } + + // Get the current user for later checks + user, err := models.GetCurrentUser(c) + if err != nil { + return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) + } + list.Owner = user + + // update or create... + if list.ID == 0 { + err = models.CreateOrUpdateList(list) + if err != nil { + return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) + } + } else { + // Check if the user owns the list + oldList, err := models.GetListByID(list.ID) + if err != nil { + return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) + } + if user.ID != oldList.Owner.ID { + return c.JSON(http.StatusForbidden, models.Message{"You cannot edit a list you don't own."}) + } + + err = models.CreateOrUpdateList(list) + if err != nil { + return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) + } + } + + return c.JSON(http.StatusOK, list) +} \ No newline at end of file diff --git a/routes/api/v1/user_add_update.go b/routes/api/v1/user_add_update.go index f88dc64c..0e744525 100644 --- a/routes/api/v1/user_add_update.go +++ b/routes/api/v1/user_add_update.go @@ -7,7 +7,6 @@ import ( "net/http" "strconv" "strings" - "fmt" ) // UserAddOrUpdate is the handler to add a user @@ -52,8 +51,6 @@ func UserAddOrUpdate(c echo.Context) error { return c.JSON(http.StatusInternalServerError, models.Message{"Could not check if the user exists."}) } - fmt.Println(exists) - // Insert or update the user var newUser models.User if exists { diff --git a/routes/routes.go b/routes/routes.go index aa1df201..571a4016 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -50,4 +50,7 @@ func RegisterRoutes(e *echo.Echo) { // Authetification a.Use(middleware.JWT(models.Config.JWTLoginSecret)) a.POST("/tokenTest", apiv1.CheckToken) + + a.PUT("/lists", apiv1.AddOrUpdateList) + a.POST("/lists/:id", apiv1.AddOrUpdateList) }