diff --git a/models/crudable.go b/models/crudable.go index d009eebb36..206c9b34a2 100644 --- a/models/crudable.go +++ b/models/crudable.go @@ -1,7 +1,8 @@ package models +// CRUDable defines the crud methods type CRUDable interface { - Create(*User) (error) + Create(*User) error ReadOne(int64) error ReadAll(*User) (interface{}, error) Update(int64, *User) error diff --git a/models/error.go b/models/error.go index 584df6fb97..e6f2b1b125 100644 --- a/models/error.go +++ b/models/error.go @@ -149,7 +149,7 @@ type ErrNeedToBeListAdmin struct { UserID int64 } -// IsErrListDoesNotExist checks if an error is a ErrListDoesNotExist. +// IsErrNeedToBeListAdmin checks if an error is a ErrListDoesNotExist. func IsErrNeedToBeListAdmin(err error) bool { _, ok := err.(ErrNeedToBeListAdmin) return ok @@ -176,12 +176,12 @@ func (err ErrListItemCannotBeEmpty) Error() string { return fmt.Sprintf("List item text cannot be empty.") } -// ErrListItemCannotBeEmpty represents a "ErrListDoesNotExist" kind of error. Used if the list does not exist. +// ErrListItemDoesNotExist represents a "ErrListDoesNotExist" kind of error. Used if the list does not exist. type ErrListItemDoesNotExist struct { ID int64 } -// IsErrListItemCannotBeEmpty checks if an error is a ErrListDoesNotExist. +// IsErrListItemDoesNotExist checks if an error is a ErrListDoesNotExist. func IsErrListItemDoesNotExist(err error) bool { _, ok := err.(ErrListItemDoesNotExist) return ok @@ -232,7 +232,7 @@ type ErrNeedToBeNamespaceOwner struct { UserID int64 } -// IsErrNamespaceDoesNotExist checks if an error is a ErrNamespaceDoesNotExist. +// IsErrNeedToBeNamespaceOwner checks if an error is a ErrNamespaceDoesNotExist. func IsErrNeedToBeNamespaceOwner(err error) bool { _, ok := err.(ErrNeedToBeNamespaceOwner) return ok @@ -289,4 +289,3 @@ func IsErrUserDoesNotHaveWriteAccessToNamespace(err error) bool { func (err ErrUserDoesNotHaveWriteAccessToNamespace) Error() string { return fmt.Sprintf("You need to have write access to this namespace to do that [NamespaceID: %d, UserID: %d]", err.NamespaceID, err.UserID) } - diff --git a/models/helper.go b/models/helper.go index 8e55e74e93..b785878bb9 100644 --- a/models/helper.go +++ b/models/helper.go @@ -1,11 +1,11 @@ package models import ( - "fmt" "github.com/labstack/echo" "strconv" ) +// GetIntURLParam is a helper method which returns an int from an url param func GetIntURLParam(param string, c echo.Context) (intParam int64, err error) { id := c.Param(param) @@ -16,6 +16,7 @@ func GetIntURLParam(param string, c echo.Context) (intParam int64, err error) { return intParam, err } +// GetByID gets an object by its ID func GetByID(id int64, result interface{}) (err error) { exists, err := x.ID(id).Get(result) if err != nil { @@ -28,9 +29,3 @@ func GetByID(id int64, result interface{}) (err error) { return } - -func GetAllByUser(user *User, result interface{}) (err error) { - fmt.Println(result) - err = x.Where("owner_id = ", user.ID).Find(result) - return -} diff --git a/models/list_create_update.go b/models/list_create_update.go index 5d1ba87cbf..04ba48a6ec 100644 --- a/models/list_create_update.go +++ b/models/list_create_update.go @@ -19,7 +19,8 @@ func CreateOrUpdateList(list *List) (err error) { } -func (l *List) Update(id int64, doer *User) (err error) { +// Update implements the update method of CRUDable +func (l *List) Update(id int64, doer *User) (err error) { l.ID = id // Check if it exists @@ -35,12 +36,13 @@ func (l *List) Update(id int64, doer *User) (err error) { } if !oldList.IsAdmin(&user) { - return ErrNeedToBeListAdmin{ListID:id, UserID:user.ID} + return ErrNeedToBeListAdmin{ListID: id, UserID: user.ID} } return CreateOrUpdateList(l) } +// Create implements the create method of CRUDable func (l *List) Create(doer *User) (err error) { // Check rights user, _, err := GetUserByID(doer.ID) @@ -54,10 +56,10 @@ func (l *List) Create(doer *User) (err error) { return } if !namespace.CanWrite(doer) { - return ErrUserDoesNotHaveWriteAccessToNamespace{UserID:user.ID, NamespaceID:namespace.ID} + return ErrUserDoesNotHaveWriteAccessToNamespace{UserID: user.ID, NamespaceID: namespace.ID} } l.Owner.ID = user.ID return CreateOrUpdateList(l) -} \ No newline at end of file +} diff --git a/models/list_delete.go b/models/list_delete.go index 68a6b1ec4b..2555cd77ed 100644 --- a/models/list_delete.go +++ b/models/list_delete.go @@ -1,5 +1,6 @@ package models +// Delete implements the delete method of CRUDable func (l *List) Delete(id int64, doer *User) (err error) { // Check if the list exists list, err := GetListByID(id) @@ -14,7 +15,7 @@ func (l *List) Delete(id int64, doer *User) (err error) { } if !list.IsAdmin(&user) { - return ErrNeedToBeListAdmin{ListID:id, UserID:user.ID} + return ErrNeedToBeListAdmin{ListID: id, UserID: user.ID} } // Delete the list diff --git a/models/list_items.go b/models/list_items.go index 86b7b8f0ce..53977e6844 100644 --- a/models/list_items.go +++ b/models/list_items.go @@ -70,6 +70,7 @@ func GetItemsByListID(listID int64) (items []*ListItem, err error) { return } +// GetListItemByID returns all items a list has func GetListItemByID(listItemID int64) (listItem ListItem, err error) { exists, err := x.ID(listItemID).Get(&listItem) if err != nil { diff --git a/models/lists.go b/models/lists.go index 14f454257a..62e6b160d4 100644 --- a/models/lists.go +++ b/models/lists.go @@ -15,7 +15,7 @@ type List struct { Updated int64 `xorm:"updated" json:"updated"` CRUDable `xorm:"-" json:"-"` - Rights `xorm:"-" json:"-"` + Rights `xorm:"-" json:"-"` } // Lists is a multiple of list @@ -45,13 +45,14 @@ func GetListByID(id int64) (list List, err error) { return list, nil } +// GetListsByNamespaceID gets all lists in a namespace func GetListsByNamespaceID(nID int64) (lists []*List, err error) { err = x.Where("namespace_id = ?", nID).Find(&lists) return lists, err } // ReadAll gets all List a user has access to -func (list *List) ReadAll(user *User) (interface{}, error) { +func (l *List) ReadAll(user *User) (interface{}, error) { lists := Lists{} fullUser, _, err := GetUserByID(user.ID) if err != nil { @@ -75,6 +76,7 @@ func (l *List) ReadOne(id int64) (err error) { return } +// IsAdmin returns whether the user has admin rights on the list or not func (l *List) IsAdmin(user *User) bool { // Owners are always admins if l.Owner.ID == user.ID { @@ -89,4 +91,4 @@ func (l *List) IsAdmin(user *User) bool { // TODO return false -} \ No newline at end of file +} diff --git a/models/namespace_delete.go b/models/namespace_delete.go index ed6442108a..8acea80d7f 100644 --- a/models/namespace_delete.go +++ b/models/namespace_delete.go @@ -1,5 +1,6 @@ package models +// DeleteNamespaceByID deletes a namespace and takes its id as an argument func DeleteNamespaceByID(namespaceID int64, doer *User) (err error) { // Check if the namespace exists diff --git a/models/namespaces.go b/models/namespaces.go index f99515fe88..59ca578db7 100644 --- a/models/namespaces.go +++ b/models/namespaces.go @@ -13,7 +13,7 @@ type Namespace struct { Updated int64 `xorm:"updated" json:"updated"` CRUDable `xorm:"-" json:"-"` - Rights `xorm:"-" json:"-"` + Rights `xorm:"-" json:"-"` } // TableName makes beautiful table names @@ -39,6 +39,7 @@ const ( NamespaceRightAdmin ) +// IsNamespaceAdmin returns whether the usre has admin rights in a namespace func (user *User) IsNamespaceAdmin(namespace *Namespace) (err error) { // Owners always have admin rights if user.ID == namespace.Owner.ID { @@ -50,6 +51,7 @@ func (user *User) IsNamespaceAdmin(namespace *Namespace) (err error) { return ErrUserNeedsToBeNamespaceAdmin{UserID: user.ID, NamespaceID: namespace.ID} } +// HasNamespaceAccess checks if the User has namespace read access func (user *User) HasNamespaceAccess(namespace *Namespace) (err error) { // Owners always have access if user.ID == namespace.Owner.ID { @@ -61,6 +63,7 @@ func (user *User) HasNamespaceAccess(namespace *Namespace) (err error) { return ErrUserDoesNotHaveAccessToNamespace{UserID: user.ID, NamespaceID: namespace.ID} } +// CanWrite checks if a user has write access to a namespace func (n *Namespace) CanWrite(user *User) bool { if err := user.HasNamespaceAccess(n); err != nil { return false @@ -69,6 +72,7 @@ func (n *Namespace) CanWrite(user *User) bool { return true } +// HasNamespaceWriteAccess checks if a user has write access to a namespace func (user *User) HasNamespaceWriteAccess(namespace *Namespace) (err error) { // Owners always have access @@ -81,6 +85,7 @@ func (user *User) HasNamespaceWriteAccess(namespace *Namespace) (err error) { return ErrUserDoesNotHaveAccessToNamespace{UserID: user.ID, NamespaceID: namespace.ID} } +// GetNamespaceByID returns a namespace object by its ID func GetNamespaceByID(id int64) (namespace Namespace, err error) { namespace.ID = id exists, err := x.Get(&namespace) diff --git a/models/rights.go b/models/rights.go index 5f40f164cb..bdb6ee92d6 100644 --- a/models/rights.go +++ b/models/rights.go @@ -1,5 +1,6 @@ package models +// Rights defines rights methods type Rights interface { IsAdmin(*User) bool CanWrite(*User) bool diff --git a/models/teams.go b/models/teams.go index d644f751f0..83404c00af 100644 --- a/models/teams.go +++ b/models/teams.go @@ -34,7 +34,7 @@ func (TeamMember) TableName() string { return "team_members" } -// TeamNamespaces defines the relationship between a Team and a Namespace +// TeamNamespace defines the relationship between a Team and a Namespace type TeamNamespace struct { ID int64 `xorm:"int(11) autoincr not null unique pk"` TeamID int64 `xorm:"int(11) autoincr not null"` @@ -64,6 +64,7 @@ func (TeamList) TableName() string { return "team_list" } +// GetAllTeamsByNamespaceID returns all teams for a namespace func GetAllTeamsByNamespaceID(id int64) (teams []*Team, err error) { err = x.Table("teams"). Join("INNER", "team_namespaces", "teams.id = team_id"). diff --git a/models/user.go b/models/user.go index 0af090828b..5d5a8aa04d 100644 --- a/models/user.go +++ b/models/user.go @@ -27,15 +27,16 @@ func (User) TableName() string { return "users" } -// ApiUserPassword represents a user object without timestamps and a json password field. -type ApiUserPassword struct { +// APIUserPassword represents a user object without timestamps and a json password field. +type APIUserPassword struct { ID int64 `json:"id"` Username string `json:"username"` Password string `json:"password"` Email string `json:"email"` } -func (apiUser *ApiUserPassword) APIFormat() User { +// APIFormat formats an API User into a normal user struct +func (apiUser *APIUserPassword) APIFormat() User { return User{ ID: apiUser.ID, Username: apiUser.Username, diff --git a/routes/api/v1/item_delete.go b/routes/api/v1/item_delete.go index c6e50bb7aa..ce8ca23e43 100644 --- a/routes/api/v1/item_delete.go +++ b/routes/api/v1/item_delete.go @@ -7,6 +7,7 @@ import ( "strconv" ) +// DeleteListItemByIDtemByID is the web handler to delete a list item func DeleteListItemByIDtemByID(c echo.Context) error { // swagger:operation DELETE /item/{itemID} lists deleteListItem // --- diff --git a/routes/api/v1/list_by_namespace.go b/routes/api/v1/list_by_namespace.go index 28a766f53a..c8a1985bc9 100644 --- a/routes/api/v1/list_by_namespace.go +++ b/routes/api/v1/list_by_namespace.go @@ -6,6 +6,7 @@ import ( "net/http" ) +// GetListsByNamespaceID is the web handler to delete a namespace func GetListsByNamespaceID(c echo.Context) error { // swagger:operation GET /namespaces/{namespaceID}/lists namespaces getListsByNamespace // --- diff --git a/routes/api/v1/list_delete.go b/routes/api/v1/list_delete.go index c246c8c8e6..0211a7eb50 100644 --- a/routes/api/v1/list_delete.go +++ b/routes/api/v1/list_delete.go @@ -1,13 +1,14 @@ package v1 import ( -// "git.kolaente.de/konrad/list/models" + // "git.kolaente.de/konrad/list/models" "github.com/labstack/echo" -// "net/http" -// "strconv" + // "net/http" + // "strconv" "net/http" ) +// DeleteListByID ... func DeleteListByID(c echo.Context) error { // swagger:operation DELETE /lists/{listID} lists deleteList // --- @@ -35,34 +36,34 @@ func DeleteListByID(c echo.Context) error { // "$ref": "#/responses/Message" /* - // Check if we have our ID - id := c.Param("id") - // Make int - itemID, err := strconv.ParseInt(id, 10, 64) - if err != nil { - return c.JSON(http.StatusBadRequest, models.Message{"Invalid ID."}) - } - - // Check if the user has the right to delete that list - user, err := models.GetCurrentUser(c) - if err != nil { - return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) - } - -// err = models.DeleteListByID(itemID, &user) - if err != nil { - if models.IsErrNeedToBeListAdmin(err) { - return c.JSON(http.StatusForbidden, models.Message{"You need to be the list owner to delete a list."}) + // Check if we have our ID + id := c.Param("id") + // Make int + itemID, err := strconv.ParseInt(id, 10, 64) + if err != nil { + return c.JSON(http.StatusBadRequest, models.Message{"Invalid ID."}) } - if models.IsErrListDoesNotExist(err) { - return c.JSON(http.StatusNotFound, models.Message{"This list does not exist."}) + // Check if the user has the right to delete that list + user, err := models.GetCurrentUser(c) + if err != nil { + return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) } - return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) - } + // err = models.DeleteListByID(itemID, &user) + if err != nil { + if models.IsErrNeedToBeListAdmin(err) { + return c.JSON(http.StatusForbidden, models.Message{"You need to be the list owner to delete a list."}) + } - return c.JSON(http.StatusOK, models.Message{"The list was deleted with success."}) + if models.IsErrListDoesNotExist(err) { + return c.JSON(http.StatusNotFound, models.Message{"This list does not exist."}) + } + + return c.JSON(http.StatusInternalServerError, models.Message{"An error occured."}) + } + + return c.JSON(http.StatusOK, models.Message{"The list was deleted with success."}) */ return echo.NewHTTPError(http.StatusNotImplemented) diff --git a/routes/api/v1/list_item_add_update.go b/routes/api/v1/list_item_add_update.go index bf7e973554..1f3e9d7c02 100644 --- a/routes/api/v1/list_item_add_update.go +++ b/routes/api/v1/list_item_add_update.go @@ -7,6 +7,7 @@ import ( "strconv" ) +// AddListItem ... func AddListItem(c echo.Context) error { // swagger:operation PUT /lists/{listID} lists addListItem // --- @@ -46,6 +47,7 @@ func AddListItem(c echo.Context) error { return updateOrCreateListItemHelper(listID, 0, c) } +// UpdateListItem ... func UpdateListItem(c echo.Context) error { // swagger:operation PUT /item/{itemID} lists updateListItem // --- diff --git a/routes/api/v1/lists_add_update.go b/routes/api/v1/lists_add_update.go index 566301084c..813709c6e0 100644 --- a/routes/api/v1/lists_add_update.go +++ b/routes/api/v1/lists_add_update.go @@ -6,6 +6,7 @@ import ( "net/http" ) +// AddList ... func AddList(c echo.Context) error { // swagger:operation PUT /namespaces/{namespaceID}/lists lists addList // --- @@ -86,6 +87,7 @@ func AddList(c echo.Context) error { return c.JSON(http.StatusOK, list) } +// UpdateList ... func UpdateList(c echo.Context) error { // swagger:operation POST /lists/{listID} lists upadteList // --- diff --git a/routes/api/v1/namespace_add_update.go b/routes/api/v1/namespace_add_update.go index 8fc9c0ac70..057e0fe115 100644 --- a/routes/api/v1/namespace_add_update.go +++ b/routes/api/v1/namespace_add_update.go @@ -7,6 +7,7 @@ import ( "strconv" ) +// AddNamespace ... func AddNamespace(c echo.Context) error { // swagger:operation PUT /namespaces namespaces addNamespace // --- @@ -33,6 +34,7 @@ func AddNamespace(c echo.Context) error { return addOrUpdateNamespace(c) } +// UpdateNamespace ... func UpdateNamespace(c echo.Context) error { // swagger:operation POST /namespaces/{namespaceID} namespaces upadteNamespace // --- diff --git a/routes/api/v1/namespace_delete.go b/routes/api/v1/namespace_delete.go index 27669a5a64..129d917783 100644 --- a/routes/api/v1/namespace_delete.go +++ b/routes/api/v1/namespace_delete.go @@ -7,6 +7,7 @@ import ( "strconv" ) +// DeleteNamespaceByID ... func DeleteNamespaceByID(c echo.Context) error { // swagger:operation DELETE /namespaces/{namespaceID} namespaces deleteNamespace // --- diff --git a/routes/api/v1/namespace_show.go b/routes/api/v1/namespace_show.go index 26bc194093..071dcf65d9 100644 --- a/routes/api/v1/namespace_show.go +++ b/routes/api/v1/namespace_show.go @@ -7,6 +7,7 @@ import ( "strconv" ) +// ShowNamespace ... func ShowNamespace(c echo.Context) error { // swagger:operation GET /namespaces/{namespaceID} namespaces getNamespace // --- diff --git a/routes/api/v1/namespaces_list.go b/routes/api/v1/namespaces_list.go index 98bc62a4e5..c641f14a43 100644 --- a/routes/api/v1/namespaces_list.go +++ b/routes/api/v1/namespaces_list.go @@ -6,6 +6,7 @@ import ( "net/http" ) +// GetAllNamespacesByCurrentUser ... func GetAllNamespacesByCurrentUser(c echo.Context) error { // swagger:operation GET /namespaces namespaces getNamespaces // --- diff --git a/routes/api/v1/swagger/options.go b/routes/api/v1/swagger/options.go index e5c9de7cde..6d7386b09a 100644 --- a/routes/api/v1/swagger/options.go +++ b/routes/api/v1/swagger/options.go @@ -12,7 +12,7 @@ type swaggerParameterBodies struct { UserLogin models.UserLogin // in:body - ApiUserPassword models.ApiUserPassword + APIUserPassword models.APIUserPassword // in:body List models.List diff --git a/routes/api/v1/user_add_update.go b/routes/api/v1/user_add_update.go index d531e4c3bc..3ab566a793 100644 --- a/routes/api/v1/user_add_update.go +++ b/routes/api/v1/user_add_update.go @@ -7,6 +7,7 @@ import ( "strconv" ) +// RegisterUser ... func RegisterUser(c echo.Context) error { // swagger:operation POST /register user register @@ -20,7 +21,7 @@ func RegisterUser(c echo.Context) error { // - name: body // in: body // schema: - // "$ref": "#/definitions/ApiUserPassword" + // "$ref": "#/definitions/APIUserPassword" // responses: // "200": // "$ref": "#/responses/User" @@ -38,7 +39,7 @@ func userAddOrUpdate(c echo.Context) error { // TODO: prevent everyone from updating users // Check for Request Content - var datUser *models.ApiUserPassword + var datUser *models.APIUserPassword if err := c.Bind(&datUser); err != nil { return c.JSON(http.StatusBadRequest, models.Message{"No user model provided."}) diff --git a/routes/CRUD/CRUD_helper.go b/routes/crud/helper.go similarity index 87% rename from routes/CRUD/CRUD_helper.go rename to routes/crud/helper.go index ddfb168621..fb122e4540 100644 --- a/routes/CRUD/CRUD_helper.go +++ b/routes/crud/helper.go @@ -1,4 +1,4 @@ -package CRUD +package crud import ( "fmt" @@ -7,16 +7,17 @@ import ( "net/http" ) +// WebHandler defines the webhandler object // This does web stuff, aka returns json etc. Uses CRUDable Methods to get the data -type CRUDWebHandler struct { - CObject interface{ +type WebHandler struct { + CObject interface { models.CRUDable models.Rights } } -// This does json, handles the request -func (c *CRUDWebHandler) ReadOneWeb(ctx echo.Context) error { +// ReadOneWeb is the webhandler to get one object +func (c *WebHandler) ReadOneWeb(ctx echo.Context) error { // Get the ID id, err := models.GetIntURLParam("id", ctx) @@ -39,8 +40,8 @@ func (c *CRUDWebHandler) ReadOneWeb(ctx echo.Context) error { return ctx.JSON(http.StatusOK, c.CObject) } -// ReadAllWeb returns all elements of a type -func (c *CRUDWebHandler) ReadAllWeb(ctx echo.Context) error { +// ReadAllWeb is the webhandler to get all objects of a type +func (c *WebHandler) ReadAllWeb(ctx echo.Context) error { currentUser, err := models.GetCurrentUser(ctx) if err != nil { return ctx.JSON(http.StatusInternalServerError, models.Message{"Could not determine the current user."}) @@ -56,7 +57,7 @@ func (c *CRUDWebHandler) ReadAllWeb(ctx echo.Context) error { } // UpdateWeb is the webhandler to update an object -func (c *CRUDWebHandler) UpdateWeb(ctx echo.Context) error { +func (c *WebHandler) UpdateWeb(ctx echo.Context) error { // Get the object if err := ctx.Bind(&c.CObject); err != nil { return ctx.JSON(http.StatusBadRequest, models.Message{"No model provided."}) @@ -88,7 +89,7 @@ func (c *CRUDWebHandler) UpdateWeb(ctx echo.Context) error { } // CreateWeb is the handler to create an object -func (c *CRUDWebHandler) CreateWeb(ctx echo.Context) error { +func (c *WebHandler) CreateWeb(ctx echo.Context) error { // Get the object if err := ctx.Bind(&c.CObject); err != nil { return ctx.JSON(http.StatusBadRequest, models.Message{"No model provided."}) @@ -111,7 +112,7 @@ func (c *CRUDWebHandler) CreateWeb(ctx echo.Context) error { } // DeleteWeb is the web handler to delete something -func (c *CRUDWebHandler) DeleteWeb(ctx echo.Context) error { +func (c *WebHandler) DeleteWeb(ctx echo.Context) error { // Get the ID id, err := models.GetIntURLParam("id", ctx) if err != nil { @@ -138,4 +139,4 @@ func (c *CRUDWebHandler) DeleteWeb(ctx echo.Context) error { } return ctx.JSON(http.StatusOK, models.Message{"Successfully deleted."}) -} \ No newline at end of file +} diff --git a/routes/routes.go b/routes/routes.go index 77fb28b56a..6e239056ef 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -1,3 +1,5 @@ +package routes + // Package v1 List API. // // This documentation describes the List API. @@ -23,14 +25,13 @@ // in: header // // swagger:meta -package routes import ( "github.com/labstack/echo" "github.com/labstack/echo/middleware" "git.kolaente.de/konrad/list/models" - CRUD "git.kolaente.de/konrad/list/routes/CRUD" + crud "git.kolaente.de/konrad/list/routes/crud" apiv1 "git.kolaente.de/konrad/list/routes/api/v1" _ "git.kolaente.de/konrad/list/routes/api/v1/swagger" // for docs generation ) @@ -50,7 +51,6 @@ func NewEcho() *echo.Echo { // RegisterRoutes registers all routes for the application func RegisterRoutes(e *echo.Echo) { - // TODO: Use proper cors middleware by echo // Middleware for cors @@ -87,7 +87,7 @@ func RegisterRoutes(e *echo.Echo) { a.Use(middleware.JWT(models.Config.JWTLoginSecret)) a.POST("/tokenTest", apiv1.CheckToken) - listHandler := &CRUD.CRUDWebHandler{ + listHandler := &crud.WebHandler{ CObject: &models.List{}, } a.GET("/lists", listHandler.ReadAllWeb)