diff --git a/REST-Tests/lists.http b/REST-Tests/lists.http index 174bfbd9..327360c1 100644 --- a/REST-Tests/lists.http +++ b/REST-Tests/lists.http @@ -25,6 +25,33 @@ Authorization: Bearer {{auth_token}} ### +# Get all teams who have access to that list +GET http://localhost:8080/api/v1/lists/10/teams +Authorization: Bearer {{auth_token}} + +### + +# Give a team access to that list +PUT http://localhost:8080/api/v1/lists/10/teams +Authorization: Bearer {{auth_token}} +Content-Type: application/json + +{"team_id":2, "right": 1} + +### + +# Delete a team from a list +DELETE http://localhost:8080/api/v1/lists/10235/teams/1 +Authorization: Bearer {{auth_token}} + +### + +# Delete a team from a list +DELETE http://localhost:8080/api/v1/lists/10235/teams/1 +Authorization: Bearer {{auth_token}} + +### + # Get all users who have access to that list GET http://localhost:8080/api/v1/lists/10/users Authorization: Bearer {{auth_token}} @@ -39,3 +66,9 @@ Content-Type: application/json {"user_id":2, "right": 5} ### + +# Delete a user from a list +DELETE http://localhost:8080/api/v1/lists/10/users/2 +Authorization: Bearer {{auth_token}} + +### \ No newline at end of file diff --git a/models/error.go b/models/error.go index 5418237b..bbf8a94f 100644 --- a/models/error.go +++ b/models/error.go @@ -530,3 +530,19 @@ func IsErrUserAlreadyHasAccess(err error) bool { func (err ErrUserAlreadyHasAccess) Error() string { return fmt.Sprintf("This user already has access to that list. [User ID: %d, List ID: %d]", err.UserID, err.ListID) } + +// ErrUserDoesNotHaveAccessToList represents an error, where the user is not the owner of that List (used i.e. when deleting a List) +type ErrUserDoesNotHaveAccessToList struct { + ListID int64 + UserID int64 +} + +// IsErrUserDoesNotHaveAccessToList checks if an error is a ErrListDoesNotExist. +func IsErrUserDoesNotHaveAccessToList(err error) bool { + _, ok := err.(ErrUserDoesNotHaveAccessToList) + return ok +} + +func (err ErrUserDoesNotHaveAccessToList) Error() string { + return fmt.Sprintf("You need to have access to this List to do that [ListID: %d, UserID: %d]", err.ListID, err.UserID) +} diff --git a/models/list_users_delete.go b/models/list_users_delete.go new file mode 100644 index 00000000..e510b7bc --- /dev/null +++ b/models/list_users_delete.go @@ -0,0 +1,25 @@ +package models + +// Delete deletes a list <-> user relation +func (lu *ListUser) Delete() (err error) { + + // Check if the user exists + _, _, err = GetUserByID(lu.UserID) + if err != nil { + return + } + + // Check if the user has access to the list + has, err := x.Where("user_id = ? AND list_id = ?", lu.UserID, lu.ListID). + Get(&ListUser{}) + if err != nil { + return + } + if !has { + return ErrUserDoesNotHaveAccessToList{ListID: lu.ListID, UserID: lu.UserID} + } + + _, err = x.Where("user_id = ? AND list_id = ?", lu.UserID, lu.ListID). + Delete(&ListUser{}) + return +} diff --git a/models/list_users_rights.go b/models/list_users_rights.go index 166b1ac9..f720199e 100644 --- a/models/list_users_rights.go +++ b/models/list_users_rights.go @@ -32,3 +32,10 @@ func (lu *ListUser) CanCreate(doer *User) bool { l, _ := GetListByID(lu.ListID) return l.CanWrite(doer) } + +// CanDelete checks if the user can delete a user <-> list relation +func (lu *ListUser) CanDelete(doer *User) bool { + // Get the list and check if the user has write access on it + l, _ := GetListByID(lu.ListID) + return l.CanWrite(doer) +} diff --git a/routes/crud/delete.go b/routes/crud/delete.go index c4b966f7..919d6130 100644 --- a/routes/crud/delete.go +++ b/routes/crud/delete.go @@ -2,6 +2,7 @@ package crud import ( "code.vikunja.io/api/models" + "fmt" "github.com/labstack/echo" "net/http" ) @@ -24,7 +25,7 @@ func (c *WebHandler) DeleteWeb(ctx echo.Context) error { err = c.CObject.Delete() if err != nil { - + fmt.Println(err) if models.IsErrNeedToBeListAdmin(err) { return echo.NewHTTPError(http.StatusForbidden, "You need to be the list admin to delete a list.") } @@ -41,6 +42,10 @@ func (c *WebHandler) DeleteWeb(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, "You cannot delete the last member of a team.") } + if models.IsErrUserDoesNotHaveAccessToList(err) { + return echo.NewHTTPError(http.StatusBadRequest, "This user does not have access to the list.") + } + return echo.NewHTTPError(http.StatusInternalServerError) }