diff --git a/pkg/routes/api/v1/user_caldav_token.go b/pkg/routes/api/v1/user_caldav_token.go index fd7b29568..55aeca4f3 100644 --- a/pkg/routes/api/v1/user_caldav_token.go +++ b/pkg/routes/api/v1/user_caldav_token.go @@ -18,6 +18,9 @@ package v1 import ( "net/http" + "strconv" + + "code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/user" "code.vikunja.io/web/handler" @@ -82,3 +85,34 @@ func GetCaldavTokens(c echo.Context) error { return c.JSON(http.StatusCreated, tokens) } + +// DeleteCaldavToken is the handler to delete a caldv token +// @Summary Delete a caldav token by id +// @tags user +// @Accept json +// @Produce json +// @Security JWTKeyAuth +// @Param id path int true "Token ID" +// @Success 200 {object} models.Message +// @Failure 400 {object} web.HTTPError "Something's invalid." +// @Failure 404 {object} web.HTTPError "User does not exist." +// @Failure 500 {object} models.Message "Internal server error." +// @Router /user/settings/token/caldav/{id} [get] +func DeleteCaldavToken(c echo.Context) error { + u, err := user.GetCurrentUser(c) + if err != nil { + return handler.HandleHTTPError(err, c) + } + + id, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil { + return handler.HandleHTTPError(err, c) + } + + err = user.DeleteCaldavTokenByID(u, id) + if err != nil { + return handler.HandleHTTPError(err, c) + } + + return c.JSON(http.StatusOK, &models.Message{Message: "The token was deleted successfully."}) +} diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index d79497164..c5089e01a 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -324,6 +324,7 @@ func registerAPIRoutes(a *echo.Group) { u.GET("/timezones", apiv1.GetAvailableTimezones) u.POST("/settings/token/caldav", apiv1.GenerateCaldavToken) u.GET("/settings/token/caldav", apiv1.GetCaldavTokens) + u.DELETE("/settings/token/caldav/:id", apiv1.DeleteCaldavToken) if config.ServiceEnableTotp.GetBool() { u.GET("/settings/totp", apiv1.UserTOTP) diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index 1e342ff4f..a95c87de9 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -7119,6 +7119,60 @@ var doc = `{ } } }, + "/user/settings/token/caldav/{id}": { + "get": { + "security": [ + { + "JWTKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Delete a caldav token by id", + "parameters": [ + { + "type": "integer", + "description": "Token ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Message" + } + }, + "400": { + "description": "Something's invalid.", + "schema": { + "$ref": "#/definitions/web.HTTPError" + } + }, + "404": { + "description": "User does not exist.", + "schema": { + "$ref": "#/definitions/web.HTTPError" + } + }, + "500": { + "description": "Internal server error.", + "schema": { + "$ref": "#/definitions/models.Message" + } + } + } + } + }, "/user/settings/totp": { "get": { "security": [ diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index 6187372b2..389e8e110 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -7103,6 +7103,60 @@ } } }, + "/user/settings/token/caldav/{id}": { + "get": { + "security": [ + { + "JWTKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Delete a caldav token by id", + "parameters": [ + { + "type": "integer", + "description": "Token ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Message" + } + }, + "400": { + "description": "Something's invalid.", + "schema": { + "$ref": "#/definitions/web.HTTPError" + } + }, + "404": { + "description": "User does not exist.", + "schema": { + "$ref": "#/definitions/web.HTTPError" + } + }, + "500": { + "description": "Internal server error.", + "schema": { + "$ref": "#/definitions/models.Message" + } + } + } + } + }, "/user/settings/totp": { "get": { "security": [ diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index 781e1ae45..be677995c 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -6142,6 +6142,40 @@ paths: summary: Generate a caldav token tags: - user + /user/settings/token/caldav/{id}: + get: + consumes: + - application/json + parameters: + - description: Token ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.Message' + "400": + description: Something's invalid. + schema: + $ref: '#/definitions/web.HTTPError' + "404": + description: User does not exist. + schema: + $ref: '#/definitions/web.HTTPError' + "500": + description: Internal server error. + schema: + $ref: '#/definitions/models.Message' + security: + - JWTKeyAuth: [] + summary: Delete a caldav token by id + tags: + - user /user/settings/totp: get: consumes: diff --git a/pkg/user/caldav_token.go b/pkg/user/caldav_token.go index 174cb2d16..4943773ec 100644 --- a/pkg/user/caldav_token.go +++ b/pkg/user/caldav_token.go @@ -22,22 +22,19 @@ func GenerateNewCaldavToken(u *User) (token *Token, err error) { s := db.NewSession() defer s.Close() - t, err := generateHashedToken(s, u, TokenCaldavAuth) - if err != nil { - return nil, err - } - - return t, err + return generateHashedToken(s, u, TokenCaldavAuth) } func GetCaldavTokens(u *User) (tokens []*Token, err error) { s := db.NewSession() defer s.Close() - t, err := getTokensForKind(s, u, TokenCaldavAuth) - if err != nil { - return nil, err - } - - return t, err + return getTokensForKind(s, u, TokenCaldavAuth) +} + +func DeleteCaldavTokenByID(u *User, id int64) error { + s := db.NewSession() + defer s.Close() + + return removeTokenByID(s, u, TokenCaldavAuth, id) } diff --git a/pkg/user/token.go b/pkg/user/token.go index 341dc3cbb..b50f6fa58 100644 --- a/pkg/user/token.go +++ b/pkg/user/token.go @@ -106,6 +106,12 @@ func removeTokens(s *xorm.Session, u *User, kind TokenKind) (err error) { return } +func removeTokenByID(s *xorm.Session, u *User, kind TokenKind, id int64) (err error) { + _, err = s.Where("id = ? AND user_id = ? AND kind = ?", id, u.ID, kind). + Delete(&Token{}) + return +} + // RegisterTokenCleanupCron registers a cron function to clean up all password reset tokens older than 24 hours func RegisterTokenCleanupCron() { const logPrefix = "[User Token Cleanup Cron] "