From b7df3d7e75fc14155d1ed57a8e62bfd46fa4a1a4 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 8 Jan 2022 22:10:55 +0100 Subject: [PATCH] Revert "feat: add time range parser" This reverts commit b9cd2d1a77c7525bf17bfcdad32eeade484a5488. --- docs/content/doc/usage/errors.md | 214 +++++++++++++-------------- pkg/modules/parse-time/errors.go | 51 ------- pkg/modules/parse-time/parse.go | 79 ---------- pkg/modules/parse-time/parse_test.go | 76 ---------- 4 files changed, 104 insertions(+), 316 deletions(-) delete mode 100644 pkg/modules/parse-time/errors.go delete mode 100644 pkg/modules/parse-time/parse.go delete mode 100644 pkg/modules/parse-time/parse_test.go diff --git a/docs/content/doc/usage/errors.md b/docs/content/doc/usage/errors.md index 54d3f152f..f5325ddd7 100644 --- a/docs/content/doc/usage/errors.md +++ b/docs/content/doc/usage/errors.md @@ -16,152 +16,146 @@ This document describes the different errors Vikunja can return. ## Generic -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|--------------------------| -| 0001 | 403 | Generic forbidden error. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 0001 | 403 | Generic forbidden error. | ## User -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|------------------------------------------------------------| -| 1001 | 400 | A user with this username already exists. | -| 1002 | 400 | A user with this email address already exists. | -| 1004 | 400 | No username and password specified. | -| 1005 | 404 | The user does not exist. | -| 1006 | 400 | Could not get the user id. | -| 1008 | 412 | No password reset token provided. | -| 1009 | 412 | Invalid password reset token. | -| 1010 | 412 | Invalid email confirm token. | -| 1011 | 412 | Wrong username or password. | -| 1012 | 412 | Email address of the user not confirmed. | -| 1013 | 412 | New password is empty. | -| 1014 | 412 | Old password is empty. | -| 1015 | 412 | Totp is already enabled for this user. | -| 1016 | 412 | Totp is not enabled for this user. | -| 1017 | 412 | The provided Totp passcode is invalid. | -| 1018 | 412 | The provided user avatar provider type setting is invalid. | -| 1019 | 412 | No openid email address was provided. | -| 1020 | 412 | This user account is disabled. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 1001 | 400 | A user with this username already exists. | +| 1002 | 400 | A user with this email address already exists. | +| 1004 | 400 | No username and password specified. | +| 1005 | 404 | The user does not exist. | +| 1006 | 400 | Could not get the user id. | +| 1008 | 412 | No password reset token provided. | +| 1009 | 412 | Invalid password reset token. | +| 1010 | 412 | Invalid email confirm token. | +| 1011 | 412 | Wrong username or password. | +| 1012 | 412 | Email address of the user not confirmed. | +| 1013 | 412 | New password is empty. | +| 1014 | 412 | Old password is empty. | +| 1015 | 412 | Totp is already enabled for this user. | +| 1016 | 412 | Totp is not enabled for this user. | +| 1017 | 412 | The provided Totp passcode is invalid. | +| 1018 | 412 | The provided user avatar provider type setting is invalid. | +| 1019 | 412 | No openid email address was provided. | +| 1020 | 412 | This user account is disabled. | ## Validation -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|---------------------------------------------------------------------------------------------------------| -| 2001 | 400 | ID cannot be empty or 0. | -| 2002 | 400 | Some of the request data was invalid. The response contains an aditional array with all invalid fields. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 2001 | 400 | ID cannot be empty or 0. | +| 2002 | 400 | Some of the request data was invalid. The response contains an aditional array with all invalid fields. | ## List -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|-------------------------------------------------------------------------------------------------------------------------------| -| 3001 | 404 | The list does not exist. | -| 3004 | 403 | The user needs to have read permissions on that list to perform that action. | -| 3005 | 400 | The list title cannot be empty. | -| 3006 | 404 | The list share does not exist. | -| 3007 | 400 | A list with this identifier already exists. | -| 3008 | 412 | The list is archived and can therefore only be accessed read only. This is also true for all tasks associated with this list. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 3001 | 404 | The list does not exist. | +| 3004 | 403 | The user needs to have read permissions on that list to perform that action. | +| 3005 | 400 | The list title cannot be empty. | +| 3006 | 404 | The list share does not exist. | +| 3007 | 400 | A list with this identifier already exists. | +| 3008 | 412 | The list is archived and can therefore only be accessed read only. This is also true for all tasks associated with this list. | ## Task -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|----------------------------------------------------------------------------| -| 4001 | 400 | The list task text cannot be empty. | -| 4002 | 404 | The list task does not exist. | -| 4003 | 403 | All bulk editing tasks must belong to the same list. | -| 4004 | 403 | Need at least one task when bulk editing tasks. | -| 4005 | 403 | The user does not have the right to see the task. | -| 4006 | 403 | The user tried to set a parent task as the task itself. | -| 4007 | 400 | The user tried to create a task relation with an invalid kind of relation. | -| 4008 | 409 | The user tried to create a task relation which already exists. | -| 4009 | 404 | The task relation does not exist. | -| 4010 | 400 | Cannot relate a task with itself. | -| 4011 | 404 | The task attachment does not exist. | -| 4012 | 400 | The task attachment is too large. | -| 4013 | 400 | The task sort param is invalid. | -| 4014 | 400 | The task sort order is invalid. | -| 4015 | 404 | The task comment does not exist. | -| 4016 | 403 | Invalid task field. | -| 4017 | 403 | Invalid task filter comparator. | -| 4018 | 403 | Invalid task filter concatinator. | -| 4019 | 403 | Invalid task filter value. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 4001 | 400 | The list task text cannot be empty. | +| 4002 | 404 | The list task does not exist. | +| 4003 | 403 | All bulk editing tasks must belong to the same list. | +| 4004 | 403 | Need at least one task when bulk editing tasks. | +| 4005 | 403 | The user does not have the right to see the task. | +| 4006 | 403 | The user tried to set a parent task as the task itself. | +| 4007 | 400 | The user tried to create a task relation with an invalid kind of relation. | +| 4008 | 409 | The user tried to create a task relation which already exists. | +| 4009 | 404 | The task relation does not exist. | +| 4010 | 400 | Cannot relate a task with itself. | +| 4011 | 404 | The task attachment does not exist. | +| 4012 | 400 | The task attachment is too large. | +| 4013 | 400 | The task sort param is invalid. | +| 4014 | 400 | The task sort order is invalid. | +| 4015 | 404 | The task comment does not exist. | +| 4016 | 403 | Invalid task field. | +| 4017 | 403 | Invalid task filter comparator. | +| 4018 | 403 | Invalid task filter concatinator. | +| 4019 | 403 | Invalid task filter value. | ## Namespace -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|-------------------------------------------------------------------------| -| 5001 | 404 | The namspace does not exist. | -| 5003 | 403 | The user does not have access to the specified namespace. | -| 5006 | 400 | The namespace name cannot be empty. | -| 5009 | 403 | The user needs to have namespace read access to perform that action. | -| 5010 | 403 | This team does not have access to that namespace. | -| 5011 | 409 | This user has already access to that namespace. | -| 5012 | 412 | The namespace is archived and can therefore only be accessed read only. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 5001 | 404 | The namspace does not exist. | +| 5003 | 403 | The user does not have access to the specified namespace. | +| 5006 | 400 | The namespace name cannot be empty. | +| 5009 | 403 | The user needs to have namespace read access to perform that action. | +| 5010 | 403 | This team does not have access to that namespace. | +| 5011 | 409 | This user has already access to that namespace. | +| 5012 | 412 | The namespace is archived and can therefore only be accessed read only. | ## Team -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|-------------------------------------------------------------------| -| 6001 | 400 | The team name cannot be emtpy. | -| 6002 | 404 | The team does not exist. | -| 6004 | 409 | The team already has access to that namespace or list. | -| 6005 | 409 | The user is already a member of that team. | -| 6006 | 400 | Cannot delete the last team member. | -| 6007 | 403 | The team does not have access to the list to perform that action. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 6001 | 400 | The team name cannot be emtpy. | +| 6002 | 404 | The team does not exist. | +| 6004 | 409 | The team already has access to that namespace or list. | +| 6005 | 409 | The user is already a member of that team. | +| 6006 | 400 | Cannot delete the last team member. | +| 6007 | 403 | The team does not have access to the list to perform that action. | ## User List Access -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|---------------------------------------------| -| 7002 | 409 | The user already has access to that list. | -| 7003 | 403 | The user does not have access to that list. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 7002 | 409 | The user already has access to that list. | +| 7003 | 403 | The user does not have access to that list. | ## Label -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|----------------------------------------------| -| 8001 | 403 | This label already exists on that task. | -| 8002 | 404 | The label does not exist. | -| 8003 | 403 | The user does not have access to this label. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 8001 | 403 | This label already exists on that task. | +| 8002 | 404 | The label does not exist. | +| 8003 | 403 | The user does not have access to this label. | ## Right -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|-----------------------| -| 9001 | 403 | The right is invalid. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 9001 | 403 | The right is invalid. | ## Kanban -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|-----------------------------------------------------------------------------------------------| -| 10001 | 404 | The bucket does not exist. | -| 10002 | 400 | The bucket does not belong to that list. | -| 10003 | 412 | You cannot remove the last bucket on a list. | -| 10004 | 412 | You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold. | -| 10005 | 412 | There can be only one done bucket per list. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 10001 | 404 | The bucket does not exist. | +| 10002 | 400 | The bucket does not belong to that list. | +| 10003 | 412 | You cannot remove the last bucket on a list. | +| 10004 | 412 | You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold. | +| 10005 | 412 | There can be only one done bucket per list. | ## Saved Filters -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|--------------------------------------------------| -| 11001 | 404 | The saved filter does not exist. | -| 11002 | 412 | Saved filters are not available for link shares. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 11001 | 404 | The saved filter does not exist. | +| 11002 | 412 | Saved filters are not available for link shares. | ## Subscriptions -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|-------------------------------------------------------------------------| -| 12001 | 412 | The subscription entity type is invalid. | -| 12002 | 412 | The user is already subscribed to the entity itself or a parent entity. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 12001 | 412 | The subscription entity type is invalid. | +| 12002 | 412 | The user is already subscribed to the entity itself or a parent entity. | ## Link Shares -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|--------------------------------------------------------------------------------| -| 13001 | 412 | This link share requires a password for authentication, but none was provided. | -| 13002 | 403 | The provided link share password was invalid. | - -## Time Ranges - -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|-------------------------------------| -| 14001 | 412 | The provided time range is invalid. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 13001 | 412 | This link share requires a password for authentication, but none was provided. | +| 13002 | 403 | The provided link share password was invalid. | diff --git a/pkg/modules/parse-time/errors.go b/pkg/modules/parse-time/errors.go deleted file mode 100644 index 197648411..000000000 --- a/pkg/modules/parse-time/errors.go +++ /dev/null @@ -1,51 +0,0 @@ -// Vikunja is a to-do list application to facilitate your life. -// Copyright 2018-2022 Vikunja and contributors. All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public Licensee as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public Licensee for more details. -// -// You should have received a copy of the GNU Affero General Public Licensee -// along with this program. If not, see . - -package parse_time - -import ( - "fmt" - "net/http" - - "code.vikunja.io/web" -) - -// ErrInvalidTimeRange represents a "InvalidTimeRange" kind of error. Used if the provided time range is invalid. -type ErrInvalidTimeRange struct { - Range string -} - -// IsErrInvalidTimeRange checks if an error is a ErrInvalidTimeRange. -func IsErrInvalidTimeRange(err error) bool { - _, ok := err.(*ErrInvalidTimeRange) - return ok -} - -func (err *ErrInvalidTimeRange) Error() string { - return fmt.Sprintf("Time range '%s' is invalid", err.Range) -} - -// ErrCodeInvalidTimeRange holds the unique world-error code of this error -const ErrCodeInvalidTimeRange = 14001 - -// HTTPError holds the http error description -func (err *ErrInvalidTimeRange) HTTPError() web.HTTPError { - return web.HTTPError{ - HTTPCode: http.StatusPreconditionFailed, - Code: ErrCodeInvalidTimeRange, - Message: "The time range is invalid.", - } -} diff --git a/pkg/modules/parse-time/parse.go b/pkg/modules/parse-time/parse.go deleted file mode 100644 index 2efbd167a..000000000 --- a/pkg/modules/parse-time/parse.go +++ /dev/null @@ -1,79 +0,0 @@ -// Vikunja is a to-do list application to facilitate your life. -// Copyright 2018-2022 Vikunja and contributors. All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public Licensee as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public Licensee for more details. -// -// You should have received a copy of the GNU Affero General Public Licensee -// along with this program. If not, see . - -package parse_time - -import ( - "strconv" - "strings" - "time" -) - -func ParseTimeRange(timeRange string) (from time.Time, to time.Time, err error) { - timeRange = strings.ReplaceAll(timeRange, " ", "") - - var parts []string - var factor int - if strings.Index(timeRange, "-") > 0 { - parts = strings.Split(timeRange, "-") - factor = -1 - } else { - parts = strings.Split(timeRange, "+") - factor = 1 - } - - if len(parts) != 2 { - return from, to, &ErrInvalidTimeRange{Range: timeRange} - } - - // Find the duration that is not "now" - var dur string - dur = parts[0] - if dur == "now" { - dur = parts[1] - } - - to = time.Now() - - var diff time.Duration - diff, err = parseTimeDuration(dur) - if err != nil { - return - } - - from = time.Now().Add(diff * time.Duration(factor)) - - // Make sure from is always before to - if to.Unix() < from.Unix() { - return to, from, nil - } - - return -} - -func parseTimeDuration(timeAmount string) (amount time.Duration, err error) { - if strings.Index(timeAmount, "d") > -1 { - var a int - a, err = strconv.Atoi(strings.ReplaceAll(timeAmount, "d", "")) - if err != nil { - return - } - - return time.Duration(a) * 24 * time.Hour, nil - } - - return time.ParseDuration(timeAmount) -} diff --git a/pkg/modules/parse-time/parse_test.go b/pkg/modules/parse-time/parse_test.go deleted file mode 100644 index 9ab3ca8c4..000000000 --- a/pkg/modules/parse-time/parse_test.go +++ /dev/null @@ -1,76 +0,0 @@ -// Vikunja is a to-do list application to facilitate your life. -// Copyright 2018-2022 Vikunja and contributors. All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public Licensee as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public Licensee for more details. -// -// You should have received a copy of the GNU Affero General Public Licensee -// along with this program. If not, see . - -package parse_time - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -func TestParseTimeRange(t *testing.T) { - t.Run("last 7 days", func(t *testing.T) { - from, to, err := ParseTimeRange("now - 7d") - - assert.NoError(t, err) - assert.Equal(t, time.Now().Add(time.Hour*24*7*-1).Unix(), from.Unix()) - assert.Equal(t, time.Now().Unix(), to.Unix()) - }) - t.Run("last 7 days, but different", func(t *testing.T) { - from, to, err := ParseTimeRange("7d - now") - - assert.NoError(t, err) - assert.Equal(t, time.Now().Add(time.Hour*24*7*-1).Unix(), from.Unix()) - assert.Equal(t, time.Now().Unix(), to.Unix()) - }) - t.Run("last 24h", func(t *testing.T) { - from, to, err := ParseTimeRange("24h - now") - - assert.NoError(t, err) - assert.Equal(t, time.Now().Add(time.Hour*24*-1).Unix(), from.Unix()) - assert.Equal(t, time.Now().Unix(), to.Unix()) - }) - t.Run("next 7 days", func(t *testing.T) { - from, to, err := ParseTimeRange("now + 7d") - - assert.NoError(t, err) - assert.Equal(t, time.Now().Unix(), from.Unix()) - assert.Equal(t, time.Now().Add(time.Hour*24*7).Unix(), to.Unix()) - }) - t.Run("next 24h", func(t *testing.T) { - from, to, err := ParseTimeRange("now + 24h") - - assert.NoError(t, err) - assert.Equal(t, time.Now().Unix(), from.Unix()) - assert.Equal(t, time.Now().Add(time.Hour*24).Unix(), to.Unix()) - }) - t.Run("range with only now", func(t *testing.T) { - _, _, err := ParseTimeRange("now") - assert.Error(t, err) - assert.True(t, IsErrInvalidTimeRange(err)) - }) - t.Run("range with only one duration part", func(t *testing.T) { - _, _, err := ParseTimeRange("7d") - assert.Error(t, err) - assert.True(t, IsErrInvalidTimeRange(err)) - }) - t.Run("invalid date range", func(t *testing.T) { - _, _, err := ParseTimeRange("now-7y") - assert.Error(t, err) - }) -}