Compare commits

..
722 Commits
Author SHA1 Message Date
kolaente 91a3b7aba2 0.13 release preperations 2020-05-12 22:11:46 +02:00
kolaente 4137d4aed2 Fix creating new things with a link share auth 2020-05-12 15:51:48 +02:00
kolaente cb095d70df Add explanation to docs about cors 2020-05-12 11:10:07 +02:00
kolaente e43e601912 Add traefik 2 example configuration 2020-05-11 22:02:15 +02:00
kolaente 55cd40d175 Fix team rights not updating for namespace rights 2020-05-11 18:39:30 +02:00
renovateandkonrad 55cd74efca Update module go-testfixtures/testfixtures/v3 to v3.2.0 (#505)
Update module go-testfixtures/testfixtures/v3 to v3.2.0

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/505
2020-05-11 10:10:15 +00:00
renovateandkonrad a9d0079bf3 Update golang.org/x/crypto commit hash to 06a226f (#504)
Update golang.org/x/crypto commit hash to 06a226f

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/504
2020-05-11 09:02:23 +00:00
konradandkolaente 8ac158cdb4 Task Filter Fixes (#495)
Fix gocyclo

Fix misspell

Error codes docs

Filter fixes

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/495
2020-05-09 15:48:56 +00:00
renovateandkonrad def2362682 Update module spf13/viper to v1.7.0 (#494)
Update module spf13/viper to v1.7.0

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/494
2020-05-09 13:44:17 +00:00
kolaente 18f6e31b54 Fix parsing array style comparators by query param 2020-05-09 15:08:58 +02:00
kolaente 7e1d0a81bf Change totp secret datatype from varchar to text 2020-05-09 14:45:57 +02:00
renovateandkonrad f30e405229 Update module lib/pq to v1.5.2 (#491)
Update module lib/pq to v1.5.2

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/491
2020-05-08 13:23:26 +00:00
kolaente 563fe16bd4 Add checking and logging when trying to put a task into a nonexisting bucket 2020-05-07 10:20:10 +02:00
kolaente a30a358b73 Update theme 2020-05-06 21:03:15 +02:00
kolaente 497499e221 Fix reference to reverse proxies in docs 2020-05-06 21:02:58 +02:00
kolaente 1fdc51078e Add docs for changing frontend url 2020-05-06 20:44:48 +02:00
renovateandkonrad 60f343a926 Update module lib/pq to v1.5.1 (#485)
Update module lib/pq to v1.5.1

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/485
2020-05-05 08:59:08 +00:00
konradandkolaente fd3ccd6130 Fix total label count when getting all labels (#477)
Fix total label count when getting all labels

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/477
2020-05-03 21:28:36 +00:00
kolaente a97ce76f1f Fix bucket ID being reset with no need to do so 2020-05-03 22:25:48 +02:00
kolaente 83cf6e191c Fix not moving its bucket when moving a task between lists 2020-05-03 21:33:59 +02:00
kolaente f0ac6e89be Remove setting task bucket to 0 2020-05-03 21:24:28 +02:00
renovateandkonrad 23950c0602 Update module lib/pq to v1.5.0 (#476)
Update module lib/pq to v1.5.0

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/476
2020-05-03 18:14:57 +00:00
renovateandkonrad 19a05a7c2c Update golang.org/x/crypto commit hash to 4b2356b (#475)
Update golang.org/x/crypto commit hash to 4b2356b

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/475
2020-05-01 10:06:00 +00:00
renovateandkonrad 299e856736 Update module prometheus/client_golang to v1.6.0 (#463)
Update module prometheus/client_golang to v1.6.0

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/463
2020-04-28 18:50:58 +00:00
renovateandkonrad 6d95dc16c2 Update golang.org/x/crypto commit hash to 729f1e8 (#458)
Update golang.org/x/crypto commit hash to 729f1e8

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/458
2020-04-27 18:56:31 +00:00
kolaente fa28ddc2f7 Fix pagination count for task collection 2020-04-27 19:28:19 +02:00
kolaente 56dbb564ea Fix link share creation & creating admin link shares without admin rights 2020-04-27 12:51:09 +02:00
renovateandkonrad 711124f5c0 Update module go-testfixtures/testfixtures/v3 to v3.1.2 (#457)
Update module go-testfixtures/testfixtures/v3 to v3.1.2

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/457
2020-04-27 09:10:08 +00:00
kolaente 5606f987fa Add creating a new first bucket when creating a new list 2020-04-26 15:51:59 +02:00
kolaente f0cb3b5e36 Fix removing the last bucket 2020-04-26 00:57:47 +02:00
konradandkolaente 231dc3913f Add real buckets for tasks which don't have one (#446)
Add docs for error code

Add moving new tasks into the default bucket when none was provided

Add moving tasks in default bucket when deleting one

Fix tests again

Add test for removing a bucket

Fix tests

Prevent removing the last bucket

Remove the empty pseudo bucket

Add migration to create a new bucket for each list (and put all tasks in it

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/446
2020-04-25 20:32:02 +00:00
renovateandkonrad 2b1fc441e6 Update golang.org/x/crypto commit hash to 4bdfaf4 (#438)
Update golang.org/x/crypto commit hash to 4bdfaf4

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/438
2020-04-24 15:23:22 +00:00
e433289832 Task Position (#412)
Fix misspell

Fix sorting tasks with null values

Fix sorting by priority for postgres

Merge branch 'master' into feature/position

Add community link

Update golang.org/x/crypto commit hash to 44a6062 (#429)

Update golang.org/x/crypto commit hash to 44a6062

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/429

Update module lib/pq to v1.4.0 (#428)

Update module lib/pq to v1.4.0

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/428

Fix updating position

Add ordering tasks in buckets by position

Make task sort by string

Merge branch 'master' into feature/position

Update golang.org/x/crypto commit hash to 3c4aac8 (#419)

Update golang.org/x/crypto commit hash to 3c4aac8

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/419

Merge branch 'master' into feature/position

Fix moving tasks back into the empty (ID: 0) bucket

Add adding a default position when creating new tasks

Update golang.org/x/crypto commit hash to a76a400 (#411)

Update golang.org/x/crypto commit hash to a76a400

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/411

Remove unused code

Fix tests

Add migration for position attribute

Add position attribute

Co-authored-by: kolaente <k@knt.li>
Co-authored-by: renovate <renovatebot@kolaente.de>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/412
2020-04-24 15:23:03 +00:00
kolaente 86bdd1e386 Add community link 2020-04-24 13:00:29 +02:00
renovateandkonrad 4f1c0d99ea Update golang.org/x/crypto commit hash to 44a6062 (#429)
Update golang.org/x/crypto commit hash to 44a6062

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/429
2020-04-22 22:49:56 +00:00
renovateandkonrad f0792cfb0b Update module lib/pq to v1.4.0 (#428)
Update module lib/pq to v1.4.0

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/428
2020-04-22 10:16:38 +00:00
renovateandkonrad dece744685 Update golang.org/x/crypto commit hash to 3c4aac8 (#419)
Update golang.org/x/crypto commit hash to 3c4aac8

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/419
2020-04-21 07:41:16 +00:00
kolaente 68ab6d2e75 Fix moving tasks back into the empty (ID: 0) bucket 2020-04-20 23:08:38 +02:00
renovateandkonrad c69f0bf3cb Update golang.org/x/crypto commit hash to a76a400 (#411)
Update golang.org/x/crypto commit hash to a76a400

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/411
2020-04-20 20:58:32 +00:00
kolaente 59037e4eee Fix moving tasks in buckets 2020-04-20 18:08:20 +02:00
kolaente 1bd8348be7 Add categories to error docs 2020-04-19 14:33:51 +02:00
konradandkolaente ecdecdd94e Kanban (#393)
Fix tests

Add error docs

Add swagger docs for bucket endpoints

Add integration tests

Fix tests

Fix err shadow

Make sure a bucket and a task belong to the same list when adding or updating a task

Add tests

Add getting users of a bucket

Fix log level when testing

Fix lint

Add migration for buckets

Cleanup/Comments/Reorganization

Add Kanban bucket handling

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/393
2020-04-19 07:27:28 +00:00
konradandkolaente 28ec44c91f Add moving tasks between lists (#389)
Fix misspell

Add moving tasks between lists

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/389
2020-04-18 12:35:37 +00:00
kolaente 895d9613b5 Add endpoint to disable totp auth 2020-04-18 01:38:49 +02:00
kolaente 87d0c9088d Add endpoint to get the current users totp status 2020-04-18 00:22:59 +02:00
konradandkolaente 24904585a2 Add 2fa for authentification (#383)
Fix user tests

Add swagger docs

Fix lint

Add totp check when logging in

Make totp enrollment work

Add migration for totp table

go mod vendor

Add routes for totp routes

Add route handler for totp routes

Add basic implementation to enroll a user in totp

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/383
2020-04-17 19:25:35 +00:00
kolaente 1dca8e96a7 Add changing email for users 2020-04-17 16:01:45 +02:00
kolaente e1ab2095fa Update docs theme 2020-04-16 23:31:36 +02:00
renovateandkonrad 12e18de8ad Update golang.org/x/crypto commit hash to 0848c95 (#371)
Update golang.org/x/crypto commit hash to 0848c95

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/371
2020-04-15 06:48:46 +00:00
kolaente 025b00247d Fix replace statements for tail 2020-04-14 21:37:00 +02:00
kolaente 5832991c4d Fix tests after renaming json fields to snake_case 2020-04-13 23:27:55 +02:00
kolaente 81990f3f80 Update xorm redis cacher to use the xorm logger instead of a special seperate one 2020-04-13 23:18:33 +02:00
kolaente 368cbdf979 Fix gosec in drone 2020-04-13 23:04:59 +02:00
kolaente b8d7c97eb7 Add gosec static analysis 2020-04-13 22:30:09 +02:00
kolaente fb8ac92abf Change all json fields to snake_case 2020-04-12 22:48:46 +02:00
kolaente 0bfb3a4709 Add configuration options for log level 2020-04-12 22:32:21 +02:00
kolaente 9559a68416 Update module prometheus/client_golang to v1 2020-04-12 22:06:24 +02:00
konradandkolaente d28f005552 Update xorm to v1 (#323)
Fix limit for databases other than sqlite

go mod tidy && go mod vendor

Remove unneeded break statements

Make everything work with the new xorm version

Fix xorm logging

Fix lint

Fix redis init

Fix using id field

Fix database init for testing

Change default database log level

Add xorm logger

Use const for postgres

go mod tidy

Merge branch 'master' into update/xorm

# Conflicts:
#	go.mod
#	go.sum
#	vendor/modules.txt

go mod vendor

Fix loading fixtures for postgres

Go mod vendor1

Update xorm to version 1

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/323
2020-04-12 17:29:24 +00:00
renovateandkonrad 713560702b Update module go-redis/redis to v7 (#309)
Update module go-redis/redis to v7

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/309
2020-04-11 21:43:04 +00:00
konradandkolaente 0ba121fdfb Task filters (#243)
Fix not returning errors

Fix integration tests

Add more tests

Make task filtering actually work

Change tests

Fix using filter conditions

Fix test

Remove unused fields

Fix static check

Remove start and end date fields on task collection

Fix misspell

add filter logic when getting tasks

Add parsing filter query parameters into task filters

Start adding support for filters

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/243
2020-04-11 14:20:33 +00:00
kolaente 0e2449482f Fix dependencies 2020-04-09 23:06:57 +02:00
renovateandkonrad 8d1a3f4fd7 Update module spf13/viper to v1.6.3 (#291)
Update module spf13/viper to v1.6.3

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/291
2020-04-09 20:29:11 +00:00
renovateandkonrad 1e0f2dde6a Update module go-redis/redis to v6.15.7 (#290)
Update module go-redis/redis to v6.15.7

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/290
2020-04-09 20:28:58 +00:00
renovateandkonrad 7abac07837 Update src.techknowlogick.com/xgo commit hash to bb0faa3 (#279)
Update src.techknowlogick.com/xgo commit hash to bb0faa3

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/279
2020-04-09 04:36:03 +00:00
renovateandkonrad 15d718fb1a Update module go-redis/redis to v7 (#277)
Update module go-redis/redis to v7

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/277
2020-04-09 04:35:36 +00:00
renovateandkonrad 4ca3f714ea Update module stretchr/testify to v1.5.1 (#274)
Update module stretchr/testify to v1.5.1

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/274
2020-04-08 20:30:48 +00:00
renovateandkonrad 6d1b123a25 Update module spf13/cobra to v0.0.7 (#271)
Update module spf13/cobra to v0.0.7

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/271
2020-04-08 19:44:10 +00:00
renovateandkonrad 13ebb98644 Update module spf13/viper to v1.6.2 (#272)
Update module spf13/viper to v1.6.2

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/272
2020-04-08 18:43:35 +00:00
renovateandkonrad dda558fe1c Update module prometheus/client_golang to v0.9.4 (#245)
Update module prometheus/client_golang to v0.9.4

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/245
2020-04-07 20:42:06 +00:00
renovateandkonrad 76f19db6e7 Update module labstack/echo/v4 to v4.1.16 (#241)
Update module labstack/echo/v4 to v4.1.16

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/241
2020-04-07 18:59:53 +00:00
renovateandkonrad f776b799b8 Update module olekukonko/tablewriter to v0.0.4 (#240)
Update module olekukonko/tablewriter to v0.0.4

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/240
2020-04-07 16:58:27 +00:00
renovateandkonrad 746a443660 Update module imdario/mergo to v0.3.9 (#238)
Update module imdario/mergo to v0.3.9

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/238
2020-04-07 16:05:10 +00:00
renovateandkonrad 026d3dc80d Update module go-redis/redis to v6.15.7 (#234)
Update module go-redis/redis to v6.15.7

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/234
2020-04-07 12:31:33 +00:00
renovateandkonrad fd7dd47d5e Update github.com/gordonklaus/ineffassign commit hash to 7953dde (#233)
Update github.com/gordonklaus/ineffassign commit hash to 7953dde

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/233
2020-04-07 12:30:57 +00:00
renovateandkonrad 1e5a1b4892 Update github.com/shurcooL/httpfs commit hash to 8d4bc4b (#229)
Update github.com/shurcooL/httpfs commit hash to 8d4bc4b

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/229
2020-04-07 08:39:00 +00:00
renovateandkonrad c7f6748761 Update github.com/jgautheron/goconst commit hash to cda7ea3 (#228)
Update github.com/jgautheron/goconst commit hash to cda7ea3

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/228
2020-04-07 08:38:00 +00:00
renovateandkonrad 7efa0069cb Update golang.org/x/crypto commit hash to 056763e (#222)
Update golang.org/x/crypto commit hash to 056763e

Update golang.org/x/lint commit hash to 738671d (#223)

Update golang.org/x/lint commit hash to 738671d

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/223

Update src.techknowlogick.com/xgo commit hash to c43d4c4 (#224)

Update src.techknowlogick.com/xgo commit hash to c43d4c4

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/224

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/222
2020-04-07 08:37:20 +00:00
renovateandkonrad 424cf80e5c Update golang.org/x/lint commit hash to 738671d (#223)
Update golang.org/x/lint commit hash to 738671d

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/223
2020-04-07 07:29:05 +00:00
renovateandkonrad 1448d9de98 Update src.techknowlogick.com/xgo commit hash to c43d4c4 (#224)
Update src.techknowlogick.com/xgo commit hash to c43d4c4

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/224
2020-04-07 07:28:48 +00:00
renovateandkonrad cbf01e118a Update github.com/c2h5oh/datasize commit hash to 28bbd47 (#212)
Update github.com/c2h5oh/datasize commit hash to 28bbd47

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/212
2020-04-06 20:28:57 +00:00
renovateandkonrad 191942fcd1 Update alpine Docker tag to v3.11 (#160)
Update alpine Docker tag to v3.11

Add github token for renovate (#164)

Add github token for renovate

Add github token for renovate

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/164

Update Renovate Configuration (#161)

Add labels to renovate

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/161

Co-authored-by: konrad <konrad@kola-entertainments.de>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/160
2020-04-06 06:40:42 +00:00
konradandkolaente d5c8f2541d Add github token for renovate (#164)
Add github token for renovate

Add github token for renovate

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/164
2020-04-05 19:16:21 +00:00
konradandkolaente 6e9ad3d808 Update Renovate Configuration (#161)
Add labels to renovate

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/161
2020-04-05 17:24:06 +00:00
renovateandkonrad 36fdff5b8b Configure Renovate (#159)
Add renovate.json

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/159
2020-04-05 15:11:27 +00:00
kolaente 8f4139f44a 0.12 Release Preparations 2020-04-04 22:29:32 +02:00
kolaente e7706a20dd Fix call to println
Signed-off-by: kolaente <k@knt.li>
2020-04-02 21:38:16 +02:00
kolaente 6d1018e647 Fix searching for config in home directories
Signed-off-by: kolaente <k@knt.li>
2020-04-02 21:13:42 +02:00
kolaente 11246b948f Fix getting the authenticated user with caldav
Signed-off-by: kolaente <k@knt.li>
2020-04-01 22:51:57 +02:00
konradandkolaente 7b619bd084 Colors for lists and namespaces (#155)
Add Hex Color properties migration

Add Hex Color properties

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/155
2020-03-22 21:09:32 +00:00
kolaente 35f05cbbec Show lists as archived if their namespace is archived
Signed-off-by: kolaente <k@knt.li>
2020-03-22 21:39:57 +01:00
kolaente 0a1887d6e7 Fix archiving namespaces
Signed-off-by: kolaente <k@knt.li>
2020-03-22 19:02:53 +01:00
kolaente c6d22bb1f8 Fix updating lists with an identifier
Signed-off-by: kolaente <k@knt.li>
2020-03-22 18:45:10 +01:00
kolaente 6132863f4a Fix getting archived lists and namespaces
Signed-off-by: kolaente <k@knt.li>
2020-03-22 18:24:54 +01:00
kolaente 26ffd2fd22 Fix getting one namespace
Signed-off-by: kolaente <k@knt.li>
2020-03-21 13:55:42 +01:00
51c74de1de expand relative path ~/.config/vikunja to $HOME/.config/vikunja **WINDOWS** (#147)
apply correct formatting

add quotes to make the yaml gods happy

log path of config file used by viper

resolve merge conflicts: windows compatible $HOME path

Prepare changelog & readme for 0.11 release

expand relative path ~/.config/vikunja to $HOME/.config/vikunja (#146)

update dependencies

expand relative path ~/.config/vikunja

Co-authored-by: Julian <juliangaal@protonmail.com>
Co-authored-by: konrad <konrad@kola-entertainments.de>

Co-authored-by: Julian Gaal <gjulian@uos.de>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/147
Reviewed-by: konrad <konrad@kola-entertainments.de>
2020-03-20 21:21:44 +00:00
konradandkolaente 5126330a10 Add support for archiving lists and namespaces (#152)
Add query param to get all lists including archived ones

Add query param to get all namespaces including archived ones

Fix getting lists by namespace only not archived lists

Fix misspell

Fix lint

Merge branch 'master' into feature/archive-lists-namespaces

Add docs for error codes

Fix archive error codes

Don't let archived lists show up in general lists

Fix updating description

Fix updating lists with link shares

More comments

Fix un-archiving lists

Move check for archiving a list to canWrite Check

Add more tests

Add more checks

Add checks for namespaces and lists

Add namespace edit

Add tests

Add migrations and filter

Add basic tests

Add is archived property to lists and namespaces

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/152
2020-03-15 21:50:39 +00:00
konradandkolaente 4472020ee9 Add workaround for timezones on windows (#151)
Add workaround for timezones on windows

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/151
2020-03-09 22:41:08 +00:00
kolaente 7de26a462f Add build time to compile flags 2020-03-02 20:24:26 +01:00
kolaente f2f17b11e8 Change release bucket 2020-03-01 22:51:50 +01:00
konradandkolaente cdd068cdb6 Add empty avatar provider (#149)
Fix lint

Add docs for avatar configuration

Add default avatar provider

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/149
2020-03-01 21:10:25 +00:00
konradandkolaente 584e3af237 Add proxying gravatar requests for user avatars (#148)
Fix getting avatar based on email

Remove avatarUrl from user struct

Fix staticcheck

Add default avatar size

Add config option for caching avatars

go mod vendor

Add swagger docs

Add proxying gravatar requests for user avatars

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/148
2020-03-01 20:30:37 +00:00
kolaente 7ddfa76a84 Prepare changelog & readme for 0.11 release 2020-03-01 17:32:38 +01:00
funkythingsandkonrad 1e03c39141 expand relative path ~/.config/vikunja to $HOME/.config/vikunja (#146)
update dependencies

expand relative path ~/.config/vikunja

Authored-by: Julian Gaal <gjulian@uos.de>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/146
Reviewed-by: konrad <konrad@kola-entertainments.de>
2020-02-29 19:51:47 +00:00
konradandkolaente 88bf8f3df0 Fix updating dates when marking a task as done (#145)
Fix lint

Fix reminders not being updated

Fix updating dates when marking a task as done

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/145
2020-02-26 21:09:45 +00:00
kolaente c551706b52 Make sure the author is returned when creating a new comment 2020-02-25 21:18:42 +01:00
konradandkolaente 1f039c4cda Task Comments (#138)
Add swagger docs

Add integration tests

Add tests

Add task comment test fixtures

Add config option to enable/disable task comments

Add custom error if a task comment does not exist

Fix lint

Add getting author when getting a single comment

Fix getting comments/comments author

Add rights check to ReadAll

+ actually get the comment author

Add migration and table definitions

Add routes

Add ReadOne method

Add basic crud rights

Signed-off-by: kolaente <k@knt.li>

Implement basic crudable functions for task comments

Signed-off-by: kolaente <k@knt.li>

Start adding task comments

Signed-off-by: kolaente <k@knt.li>
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/138
2020-02-19 21:57:56 +00:00
konradandkolaente 5901cf64b4 Fix inserting task structure with related tasks (#142)
Fix typo

Fix creating related tasks

Add better logging

Fix inserting task structure with related tasks

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/142
2020-02-18 22:00:54 +00:00
kolaente f87bb6d8ef Update theme 2020-02-18 18:47:19 +01:00
kolaente 021a715aff Fix frontend url for wunderlist migration in docs 2020-02-17 19:52:26 +01:00
konradandkolaente e95a6eeb11 Explicitly disable wunderlist migration by default (#141)
Fix wunderlist callback link in docs

Explicitly disable wunderlist migration by default

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/141
2020-02-17 17:29:17 +00:00
Dpvhandkonrad f46e9cb64e Fixed typo in docker-compose example (#140)
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/140
Reviewed-by: konrad <konrad@kola-entertainments.de>
2020-02-17 16:47:55 +00:00
ce5be947b4 Add postgres support (#135)
Revert fixture fixes for postgres

Use postgres connection string with spaces instead of url

Fix label order

Make postgres tests in ci less verbose

Add sequence update script

Skip resets in postgres

Remove option to skip resets in postgres

Make postgres tests in ci verboseq

Update test fixtures database

Fix file tests on postgres

Add postgres options to sample config

Make sure tests init test fixtures before running the actual tests

Fix issues with IDs too big to fit in an int

Fix duplicate auto incremented IDs

Refactor / Fix team tests

Refactor team member tests

Fix team member create

Fix label test

Fix getting labels

Fix test fixtures for postgresql

Fix connection string params

Disable ssl mode on postgres integration tests

Disable ssl mode on postgres tests

Use sprintf to create the connection string for postgresql

fixup! Add postgres support

Add postgres support

Added generate as a make dependency for make build

Clarify docs on building

Co-authored-by: kolaente <k@knt.li>
Co-authored-by: Jan Tojnar <jtojnar@gmail.com>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/135
2020-02-16 21:42:04 +00:00
kolaente 7e42724439 Added generate as a make dependency for make build
Clarify docs on building

Signed-off-by: kolaente <k@knt.li>
2020-02-15 11:35:24 +01:00
konradandkolaente caf91d1904 Update xorm to use the new import path (#133)
Fix ineffassign

Fix getting all labels including the ones not associated to a task

Signed-off-by: kolaente <k@knt.li>

Fix logging sql queries

Signed-off-by: kolaente <k@knt.li>

Start fixing getting all labels

Update xormigrate

Update xorm to use the new import path

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/133
2020-02-14 16:34:25 +00:00
shilchandkonrad 014ec2be69 Use relative url in .gitmodules (#132)
Use relative url in .gitmodules

Co-authored-by: Simon Hilchenbach <simon@hilchenba.ch>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/132
Reviewed-by: konrad <konrad@kola-entertainments.de>
2020-02-13 21:18:49 +00:00
kolaente 5d96c62a47 Fix time zone settings not working in Docker 2020-02-08 23:18:41 +01:00
kolaente 1c3b35fa6f Add more logging to web handler methods 2020-02-08 22:45:38 +01:00
kolaente d84a160054 Remove double user field 2020-02-08 22:12:06 +01:00
konradandkolaente db2d868eed Return iso dates for everything date related from the api (#130)
Remove traces of unix timestamp

Revert renaming reminder table column

Fix staticcheck

Remove unused table call

Add migration for renaming reminders table

Fix issues with using TimeStamp

Fix lint

Updated all created / updated fields to use TimeStamps

Add comments

Convert all created / updated fields to datetime

Add time util package

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/130
2020-02-08 12:48:49 +00:00
kolaente 1f99238019 Update copyright header 2020-02-07 17:27:45 +01:00
konradandkolaente f603b41d99 Better efficency for loading teams (#128)
Fix staticcheck

Better performance for getting teams on a namespace

Better performance for getting teams on a list

Fix lint

Fix swagger

Signed-off-by: kolaente <k@knt.li>

Make loading a single full team more efficent

Signed-off-by: kolaente <k@knt.li>

Make loading teams more efficent

Signed-off-by: kolaente <k@knt.li>

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/128
2020-01-27 17:28:17 +00:00
konradandkolaente 2abb858859 Add rate limit by ip for non-authenticated routes (#127)
Add rate limit by ip for non-authenticated routes

Signed-off-by: kolaente <k@knt.li>

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/127
2020-01-26 19:53:47 +00:00
konradandkolaente a464d1760c Add logging for invalid model errors (#126)
Add logging for invalid model errors

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/126
2020-01-26 19:40:23 +00:00
konradandkolaente fc65052ba0 Add config options for task attachments (#125)
Add config options for task attachments

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/125
2020-01-26 19:10:31 +00:00
konradandkolaente b2b1546a8f Add config options for cors handling (#124)
Add config options for cors handling

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/124
2020-01-26 19:09:54 +00:00
konradandkolaente 7e9446ea07 Refactor User and DB handling (#123)
fix copyright date

Add more user tests

More user tests

More user tests

Start refactoring user tests

Docs

Fix lint

Fix db fixtures init in tests

Fix models test

Fix loading fixtures

Fix ineffasign

Fix lint

Fix integration tests

Fix init of test engine creation

Fix user related tests

Better handling of creating test enging

Moved all fixtures to db package

Moved all fixtures to db package

Moved user related stuff to seperate package

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/123
2020-01-26 17:08:06 +00:00
konradandkolaente 8c33e24e92 Migration Improvements (#122)
Update swagger docs

Update docs

Let the wunderlist migrator use the registerRoutes function

Add migration status table

Add migration status

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/122
2020-01-20 19:48:46 +00:00
kolaente 0654ead831 Update version link in README 2020-01-19 22:27:19 +01:00
kolaente 2b80025cc0 Update changelog for v0.10 2020-01-19 22:25:38 +01:00
konradandkolaente 3081338a37 Use redis INCRBY and DECRBY when updating metrics values (#121)
Move test coverage processing to a seperate command

Use redis INCRBY and DECRBY when updating metrics values

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/121
2020-01-19 17:26:26 +00:00
konradandkolaente 9e39399689 Migration (#120)
Go mod tidy

[skip ci] Add modules/migration to docs

[skip ci] update date

fmt

Merge branch 'master' into feature/migration

# Conflicts:
#	pkg/routes/api/v1/info.go

Add docs on how to create a migrator

Add available migrators to /info endpoint

Return a message once everything was migrated successfully

Add swagger docs for wunderlist migration

Docs for migration [skip ci]

Fix due date fixture in migration test

Fix staticcheck

Fix lint

Logging and cleanup

Make the migrator work with real data

Add routes for migration

Fix misspell

Add method to store a full vikunja structure into vikunja

Add getting all data from wunderlist

Add attachment migration from wunderlist

Add done and done at to wunderlist migrator

Add todo

Add wunderlist auth url implementation

Fix lint

Finish wunderlist migration

Added all structs for the wunderlist migratior

Fix owner field being null for user shared namespaces (#119)

Update copyright year (#118)

Add option to disable registration (#117)

Added migrator interface

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/120
2020-01-19 16:52:16 +00:00
konrad 1d2cdf0fb8 Fix owner field being null for user shared namespaces (#119) 2020-01-09 19:24:08 +00:00
konrad a0c5e4e985 Update copyright year (#118) 2020-01-09 17:33:22 +00:00
konrad 402cef3c15 Add option to disable registration (#117) 2019-12-30 23:27:02 +00:00
kolaente b9f0ba84ab Add motd config option to docs 2019-12-25 17:27:10 +01:00
konrad 7cdc997191 Fix new tasks not getting a new task index (#116) 2019-12-08 15:10:34 +00:00
konrad 720df3cbed Add task identifier (#115) 2019-12-07 22:28:45 +00:00
konrad 1a47d7d80d Use utf8mb4 instead of plain utf8 (#114) 2019-12-07 20:14:13 +00:00
konrad 62e550bf35 Add user token renew (#113) 2019-12-07 19:52:04 +00:00
kolaente 10ab8ef4d9 Fix task collection tests 2019-12-07 17:21:37 +01:00
kolaente d483fe8beb Fix passing sort_by and order_by as query path arrays 2019-12-07 16:57:19 +01:00
kolaente 1555f04bd2 Fix sorting tasks by bool values
There was a bug where it would return all tasks with a true value before the ones with a false value. This is the exact opposite of what the db does, leading to wrongly sorted values
2019-12-07 16:56:18 +01:00
konrad d8399e374c Sort Order for tasks (#110) 2019-12-07 14:30:51 +00:00
shilchandkonrad e890001ee1 Consistent copyright text in file headers (#112) 2019-12-04 19:39:56 +00:00
shilchandkonrad 38653b49c7 Add tests for md5 generation (#111) 2019-12-04 19:19:38 +00:00
konrad 7e4deab8f7 Task collection improvements (#109) 2019-12-01 13:38:11 +00:00
konrad d96831fe3a Endpoint to get tasks on a list (#108) 2019-11-29 22:59:20 +00:00
kolaente 4c55b4455c update theme 2019-11-25 19:12:42 +01:00
kolaente b6308f783b Add files volume to docker compose docs 2019-11-25 19:08:24 +01:00
kolaente 843c1e5193 Update docs with a traefik configuration 2019-11-25 19:07:11 +01:00
kolaente 6045f4a426 Prepare changelog & readme for 0.9 release 2019-11-24 19:38:23 +01:00
kolaente 7be14239a3 [skip ci] Add changelog in repo 2019-11-24 19:33:16 +01:00
konrad 27ba31366c Fix default logging settings (#107) 2019-11-24 18:17:59 +00:00
kolaente 9dc419e854 Add file volume to the docker image 2019-11-24 18:36:43 +01:00
kolaente 37efd5cb49 Fixed removing reminders 2019-11-24 16:13:16 +01:00
kolaente dcec9511dc Fixed a bug where deleting an attachment would cause a nil panic 2019-11-19 23:07:48 +01:00
kolaente c203d73b33 Fixed a bug where adding assignees or reminders via an update would re-create them and not respect already inserted ones, leaving a lot of garbage 2019-11-03 23:08:26 +01:00
konrad 9be5ab248c Add endpoint to get a single task (#106) 2019-11-02 20:33:18 +00:00
kolaente ed4c17892e Fixed building docs theme 2019-10-30 21:53:57 +01:00
kolaente 886110a20a update docs theme 2019-10-30 21:47:16 +01:00
konrad 8948a5f219 Improve pagination (#105) 2019-10-23 21:11:40 +00:00
kolaente 89f385a53d Move from markdown lists to Vikunja for roadmap [skip ci] 2019-10-20 20:52:41 +02:00
kolaente 82f11c4ec2 Fixed not getting all labels when retrieving a list with all tasks 2019-10-20 17:56:53 +02:00
kolaente eb279fdba3 Refactored getting task IDs for labels 2019-10-20 17:55:54 +02:00
kolaente 48e422b379 [skip ci] Prepare the roadmap for migration 2019-10-20 17:54:32 +02:00
kolaente 854fde1e4c Fixed panic when using link share and metrics 2019-10-19 22:34:33 +02:00
kolaente b653278e42 Reverted telegram notification in CI "fix" 2019-10-19 18:18:39 +02:00
kolaente 35e4ab198f Fixed telegram notification in CI 2019-10-19 16:57:39 +02:00
kolaente b81cd6128a Fixed error when setting max file size on 32-Bit systems 2019-10-18 17:30:25 +02:00
konradandGitea 2169464983 Task Attachments (#104) 2019-10-16 20:52:29 +00:00
kolaente e2f481a6e5 Fixed migration for task relations 2019-10-13 11:44:56 +02:00
kolaente af1d1e1921 [skip ci] updated todo 2019-09-25 20:45:20 +02:00
konradandGitea 8fe33fd616 Task Relations (#103) 2019-09-25 18:44:41 +00:00
konradandGitea 1272255975 Added percent done to tasks (#102) 2019-09-21 10:52:10 +00:00
kolaente 1e2ec17343 [skip ci] update todo 2019-09-20 18:45:28 +02:00
konradandGitea 2f267f3f68 Moved teams_{namespace|list}_* to {namespace|list}_teams_* for better consistency (#101) 2019-09-20 16:39:02 +00:00
konradandGitea 694fc62495 Refactored getting all lists for a namespace (#100) 2019-09-20 16:16:31 +00:00
konradandGitea 8d5a2685c4 Fixed labels being displayed multiple times if they were associated with more than one task (#99) 2019-09-20 15:52:09 +00:00
konradandGitea 71ef86e0df Added more infos to a link share auth (#98) 2019-09-08 19:22:54 +00:00
konradandGitea 6140920cb8 Fixed rate limit panic when authenticatin with a link share auth token (#97) 2019-09-08 19:11:42 +00:00
konradandGitea fdd1624121 Small link share fixes (#96) 2019-09-07 13:19:23 +00:00
kolaente 158ad631e1 [skip ci] update todo 2019-09-05 22:48:51 +02:00
kolaente c126d2f55c [skip ci] update todo 2019-09-05 22:00:21 +02:00
kolaente 1d98e4cabe Fixed metrics on/off setting 2019-09-01 18:39:03 +02:00
kolaente 43676f045c Switched default logger to stdout instead of stderr 2019-09-01 18:23:35 +02:00
kolaente ba7db545fe Added extra depth to logging to correctly show the functions calling the logger in logs 2019-09-01 17:56:22 +02:00
kolaente 021ee48ec3 Made sure all tags are checked out when building in docker 2019-09-01 11:43:01 +02:00
kolaente a324921dce Updated Readme [skip ci] 2019-09-01 11:01:36 +02:00
konradandGitea 8d57923a7d Sharing of lists via public links (#94) 2019-08-31 20:56:41 +00:00
kolaente 88ea66798b [skip ci] updated todo 2019-08-27 22:51:27 +02:00
konradandGitea 66cdd79666 Refactor ListTask to Task (#92) 2019-08-14 20:19:04 +00:00
konradandGitea be14634e1e GetUser now returns a pointer (#93) 2019-08-14 19:59:31 +00:00
kolaente 8fbe721453 [skip ci] updated todo 2019-08-13 22:31:05 +02:00
kolaente 5d3e169883 [skip ci] update todo 2019-08-11 14:56:50 +02:00
kolaente 208eb4e68c Fixed swaggerdocs of description fields 2019-07-21 23:57:19 +02:00
kolaente 8d76280811 [skip ci] updated todo 2019-07-21 23:53:04 +02:00
kolaente 10fbbe1db6 Moved metrics init to seperate methods 2019-07-21 23:44:12 +02:00
konradandGitea 4327a559e5 feature/rate-limit (#91) 2019-07-21 21:27:30 +00:00
kolaente 2e599e792e [skip ci] update todo 2019-07-20 20:46:06 +02:00
konradandGitea 48826a6ed7 Logger refactoring (#90) 2019-07-20 18:12:10 +00:00
kolaente 15a0963bd1 [skip ci] update todo 2019-07-18 22:54:55 +02:00
konradandGitea 9a7d470ce2 Limit the test pipeline to run only on pull requests (#89) 2019-07-18 20:28:56 +00:00
konradandGitea ef0e7c9769 Use longtext instead of varchar(1000) on description fields (#88) 2019-07-18 19:56:34 +00:00
konradandGitea 12eaddc8ee Added http endpoint to list all users on a list (#87) 2019-07-18 16:38:21 +00:00
konradandGitea b63928850a Simplify structure by having less files (#86) 2019-07-16 14:15:40 +00:00
kolaente 4005cd2f32 [skip ci] Updated todo 2019-07-16 01:04:19 +02:00
kolaente 5cc89fd474 [skip ci] Updated todo 2019-07-16 00:56:25 +02:00
konradandGitea e2d9de191d /info endpoint (#85) 2019-07-15 22:54:38 +00:00
kolaente c3ea45d900 Removed rancher from drone config 2019-07-13 19:23:09 +02:00
konradandGitea 50ca8bd28e Statically compile templates in the final binary (#84) 2019-07-11 19:10:42 +00:00
konradandGitea 1f1a079fd3 Better config handling with constants (#83) 2019-07-06 20:12:26 +00:00
kolaente f1d21ea52b Use the auth methods to get IDs to avoid unneeded casts 2019-06-28 10:21:48 +02:00
kolaente fc3c5f2187 Updated the web handler with updated param binder 2019-06-28 09:13:17 +02:00
kolaente 5d3b6573ca Updated echo to use the latest version 2019-06-28 09:01:50 +02:00
konradandGitea 9930f98f8e Compress binaries after building them (#81) 2019-06-22 22:07:58 +00:00
konradandGitea 16825ba7c6 Update echo (#82) 2019-06-22 21:51:58 +00:00
kolaente 4e8c2a7bf6 Fixed avatar url when logging in 2019-06-06 12:28:08 +02:00
kolaente 7f5a6e338c [skip ci] updated todo 2019-06-06 12:13:15 +02:00
konrad 2763df20c9 [skip ci] updated todo 2019-06-05 22:25:55 +02:00
kolaente 9bc09ebbe5 Fixed user sharing not working 2019-06-04 19:45:09 +02:00
konradandGitea 6746984c97 Simplified the docker image (#80) 2019-06-02 14:37:10 +00:00
konradandGitea 7acf318b28 Fixed duedate spelling issue (#79) 2019-05-31 08:10:56 +00:00
konradandGitea f638fae4fd Add the md5-hashed user email to user objects for use with gravatar (#78) 2019-05-31 07:24:59 +00:00
konrad bd930bf654 [skip ci] rearrange todo 2019-05-30 22:32:24 +02:00
kolaente 2cdb0eed3e [skip ci] updated todo 2019-05-27 18:30:08 +02:00
konradandGitea 85d08e5697 Fixed check if the user really exists before updating/deleting its rights (#77) 2019-05-25 10:16:55 +00:00
kolaente 4c4eb76fed [skip ci] updated todo 2019-05-25 11:53:16 +02:00
konradandGitea 50d1f29125 Use the username instead of a user when adding a user to a team or giving it rights (#76) 2019-05-25 09:47:16 +00:00
kolaente 3fffcbd986 [skip ci] updated todo 2019-05-25 10:09:47 +02:00
konradandGitea 24ce940885 Put reminders in an extra table (#75) 2019-05-25 07:33:57 +00:00
konradandGitea 802a13cffd Added settings for max open/idle connections and max connection lifetime (#74) 2019-05-25 05:49:52 +00:00
kolaente 6b348fad04 Used one branch for both fixes in caldav-go 2019-05-24 20:01:59 +02:00
kolaente 951d92b2f0 Fixed ical-go package include 2019-05-24 19:45:58 +02:00
kolaente 24f06b2da5 Fixed ical-go package include 2019-05-24 19:45:33 +02:00
kolaente a7bbaf7c5f Fixed replace directive 2019-05-24 11:57:18 +02:00
konrad 3356a691f7 Removed drone debug env variables 2019-05-22 22:55:32 +02:00
konrad 7d46c88285 Fixed build 2019-05-22 20:36:11 +02:00
konradandGitea 7107d030fc Better caldav support (#73) 2019-05-22 17:48:48 +00:00
konrad de24fcc2f8 Fixed metrics endpoint not working 2019-05-12 16:49:16 +02:00
konrad 3d7fd9ca20 Updated libraries 2019-05-07 21:42:24 +02:00
konradandGitea 2b160b73c3 Fix tests (#72) 2019-04-30 18:36:39 +00:00
kolaente 24704bd4ed Added color field to tasks 2019-04-30 11:26:37 +02:00
konrad 733d0be753 [skip ci] Updated todo 2019-04-28 23:50:38 +02:00
konrad e40ab8652d [skip ci] Updated todo 2019-04-28 23:49:13 +02:00
konrad b854112704 [skip ci] Updated todo 2019-04-28 23:47:25 +02:00
konrad e2820e6806 Merge remote-tracking branch 'origin/master' 2019-04-27 11:41:40 +02:00
konrad a6e70f1b29 Fixed enabling go modules for cross-platform 2019-04-27 11:41:28 +02:00
konrad 44223bde77 Fixed enabling go modules for cross-platform 2019-04-27 11:24:47 +02:00
kolaente d404716342 Fixed integration tests 2019-04-24 22:58:20 +02:00
konrad 7e38937efc Fixed lint 2019-04-23 21:58:42 +02:00
konrad ed671baf8f Fixed listID not being returned in tasks 2019-04-23 21:53:37 +02:00
kolaente d4ff1eca80 Added dependencies 2019-04-23 10:34:28 +02:00
kolaente 6bab8fb769 Updated and re-enabled statickcheck 2019-04-23 10:34:06 +02:00
kolaente 07bdb08f9c Fixed darwin build 2019-04-22 14:31:46 +02:00
kolaente 1117b6eb47 Change path in drone 2019-04-22 14:20:25 +02:00
kolaente 10f80c190b Switched to techknowlogick/xgo 2019-04-22 14:02:18 +02:00
kolaente c8858f6cfb Fixed xgo docker image 2019-04-22 13:27:26 +02:00
kolaente dd1749f11f Disabled staticcheck until their memory leak is resolved 2019-04-22 13:04:16 +02:00
kolaente 99f83542f6 Updated staticcheck 2019-04-22 12:59:42 +02:00
kolaente 5dc1fd0f86 Switched to use src.techknowlogick.com/xgo 2019-04-21 23:07:33 +02:00
kolaente b1701ca769 Removed debugging 2019-04-21 23:04:46 +02:00
kolaente 5cfaa0f322 Debugging 2019-04-21 22:43:18 +02:00
kolaente 7b332808f9 Always fetch tags in drone when building 2019-04-21 22:39:35 +02:00
kolaente 228c47d79e removed unneded drone configs 2019-04-21 22:36:01 +02:00
kolaente 27339a7cf0 Debugging 2019-04-21 21:55:31 +02:00
kolaente 3adfb81d5e Debugging 2019-04-21 21:54:47 +02:00
konradandGitea 3872d1d8a7 Integration tests (#71) 2019-04-21 18:18:17 +00:00
kolaente 46efcb1005 updated version in readme 2019-04-05 17:00:02 +02:00
kolaente 0ed6c6cc0d updated version in readme 2019-04-05 16:54:41 +02:00
kolaente 93dbaea303 Fixed priority not updating when set to 0 2019-04-05 12:40:40 +02:00
kolaente 55e33c1694 [skip ci] updated todo 2019-04-05 12:16:57 +02:00
kolaente 2d9d27f63c Fixed getting lists by namespace 2019-04-02 10:53:16 +02:00
konradandGitea 87873e53c5 Fix rights checks (#70) 2019-04-01 19:48:48 +00:00
konradandGitea 19faee0102 Hide a users email everywhere (#69) 2019-04-01 18:19:55 +00:00
kolaente ac5446e4f5 [skip ci] update todo 2019-03-31 22:33:28 +02:00
kolaente a799527a3c [skip ci] update todo 2019-03-31 22:31:03 +02:00
konradandGitea 2b28ab12f1 Added docs for cli usage and adding new commands (#68) 2019-03-31 19:54:17 +00:00
konradandGitea be5a17e993 DB Migrations (#67) 2019-03-29 17:54:35 +00:00
kolaente e21471a193 Update web handler (fixed) 2019-03-29 18:29:44 +01:00
konrad 81f76f09ce Added docs redirect
Updated docs theme
2019-03-24 19:38:12 +01:00
konrad c27e8fe2f1 updated docs theme 2019-03-24 18:33:42 +01:00
konradandGitea 8d78e473f5 Added cli for general usage of Vikunja (#66) 2019-03-24 17:15:44 +00:00
konradandGitea 5525ee0328 Refactored canRead method to get the list before checking the right (#65) 2019-03-24 13:17:36 +00:00
konradandGitea 47352d3ed4 Let rights methods return errors (#64) 2019-03-24 12:35:50 +00:00
konradandGitea 11e7c071ce Updated handler config (#63) 2019-03-24 09:13:40 +00:00
konrad 1dc14d5ddf Fixed labels not being queried correctly on tasks 2019-03-22 22:03:41 +01:00
kolaente c42e22f352 Fixed bulk update label tasks 2019-03-21 19:26:04 +01:00
kolaente 72e64f7203 Fixed swagger docs for bulk label tasks 2019-03-21 18:42:21 +01:00
kolaente 25999d9b69 Fixed swagger docs for task labels 2019-03-21 07:40:56 +01:00
konradandGitea eb4d38b5b8 Fixed rights check on lists and namespaces (#62) 2019-03-08 21:31:37 +00:00
kolaente 65f428fe78 Updated swagger docs 2019-03-08 15:41:46 +01:00
konrad 2cc968ec61 [skip ci] updated todo 2019-03-07 21:25:54 +01:00
kolaente 073aa9940f [skip ci] update todo 2019-03-03 18:18:47 +01:00
kolaente 5506dd1ceb [skip ci] update todo 2019-03-03 17:43:25 +01:00
kolaente e47313b17e [skip ci] update todo 2019-03-03 15:33:14 +01:00
konrad 7cc172cc0c [skip ci] updated todo 2019-02-24 22:18:20 +01:00
konrad 2bcd6e9cb6 [skip ci] updated todo 2019-02-24 18:35:25 +01:00
konrad afd55d8cf8 [skip ci] updated todo 2019-02-24 12:06:20 +01:00
konrad caed219d39 [skip ci] Update todo 2019-02-23 21:05:10 +01:00
konradandGitea 1b84292332 Fix lint errs (#59) 2019-02-18 19:32:41 +00:00
konradandGitea 15ef6deabc Use query params to sort tasks instead of url params (#61) 2019-02-18 18:06:15 +00:00
konrad a06a5fc4f4 Updated readme and todo 2019-02-17 20:57:28 +01:00
konradandGitea 2d88fad5b1 Huge improvements for docs (#58) 2019-02-17 19:53:04 +00:00
konrad 5e7c9b9eb9 Added possible fix for logging when nothing is set 2019-01-25 21:09:24 +01:00
konradandGitea 9e635ea54e Improve logging handling (#57) 2019-01-25 11:40:54 +00:00
kolaente d0fa9ddaec Remove debugging 2019-01-23 14:33:44 +01:00
konrad add491d1e0 moar debugging 2019-01-22 22:35:00 +01:00
konrad e735378caf added debug + possible fix 2019-01-22 22:15:56 +01:00
konrad f95aa431b8 added debug + possible fix 2019-01-22 21:50:15 +01:00
kolaente 01e7540530 Fix makefile 2019-01-22 13:13:11 +01:00
konradandGitea 75431e1ca5 Rights performance improvements for lists and namespaces (#54) 2019-01-21 22:08:04 +00:00
konrad f6c7c764d1 Fix drone move step 2019-01-21 23:03:11 +01:00
konradandGitea eedc19a49e Build debian packages (#56) 2019-01-21 21:52:26 +00:00
konrad c07e2b6cd4 remove unused makefile variable 2019-01-20 18:43:38 +01:00
konradandGitea 08cbd18bc5 Added more config paths (#55) 2019-01-20 17:13:21 +00:00
konrad 8362799a93 Merge remote-tracking branch 'origin/master' 2019-01-20 00:56:42 +01:00
konrad 3edc728094 [skip ci] updated todo 2019-01-20 00:56:36 +01:00
konradandGitea d3975193fe Fix build building infinitly (#53) 2019-01-18 09:24:07 +00:00
konrad 6b00ccc942 updated todo with a shit ton of new features 2019-01-17 00:57:13 +01:00
konrad 7e8c2bb53b Fixed depend_on 2019-01-16 23:09:18 +01:00
konrad 20c4b249a4 Pipeline now uses two seperate configs to handle tags and pushes to master 2019-01-16 23:07:43 +01:00
konrad 0db5292f9f clone depth now uses the "good" format for drone 1 2019-01-15 23:07:39 +01:00
konrad 08e84f4e8d re-add automatic deploy 2019-01-14 23:53:53 +01:00
konrad a791fe0fa7 updated todo 2019-01-14 23:35:54 +01:00
konradandGitea 19218b28a2 Refactor {List|Namespace}{User|Team} to not expose unneded values via json (#52) 2019-01-14 22:32:56 +00:00
konrad cf0b0a2853 updated todo 2019-01-14 22:51:25 +01:00
konradandGitea 17fefae8bb Simplify list rights check (#50) 2019-01-14 21:49:50 +00:00
konrad 3d05d0aa45 fix dronefile lint 2019-01-14 20:51:30 +01:00
konrad cbcd12b5e5 remove debbugging 2019-01-14 20:48:02 +01:00
konrad 8fdb8b7840 fix debugging 2019-01-14 20:36:40 +01:00
konrad ed44478b20 remove debug step 2019-01-14 20:35:54 +01:00
konrad 0a092214c8 fix section 2019-01-14 18:47:00 +01:00
konrad 3ebf0da1b9 Added debugging for ci 2019-01-14 18:05:09 +01:00
konrad 07bc4f3f01 Added debugging for ci 2019-01-14 17:40:42 +01:00
kolaente cb58f55923 modify signing to sign zip and detach the signature 2019-01-13 01:07:10 +01:00
kolaente 7cc078aaec Fix sequence of drone builds 2019-01-13 00:25:02 +01:00
kolaente d20a899f92 fix sign step 2019-01-13 00:17:45 +01:00
kolaente 3cfe8c238a Add gpg sign step 2019-01-12 23:58:17 +01:00
kolaente 22495a66e0 Fixed minio folder definition 2019-01-12 00:03:41 +01:00
konradandGitea d5e68ee037 Update drone to version 1 (#49) 2019-01-11 22:46:51 +00:00
konradandGitea 318920fe29 Improve label handling (#48) 2019-01-09 23:08:12 +00:00
konradandGitea 364a172876 Assignees optimizations (#47) 2019-01-08 19:13:07 +00:00
kolaente 31c39388f1 Fixed the generated version by the makefile to be more verbose 2019-01-03 23:51:16 +01:00
kolaente 056e37331e [skip ci] Update todo 2019-01-03 23:35:53 +01:00
kolaente 09787fb29b [skip ci] Update todo 2019-01-03 23:31:29 +01:00
konradandGitea 607dbd6ae8 API Docs improvements (#46) 2019-01-03 22:22:06 +00:00
kolaente 3183d10dbe [skip ci] update readme and todo 2018-12-31 02:21:44 +01:00
konradandGitea 6b40df50d3 Add labels to tasks (#45) 2018-12-31 01:18:41 +00:00
konradandGitea d39007baa0 Task assignees (#44) 2018-12-29 14:29:50 +00:00
kolaente 37345e6bd3 update todo
update gitignore
2018-12-28 23:38:43 +01:00
konradandGitea 018dd8164c [CI] Add more checks (#43) 2018-12-28 22:15:05 +00:00
konradandGitea 3814b8a504 Add bulk edit for tasks (#42) 2018-12-28 21:49:46 +00:00
kolaente b050132f4f Update todo 2018-12-27 23:37:25 +01:00
kolaente 36eb580c8a Updated swagger docs 2018-12-25 21:45:26 +01:00
kolaente 067bb695b1 Updated todo 2018-12-25 21:29:55 +01:00
kolaente fd80094eca Updated todo 2018-12-25 21:29:16 +01:00
kolaente ce0bff8d9c Fixed a bug where updating a list would update it with the same values it had before 2018-12-25 15:30:11 +01:00
konradandGitea 5a93475be9 Get tasks between a date range (#41) 2018-12-22 18:06:14 +00:00
konradandGitea 784b890f70 Start end end dates for tasks (#40) 2018-12-22 15:45:16 +00:00
konradandGitea 7322bfafb3 Fix swaggerdocs generation to produce actually valid output (#39) 2018-12-21 21:30:43 +00:00
konrad 0edc5fd315 go mod tidy 2018-12-19 22:07:23 +01:00
konradandGitea cbc5995ad3 Various user fixes (#38) 2018-12-19 21:05:25 +00:00
konradandGitea 3e4f7fb2f4 Fix sorting of tasks in lists (#37) 2018-12-19 19:14:48 +00:00
kolaente 79b463d0af updated todo 2018-12-19 16:50:22 +01:00
konradandGitea 97febdb397 Tests can now use config files (#36) 2018-12-18 16:01:46 +00:00
kolaente 67e94f95b0 update todo 2018-12-18 15:35:20 +01:00
kolaente 34af627b66 updated todo 2018-12-18 10:38:00 +01:00
konradandGitea ec347a71bc Fix "unexpected EOF" error when using metrics (#35) 2018-12-17 12:22:06 +00:00
konradandGitea 777d63dff1 More unit tests (#34) 2018-12-16 13:21:32 +00:00
konrad 424dfe19af Only make all platform builds when pushing to master 2018-12-16 11:53:26 +01:00
kolaente 7b439cc568 Properly init tables for redis 2018-12-14 17:45:31 +01:00
konrad 553055f073 Fixed build 2018-12-13 16:09:00 +01:00
konrad 70f7f630a3 Update todo 2018-12-12 23:56:00 +01:00
konrad 82340cb70b cleanup 2018-12-12 23:53:20 +01:00
konrad 94fd2d758a cleanup 2018-12-12 23:51:40 +01:00
konradandGitea e047673c6b Add prometheus endpoint for getting metrics (#33) 2018-12-12 22:50:35 +00:00
konrad ee398b5272 Updated todo 2018-12-12 16:25:39 +01:00
konrad 3e8fd1e619 updated todo 2018-12-04 23:32:35 +01:00
konradandGitea 0c1d786ade Exlicitly get the pseudonamespace with all shared lists (#32) 2018-12-04 10:16:42 +00:00
kolaente f1fca3346b Merge branch 'master' of ssh://git.kolaente.de:9022/vikunja/api 2018-12-03 15:13:26 +01:00
kolaente 07d6e1219b updated todo 2018-12-03 15:13:21 +01:00
konrad 8e5ff72c4a fixed path to get all tasks (echo bug) 2018-12-02 19:31:03 +01:00
konrad fc17232819 Updated vendor 2018-12-02 19:30:42 +01:00
konrad 8aed78b296 update version in readme 2018-12-02 02:18:31 +01:00
konradandGitea cc6b35e314 Priorites for tasks (#31) 2018-12-02 00:49:30 +00:00
konradandGitea f2f881f505 Fixed generation of swagger docs (#30) 2018-12-01 02:04:10 +00:00
konradandGitea 6c5885747b Subtasks (#28) 2018-12-01 02:00:57 +00:00
konradandGitea 007d8ec375 Fixed generation of swagger docs (#29) 2018-12-01 01:59:17 +00:00
konrad 1b24cdf164 updated todo 2018-12-01 00:28:01 +01:00
konradandGitea ce2cae9430 Move the crudhandler to own repo (#27) 2018-11-30 23:26:56 +00:00
konrad d9304f6996 remove drone github update step 2018-11-28 22:53:55 +01:00
konrad d5e4195ee7 added drone config to update github mirror 2018-11-28 21:04:17 +01:00
konrad 136adb69c8 tidied mod 2018-11-28 20:50:06 +01:00
konradandGitea 06fc9f7886 Repeating tasks (#25) 2018-11-26 20:24:00 +00:00
konradandGitea 3f44e3b83e Change License to GPLv3 (#26) 2018-11-26 20:17:33 +00:00
konradandGitea b73786f7fe Make validation less verbose (#24) 2018-11-25 21:38:50 +00:00
kolaente e5c1588576 Fix docker build 2018-11-25 22:00:43 +01:00
konradandGitea d51ed8defd make validation less verbose (#23) 2018-11-24 12:44:40 +00:00
konradandGitea fded3c23d0 Multiple Reminders (#22) 2018-11-21 15:03:47 +00:00
konradandGitea af0ce5bb96 Added Shared lists overview in namespaces (#21) 2018-11-19 11:37:59 +00:00
konradandGitea 0c112a0ca3 Fixed Validation being to verbose (#20) 2018-11-17 00:12:26 +00:00
konrad 196b6728b8 updated readme 2018-11-17 00:29:10 +01:00
konrad 5bc23458de updated todo 2018-11-17 00:20:48 +01:00
konradandGitea 0c544fe355 Added validation for structs (#19) 2018-11-16 23:17:37 +00:00
konradandGitea 373bbd2202 Migrate to new swagger docs generation (#18) 2018-11-12 15:46:35 +00:00
konradandGitea d3de658882 Implemented search for everything (#17) 2018-11-09 17:33:06 +00:00
konrad ad74d24ee2 updated docs for pagination 2018-11-09 17:28:59 +01:00
konradandGitea d232836423 Added pagination (#16) 2018-11-09 10:30:17 +00:00
konrad 0e7e1b7e38 updated todo 2018-11-06 22:28:56 +00:00
konrad f976fd9f54 updated todo 2018-11-06 22:09:54 +00:00
konradandGitea d03fca801b CalDAV support (#15) 2018-11-03 15:05:45 +00:00
konradandGitea 31a4a1dd00 Added a route to get all tasks sorted desc by their due dates (#14) 2018-11-02 16:59:49 +00:00
konradandGitea 14207a0fa8 Fix tests in drone (#13) 2018-11-02 14:37:11 +00:00
konrad e906184bf7 updated version in readme 2018-11-02 15:29:01 +01:00
kolaente 1f41db9239 Hotfix: fix duplicate header in html mails with templates 2018-11-02 11:23:41 +01:00
konradandGitea 4f8a0f8739 Fixed no root path for templates and static assets (#12) 2018-11-02 10:01:28 +00:00
konradandGitea c51ca4dd26 Fixed dockerfile (#11) 2018-11-02 09:18:38 +00:00
konradandGitea 9e539b8c40 Fix checking for an email verification token (#10) 2018-11-01 22:59:20 +00:00
konradandGitea 9a5eb577b8 Fix not checking for user credentials upon login (#9) 2018-11-01 22:51:05 +00:00
konradandGitea 4713023a97 Prevent login from inactive (aka non-verified) users (#8) 2018-11-01 22:47:41 +00:00
konradandGitea 301a4eedda New structure (#7) 2018-10-31 12:42:38 +00:00
kolaente 3f9fad0e2a use go modules from vendor when building the docker image 2018-10-28 18:38:40 +01:00
kolaente 990740fc19 fixed fmt 2018-10-28 17:35:48 +01:00
kolaente 960d72aa1b Fixed tests 2018-10-28 17:30:10 +01:00
kolaente f94bbf023c Merge branch 'master' of ssh://git.kolaente.de:9022/vikunja/api 2018-10-28 17:24:13 +01:00
kolaente 2556ef7624 added vendor 2018-10-28 17:24:10 +01:00
konradandGitea 321c0f2404 Fix build when using go modules (#6) 2018-10-28 16:11:13 +00:00
konradandGitea 738c22b5f9 Add user email verification when registering (#5) 2018-10-27 13:14:55 +00:00
konradandGitea d0c30cb089 Password reset with token only (#4) 2018-10-27 13:12:15 +00:00
konradandGitea 0cfea682ea Add password reset (#3) 2018-10-27 09:33:28 +00:00
konrad 95197ec6ed moar featurecreep 2018-10-22 22:20:45 +02:00
konrad eecace511d updated todo 2018-10-21 22:22:56 +02:00
konrad 6793e13e6d updated todo 2018-10-21 22:21:37 +02:00
konrad 85da2d72aa updated todo 2018-10-21 22:19:51 +02:00
kolaente 206705d2e9 updated makefile to use new golint url 2018-10-15 12:54:39 +02:00
kolaente 522e647db0 Added config for database max connections 2018-10-11 18:39:53 +02:00
kolaente bbd90eb976 Fixed not setting http code on error 2018-10-11 18:18:44 +02:00
kolaente d8f6a628db Replaced CObject with a function returning an object 2018-10-11 17:53:59 +02:00
kolaente a612037ee1 added go mod 2018-10-11 13:28:41 +02:00
kolaente 224cebfd10 Fixed tests failing 2018-10-06 22:26:17 +02:00
kolaente f4ac036f27 removed unused errors 2018-10-06 18:55:14 +02:00
kolaente c626b05af6 Improved log error messages 2018-10-06 18:44:04 +02:00
kolaente 56dc781594 added docs for error codes 2018-10-06 18:32:33 +02:00
kolaente 1ddb819c31 updated docs 2018-10-06 15:47:26 +02:00
kolaente 75b611de48 updated docs 2018-10-06 15:41:57 +02:00
konrad c5100aad42 updated todo 2018-10-06 15:08:38 +02:00
konrad f969593c0a Improved error handling 2018-10-06 15:04:14 +02:00
konrad a4137b3d6f Added more checks to not leave an error unpassed when checking for rights 2018-10-06 13:25:37 +02:00
konrad 06638fccc8 Fixed lint & misspell 2018-10-06 13:07:42 +02:00
konrad a108ed689d Added extra function to get a list without tasks or user objects 2018-10-06 13:05:29 +02:00
kolaente 53a7f2e6a7 cleanup 2018-10-05 19:17:39 +02:00
kolaente 3819927dd2 updated todo 2018-10-05 19:16:31 +02:00
kolaente cca677878d Optimized used sql queries when getting lists or namespaces with lists 2018-10-05 19:16:14 +02:00
kolaente a1a77a9b75 improved logging format 2018-10-05 18:49:56 +02:00
kolaente 6ea4f0598c fmt 2018-10-05 18:46:05 +02:00
kolaente 358b569bf1 Addded indecies everywhere 2018-10-05 18:46:01 +02:00
kolaente 1139eee2ad Improved update password method to ask the current password 2018-10-04 07:53:45 +02:00
konrad a6d49a5e70 Fixed lint 2018-10-03 19:32:05 +02:00
kolaente cd4fca19fd updated swagger spec 2018-10-03 19:30:43 +02:00
konrad 85c9fba808 Added the ability to update a users password 2018-10-03 19:28:17 +02:00
konrad 17368dea9a Cleanup 2018-10-03 19:00:09 +02:00
konrad 43c67d8c29 added go report badge 2018-09-23 21:16:56 +02:00
konradandGitea e724aeb206 Added new checks (#2)
* added gocyclo-check
* Added new tests to drone
* Added new checks to makefile
2018-09-23 19:15:14 +00:00
konrad b912ff4176 updated drone config 2018-09-22 23:52:19 +02:00
konrad 849b64fc0c updated drone 2018-09-22 22:55:06 +02:00
konrad ce661f1c6e updated drone 2018-09-22 22:38:25 +02:00
konrad 06a4ede4a8 fmt 2018-09-22 11:06:39 +02:00
kolaente 6519c62ade fixed a bug where xorm treid to insert something with an id wich already exist 2018-09-21 08:41:28 +02:00
kolaente bfc783d1d0 updated swagger docs 2018-09-20 22:06:19 +02:00
kolaente e7d43567aa updated readme 2018-09-20 21:59:43 +02:00
kolaente 6c35db57c7 updated todo 2018-09-20 19:44:43 +02:00
kolaente 64d290bcae Added endpoint to search for users 2018-09-20 19:42:01 +02:00
kolaente 3401d7ab2c Fixed makefile 2018-09-20 07:36:58 +02:00
kolaente 8d27daccc6 Fixed lint & fmt 2018-09-20 07:31:36 +02:00
kolaente 0f60c607ee updated todo 2018-09-19 20:52:22 +02:00
kolaente 036a5fcefd updated todo 2018-09-19 08:45:45 +02:00
kolaente 5bb78a749e Fixed list update not working 2018-09-19 08:45:23 +02:00
kolaente aeff343a31 Fixed namespace update not working 2018-09-19 08:44:00 +02:00
kolaente e93cba7108 Added logging 2018-09-19 08:35:53 +02:00
kolaente 091711f4c5 Updated todo 2018-09-19 08:25:24 +02:00
kolaente 477db9ea1c Added swaggercheck to drone build 2018-09-19 08:24:50 +02:00
kolaente cbfb7eafa8 Updated swaggerdocs 2018-09-19 08:23:54 +02:00
kolaente 067672dcb4 Added an endpoint to update a team <-> namespace relation 2018-09-19 08:16:04 +02:00
kolaente aa40ab8eed Added an endpoint to update a team <-> list relation 2018-09-19 08:08:41 +02:00
kolaente 5e8597699d Added endpoint to update a user <-> namespace relation 2018-09-19 08:03:39 +02:00
kolaente 1e993f1e5c Fixed a bug where it was not possible to give a user access to a namespace 2018-09-19 08:03:05 +02:00
kolaente 4f538abc83 Added endpoint to update a users right for a list 2018-09-19 07:54:47 +02:00
kolaente 3a338f54f9 added try link to readme 2018-09-18 18:20:39 +02:00
kolaente 5fbf63bddc /namespaces/{namespaceID}/teams now also returns the team right 2018-09-18 08:17:18 +02:00
kolaente db54309df4 updated todo 2018-09-17 19:51:01 +02:00
kolaente f93a27d67d fmt 2018-09-17 19:46:31 +02:00
kolaente 30ce67c38f updated todo 2018-09-17 19:45:52 +02:00
kolaente 0a06e5a246 /lists/{listID}/teams now also returns the user right 2018-09-17 19:45:18 +02:00
kolaente cf6577445d /namepspaces/{namespacesID}/users now also returns the user right 2018-09-17 19:39:14 +02:00
kolaente b1564659c4 /lists/{listID}/users now also returns the user right 2018-09-17 19:36:44 +02:00
kolaente 59361df9b2 updated todo 2018-09-17 19:32:34 +02:00
kolaente dffb6dab7f updated todo 2018-09-17 19:26:34 +02:00
kolaente 1ea2f0a8c1 updated todo 2018-09-17 19:19:56 +02:00
kolaente 45c5d4fb82 updated todo 2018-09-17 18:45:54 +02:00
kolaente 96cafe0ad9 Moved swaggerdocs to /api/v1/swagger 2018-09-17 18:38:15 +02:00
kolaente 1d62b09792 Moved swaggerdocs to /api/v1/swagger 2018-09-17 18:34:46 +02:00
kolaente 24382f2dc0 Merge remote-tracking branch 'origin/master' 2018-09-17 18:25:17 +02:00
JonasFranzandGitea 26d37bbedf Add /user endpoint (#1) 2018-09-17 16:25:05 +00:00
kolaente 8ca8803404 Updated swaggerdocs 2018-09-17 08:22:31 +02:00
kolaente 42bd69321a Merge remote-tracking branch 'origin/master' 2018-09-17 07:48:03 +02:00
kolaente 382407e07f updated todo 2018-09-17 07:30:23 +02:00
kolaente 5a83ce1216 /namespaces now also gets lists 2018-09-17 07:27:49 +02:00
konrad 4c96ee4263 updated makefile 2018-09-15 16:11:28 +02:00
kolaente 3707f4d3c5 fmt 2018-09-13 22:14:53 +02:00
kolaente 382daac0dd when ID = 0 is passed to a 'GetSthByID'-function, it now returns a 'not exist' error 2018-09-13 20:07:11 +02:00
kolaente 716b06feff added new cache libraries 2018-09-13 19:53:39 +02:00
kolaente 416745ddab added options to configure cache 2018-09-13 19:53:03 +02:00
kolaente 23dc9f777e updated gitignore 2018-09-13 19:30:22 +02:00
kolaente 8cb85dc151 updated gitignore 2018-09-13 19:28:46 +02:00
kolaente fc136948d6 updated gitignore 2018-09-13 19:28:38 +02:00
kolaente 836b5812c0 Merge branch 'master' of ssh://git.kolaente.de:9022/vikunja/api 2018-09-13 19:27:29 +02:00
kolaente 7d8e3f1bae Updated tests 2018-09-13 19:24:40 +02:00
konrad 13145962a4 updated todo 2018-09-12 23:05:13 +02:00
konrad b47c19d46c Merge branch 'master' of ssh://git.kolaente.de:9022/vikunja/api 2018-09-12 22:59:53 +02:00
konrad 7c9818440a updated todo 2018-09-12 22:59:45 +02:00
kolaente c018589749 fixed lint + fmt 2018-09-12 21:45:30 +02:00
kolaente 1f3f8afa85 Fixed a bug where it was not possible for a user to see a namespace which could be access by a team the user was in 2018-09-12 20:13:00 +02:00
kolaente e85d3c4f36 Fixed a bug where a user didn't had access to lists which are not his own, but part of a namespace he owns 2018-09-12 19:56:07 +02:00
kolaente 65818d6f9e Added libs 2018-09-10 22:25:37 +02:00
kolaente 31a850c28e Fixed un-setting a task as done not working 2018-09-10 19:38:35 +02:00
kolaente 431564d63c When updating a list task, all relevant values are now updated. 2018-09-10 19:34:34 +02:00
kolaente 5b8cd30736 Added rancher deploy to drone 2018-09-10 19:24:17 +02:00
kolaente 0da1bb74e0 Fixed lint 2018-09-10 19:22:00 +02:00
kolaente 8ed1fb304e Fixed task update function not updating when marking a task as done 2018-09-10 07:59:45 +02:00
kolaente b91d9eb712 Fixed task update function to be able to update a task with minimal informaton 2018-09-10 07:41:39 +02:00
konrad b16c88a6f3 Added swaggerfiles do dockerfile 2018-09-08 16:54:21 +02:00
kolaente d48f3f9737 fixed crashing when no config was found 2018-09-08 16:43:37 +02:00
konrad 82c098aa0d Updated config to not hard fail when no config file is found. 2018-09-08 16:10:46 +02:00
kolaente 371dd52fa9 updated dockerimage 2018-09-08 16:10:06 +02:00
konrad f0b0319f54 [skip-ci] added s6config 2018-09-08 15:51:49 +02:00
konrad f920e336f0 [skip-ci] added s6config 2018-09-08 15:44:04 +02:00
konrad c834bc14d5 Moved dockerfile 2018-09-08 15:23:53 +02:00
konrad 8245c90bc1 Fixed dockerfile 2018-09-08 15:18:57 +02:00
konrad 9d83293590 Updated makefile 2018-09-08 15:18:15 +02:00
konrad e882fbe6ad Added dockerfile 2018-09-08 15:08:33 +02:00
konrad 6c7f8fd89a updated deps 2018-09-08 13:50:18 +02:00
konrad f47d4586c4 [skip-ci] updated docs 2018-09-08 13:50:05 +02:00
konrad 4d81a13ba5 Updated deps 2018-09-08 13:36:22 +02:00
konrad de10754cb8 Added missing viper dependencies 2018-09-08 13:33:04 +02:00
konrad f45c8aa0ce Fixed lint 2018-09-08 13:31:13 +02:00
konrad 427f752990 Vikunja now uses viper to handle config 2018-09-08 13:29:35 +02:00
kolaente 4f3e016751 Fixed CORS once and for all 2018-09-07 22:49:16 +02:00
kolaente 4749352bbd Fixed cors (Again...) 2018-09-07 08:43:23 +02:00
kolaente 21774fd447 updated todo 2018-09-07 08:24:15 +02:00
konrad 64639ab832 Added cors headers for /namespaces 2018-09-07 08:20:19 +02:00
konrad fc8c6c97fd Updated todo 2018-09-06 19:01:13 +02:00
konrad fb746714d0 Updated return status when creating 2018-09-06 18:57:28 +02:00
konrad c1767d219a Fixed getting all lists of a namespace not working 2018-09-06 18:55:58 +02:00
kolaente 37de3ef232 Fixed user_namespace relation not working 2018-09-06 18:52:10 +02:00
kolaente 6d971c5fe1 fmt 2018-09-06 08:46:47 +02:00
kolaente c43db9929b Namespaces now respect user rights 2018-09-06 08:46:34 +02:00
konrad 521e7c3bef List rights are now respected 2018-09-06 08:42:18 +02:00
konrad 92174aac08 Fixed a bug where a user could see every namespace 2018-09-06 08:39:05 +02:00
konrad f2758e239c Added namespace user rights 2018-09-04 20:15:24 +02:00
konrad 422662e3e1 updated featurecreep 2018-09-04 19:54:15 +02:00
konrad 245259216f Fixed creating of new users 2018-09-04 19:39:31 +02:00
konrad 906aee8b7d Updated featurecreep 2018-08-30 19:18:36 +02:00
konrad 76f3357a0c fmt 2018-08-30 19:14:16 +02:00
konrad 478c98fb8d Refactor GetUser & GetUserByID 2018-08-30 19:14:02 +02:00
konrad aeb1521cc4 Cleanup/fixing methods 2018-08-30 19:00:27 +02:00
konrad efaa277751 Added methods to revoke a users access to a list 2018-08-30 18:52:12 +02:00
konrad b1c3e92f66 Added methods to give users access to a list 2018-08-30 08:58:09 +02:00
konrad d31f16aff1 Renamed list items to tasks 2018-08-30 08:09:17 +02:00
konrad d5758e0444 fmt 2018-08-29 15:22:17 +02:00
konrad c17dec7954 Updated swagger docs 2018-08-29 15:13:54 +02:00
konrad 4e70486a9b Cleanup 2018-08-29 14:40:03 +02:00
konrad bdff353e78 Added tests for team <-> list relations 2018-08-29 14:33:04 +02:00
konrad 98e3d3e884 Added tests for team <-> list relations 2018-08-29 08:50:52 +02:00
konrad 950533df21 Added tests for team namespace relationsk 2018-08-29 08:26:59 +02:00
kolaente f71f98b8f4 updated featurecreep 2018-08-29 08:02:12 +02:00
kolaente 5db306bacc fmt 2018-07-27 19:28:12 +02:00
kolaente 261136c2bc Added tests for team members 2018-07-27 19:20:49 +02:00
kolaente d556162591 fmt 2018-07-27 16:28:28 +02:00
kolaente 51064f3d8f Added tests for teams 2018-07-27 16:28:09 +02:00
kolaente a55e28df76 updated todo 2018-07-27 15:57:47 +02:00
kolaente 62ac4c2a74 fmt 2018-07-27 15:53:01 +02:00
kolaente 628f3eee64 Added tests for namespaces 2018-07-27 15:52:50 +02:00
kolaente ba606515d1 Improved tests for lists 2018-07-27 15:11:47 +02:00
kolaente f7bc88c825 Added tests for listitems 2018-07-27 14:47:52 +02:00
kolaente 2c12797111 fmt 2018-07-26 10:50:03 +02:00
kolaente c97a4d74cb Added check if the namespace exists when creating a list 2018-07-26 10:49:33 +02:00
kolaente 6eeab7fe10 improved tests 2018-07-26 10:49:17 +02:00
kolaente a78b333e3f Added tests for list creation 2018-07-26 10:29:19 +02:00
kolaente 935aef8a38 Added check for list title when creating a new list 2018-07-26 10:29:09 +02:00
kolaente a9094506fa cleanup 2018-07-26 10:10:39 +02:00
kolaente 7b07137b67 fmt 2018-07-26 10:08:01 +02:00
kolaente fba505130d updated gitignore 2018-07-26 10:07:18 +02:00
kolaente 80e9021ba6 Fixed a bug where it was possible to add the same user multiple times to a team 2018-07-26 10:06:41 +02:00
konrad 9c451daf30 Added method to delete a user from a team 2018-07-26 09:58:48 +02:00
konrad bc580e0115 Added method to add a user to a team 2018-07-26 09:53:32 +02:00
kolaente 0b2f66965a [skip-ci] updated todo 2018-07-25 23:03:53 +02:00
kolaente 4baf74a999 Added http test files 2018-07-25 22:26:53 +02:00
kolaente 29e3afdd08 Added roadmap 2018-07-25 21:47:26 +02:00
kolaente 5b0788ed1e renamed build steps 2018-07-25 17:43:38 +02:00
kolaente 8f2a24298d fixed makefile
+ lint & fmt
2018-07-25 17:30:29 +02:00
kolaente 32b369e2e4 Added drone 2018-07-25 17:28:54 +02:00
kolaente 01aa1910ef Renamed all packages 2018-07-25 16:26:32 +02:00
kolaente 0df8881028 Renamed all packages 2018-07-25 16:24:46 +02:00
kolaente d18570574a updated todo 2018-07-25 00:51:23 +02:00
kolaente e602914659 Implemented proper check for team rights on namespaces 2018-07-25 00:49:44 +02:00
kolaente f36eeb662a Implemented proper check for team rights on lists 2018-07-25 00:40:24 +02:00
konrad 7dc8699cbd updated todo
+ fmt
2018-07-24 17:47:08 +02:00
kolaente 26c2ad078f Fixed a bug where it was possible to add a team multiple times to a list/namespace 2018-07-24 17:46:32 +02:00
kolaente 9638f36788 implemented deletomg a team from a list 2018-07-24 17:32:08 +02:00
kolaente 227a2afd37 implemented viewing all teams of a list 2018-07-24 17:29:46 +02:00
kolaente edf9b6f2c7 Implemented creating a team <-> list relation 2018-07-24 17:29:13 +02:00
konrad 6ff10e6353 added missing libraries 2018-07-24 14:06:03 +02:00
kolaente 9de26f6547 cleanup 2018-07-24 13:56:57 +02:00
kolaente 9c0c9474e8 Migrated to dep instead of govendor 2018-07-24 13:49:45 +02:00
konrad 0a2eae120e More docs 2018-07-24 00:48:02 +02:00
konrad 7e0965ed91 docs 2018-07-21 15:45:46 +02:00
konrad 0487889963 fmt + lint + docs 2018-07-21 15:28:09 +02:00
konrad 9979b7e321 implemented update method via param binder 2018-07-21 15:17:02 +02:00
konrad 9e75e9b73b implemented readone with parambinder 2018-07-21 15:08:46 +02:00
konrad d06ed68125 cleanup 2018-07-18 22:19:51 +02:00
konrad 935c99be45 implemented read all method for namespace teams 2018-07-18 22:06:29 +02:00
konrad 6618874441 Fixed parambinder 2018-07-18 21:54:04 +02:00
konrad de95ff40bf implemented creation of thing via parambinder 2018-07-18 08:56:19 +02:00
konrad ebb5b332b6 implemented delete team <-> namespace relation 2018-07-18 08:16:15 +02:00
konrad 249128a46e implemented binding url params directly to struct instead of passing them to the method for deleting items 2018-07-18 08:15:38 +02:00
konrad f0c003d069 implemented custom param binder
This is currently more a workaround, until the echo pr gets merged
2018-07-17 23:10:54 +02:00
kolaente 1a7779a229 Merge branch 'master' of ssh://git.kolaente.de:9022/vikunja/api 2018-07-17 09:10:45 +02:00
konrad 7feb82702d implemented create team <-> namespace relation 2018-07-17 08:44:21 +02:00
konrad 2e3c10be13 updated todo + cleanup 2018-07-17 08:16:04 +02:00
konrad 0439bade41 updated todo 2018-07-16 22:17:35 +02:00
kolaente a46901397b Merge remote-tracking branch 'real-origin/master' 2018-07-16 09:16:21 +02:00
konrad f6a816941b implemented get all teams the user is part of 2018-07-16 08:52:16 +02:00
konrad b11bd9f0b1 fixed lint 2018-07-16 08:45:38 +02:00
konrad 7dc4cd2173 Implemented Get one team method 2018-07-16 08:43:47 +02:00
konrad 8a06db5351 Implemented team delete method 2018-07-16 08:18:15 +02:00
kolaente 90da51ad7e Updated sample config 2018-07-15 18:31:43 +02:00
konrad 4cf0cd233c Implemented team update method 2018-07-14 18:29:24 +02:00
konrad bcbd415529 Fixed a bug where a struct would have old values in it 2018-07-14 17:46:01 +02:00
konrad a5552b8f9d fixed lint + fmt 2018-07-14 17:37:46 +02:00
konrad bc0e6da602 cleanup 2018-07-14 17:36:17 +02:00
konrad e1c58843e9 implemented team create method 2018-07-14 17:34:59 +02:00
konrad 376c649a12 cleanup 2018-07-12 23:47:50 +02:00
konrad bb44b2f98c fmt 2018-07-12 23:37:14 +02:00
konrad 7f7b243cbe cleanup 2018-07-12 23:36:55 +02:00
konrad c5888093fe Implemented deletion of namespaces 2018-07-12 23:33:37 +02:00
konrad 55c02bc973 Fixed CanDelete 2018-07-12 23:33:21 +02:00
konrad b24b245f4d Fixed creation of new namespaces 2018-07-12 23:22:02 +02:00
konrad e5493965ff Fixed creation of new lists 2018-07-12 23:18:50 +02:00
konrad ddcc063b0b Implemented CanCreate method 2018-07-12 23:16:32 +02:00
konrad 6fd2a97574 Implemented CanUpdate method 2018-07-12 23:07:03 +02:00
konrad e3b996c383 Cleanup 2018-07-12 22:42:41 +02:00
konrad 4e503072a8 Implemented CanDelete method for lists and listitems 2018-07-12 21:20:24 +02:00
konrad 217208274e cleanup 2018-07-12 21:10:58 +02:00
konrad 32fde286db Optimized right checking
+ list.ReadAll now really gets all lists
2018-07-12 21:07:59 +02:00
konrad bae9c7f35e Added right check for namespaces 2018-07-12 13:43:42 +02:00
konrad fb4fa25f2f fmt 2018-07-12 11:55:07 +02:00
konrad 868b93dbbc implemented get one namespace via interface mthod 2018-07-12 11:54:55 +02:00
konrad 6f5cf55e42 fmt + lint 2018-07-12 00:37:31 +02:00
konrad 4ae95c1333 Updated featurecreep 2018-07-12 00:36:38 +02:00
konrad 261aaba315 implemented namespace update via interface method 2018-07-12 00:30:31 +02:00
konrad 0aa84e653f implemented namespace creation via interface method 2018-07-12 00:09:16 +02:00
konrad 4734a0a6a6 use echo.NewHTTPError 2018-07-11 14:27:16 +02:00
konrad 4213f3b08c implemented get all namespaces via interface 2018-07-11 13:00:00 +02:00
konrad 5c4fb7ed73 implemented delete list item via CRUD 2018-07-11 11:44:17 +02:00
konrad 281e9c1cd0 fmt 2018-07-11 02:40:29 +02:00
konrad ee4a904e35 Implemented create and update methods for items 2018-07-11 02:39:55 +02:00
konrad 592dc20af4 List item creation is now done via handler 2018-07-11 02:13:53 +02:00
konrad b067425dc3 more optimization 2018-07-11 01:45:11 +02:00
konrad e97fa30202 more optimization 2018-07-11 00:28:53 +02:00
konrad 237874eda6 Fixed lint + fmt 2018-07-10 14:02:23 +02:00
konrad c8622b0029 Implemented Delete methods on list 2018-07-10 13:27:25 +02:00
kolaente b1de837c4f Implemented Create and Update methods on list 2018-07-09 23:17:19 +02:00
kolaente 9e8f13edf6 Getting all lists or one works now 2018-07-09 19:49:27 +02:00
kolaente d5eb2f08e3 Implemented CRUD Helper, every struct needs its own methods 2018-07-08 22:50:01 +02:00
kolaente 0c5ed914e0 CRUD helper now returns directly the target struct filled with data instead of a sub objectq 2018-07-08 13:26:43 +02:00
kolaente 490f32d46b Added CRUD helper method 2018-07-07 14:19:34 +02:00
kolaente 2d0d074f89 small optimizations 2018-07-06 08:40:35 +02:00
kolaente 31eb916af2 updated featurecreep 2018-07-05 08:55:34 +02:00
kolaente 462dfc8868 Implemented method to add a list to a namespace 2018-07-05 08:52:05 +02:00
kolaente 93efaa95f8 Implemented method to delete a namespace 2018-07-04 19:21:04 +02:00
kolaente 2d81330b27 Removed debugging 2018-07-04 18:44:13 +02:00
kolaente f59917e721 Fixed getting all lists of one namespace 2018-07-04 08:56:52 +02:00
kolaente b57ca9375a Fixed namespace updates not working 2018-07-04 08:15:47 +02:00
kolaente ac134fb16b Small fixes to manage namespaces 2018-07-03 09:09:44 +02:00
kolaente 064e1cd3b7 Small fixes to manage namespaces 2018-07-03 08:48:28 +02:00
kolaente e0244e28d7 Added method to show all lists in a namespace 2018-07-03 08:26:28 +02:00
kolaente 06cae09f77 Added method to show one namespace 2018-07-02 09:09:32 +02:00
kolaente 124e4f4a5b Added method to show all namespaces a user has access to 2018-07-02 08:54:44 +02:00
kolaente 6dfdcb9571 Added basic functions + endpoints to add/update namespaces 2018-07-02 08:40:24 +02:00
kolaente bd2bf24813 Started working on namespaces 2018-06-14 17:43:00 +02:00
kolaente ac0a50663d Added basic definitions for namespaces and teams 2018-06-14 16:14:49 +02:00
kolaente 6398134eef More Featurecreep. Or call it a plan. Whatever you want. 2018-06-14 14:58:00 +02:00
kolaente 6141956847 Added swagger UI 2018-06-14 14:19:19 +02:00
kolaente 33c5f91491 Updated Roadmap 2018-06-13 13:49:19 +02:00
kolaente 8500659aec added generated swagger spec 2018-06-13 13:45:53 +02:00
kolaente 4589f3b4bb Added docs via swagger 2018-06-13 13:45:22 +02:00
kolaente 0652125c25 Fixed returning of user infos when updating a todo item 2018-06-13 12:18:55 +02:00
konrad b11a6b912e More Featurecreep 2018-06-12 19:57:48 +02:00
konrad f0f92ad1a1 Improved creation of list items 2018-06-12 19:57:38 +02:00
konrad fc974fd87f Added endpoint to be able to edit list items 2018-06-12 19:44:47 +02:00
konrad 1b3b2ccb59 Improved item deletion rights check 2018-06-12 18:49:56 +02:00
konrad 1bb7187285 Added check to only let a user delete his own list 2018-06-12 18:46:59 +02:00
konrad be18247682 Added check to only let a user delete his own list 2018-06-12 18:35:36 +02:00
konrad 5ba9d76328 Added method to delete a list 2018-06-12 18:17:52 +02:00
konrad dcb046665f Added method to delete a list 2018-06-12 18:17:21 +02:00
kolaente 853fb2a2b7 Added method to delete a todo item from a list 2018-06-12 18:07:47 +02:00
konrad 91f67dc364 Added functions for adding items to a todolist 2018-06-10 19:49:40 +02:00
konrad 7bac9f490e Started adding listitems 2018-06-10 15:55:56 +02:00
konrad abd21f0c14 Plan. 2018-06-10 15:32:25 +02:00
konrad cf4871af59 cleanup 2018-06-10 14:43:35 +02:00
konrad 125f0ba230 Added lists view 2018-06-10 14:41:42 +02:00
konrad b841ec121b unit tests improvments 2018-06-10 14:24:33 +02:00
konrad 2cf20fe1c4 fixed lint + fmt 2018-06-10 14:22:37 +02:00
konrad f372128784 Added list create and update methods 2018-06-10 14:14:10 +02:00
konrad fb4c9d580c Update gitignore 2018-06-10 11:41:29 +02:00
konrad db6c2bfd8f made tests work again 2018-06-10 11:41:10 +02:00
konrad 5510249813 updated fixtures 2018-06-10 11:37:24 +02:00
konrad d840651a24 removed unused errors 2018-06-10 11:35:53 +02:00
konrad 1bee67cac7 Made registration work 2018-06-10 11:34:59 +02:00
kolaente 2ca4c521aa deleted old binary 2018-06-10 11:13:23 +02:00
konrad 986059d719 updated makefile 2018-06-10 11:13:01 +02:00
konrad 479cf54ada initial commit 2018-06-10 11:11:42 +02:00
2519 changed files with 920372 additions and 3393 deletions
-236
View File
@@ -1,236 +0,0 @@
---
kind: pipeline
type: docker
name: build
trigger:
branch:
exclude:
- main
event:
include:
- push
- pull_request
steps:
- name: fetch-tags
image: docker:git
commands:
- git fetch --tags
- name: restore-cache
image: meltwater/drone-cache:dev
pull: true
environment:
AWS_ACCESS_KEY_ID:
from_secret: cache_aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: cache_aws_secret_access_key
settings:
restore: true
bucket: kolaente.dev-drone-dependency-cache
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
path_style: true
cache_key: '{{ .Repo.Name }}_{{ checksum "yarn.lock" }}_{{ arch }}_{{ os }}'
mount:
- '.cache'
- name: build
image: electronuserland/builder:wine-mono
pull: true
environment:
YARN_CACHE_FOLDER: .cache/yarn/
depends_on:
- fetch-tags
- restore-cache
commands:
- export VERSION=${DRONE_TAG##v}
- if [ -z "$$VERSION" ]; then export VERSION=unstable; fi
# TODO: Move to a yarn script
- wget https://dl.vikunja.io/frontend/vikunja-frontend-$$VERSION.zip
- unzip vikunja-frontend-$$VERSION.zip -d frontend
- sed -i 's/\\/api\\/v1//g' frontend/index.html
# Make sure that the -unstable suffix is added to release files
- sed -i "s/\$${version}/$$VERSION/g" package.json
- yarn install
- yarn dist --linux --windows
- name: rebuild-cache
image: meltwater/drone-cache:dev
pull: true
environment:
AWS_ACCESS_KEY_ID:
from_secret: cache_aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: cache_aws_secret_access_key
settings:
rebuild: true
bucket: kolaente.dev-drone-dependency-cache
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
path_style: true
cache_key: '{{ .Repo.Name }}_{{ checksum "yarn.lock" }}_{{ arch }}_{{ os }}'
mount:
- '.cache'
depends_on:
- build
---
kind: pipeline
type: docker
name: release
trigger:
ref:
- refs/heads/main
- "refs/tags/**"
steps:
- name: fetch-tags
image: docker:git
commands:
- git fetch --tags
- name: restore-cache
image: meltwater/drone-cache:dev
pull: true
environment:
AWS_ACCESS_KEY_ID:
from_secret: cache_aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: cache_aws_secret_access_key
settings:
restore: true
bucket: kolaente.dev-drone-dependency-cache
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
path_style: true
cache_key: '{{ .Repo.Name }}_{{ checksum "yarn.lock" }}_{{ arch }}_{{ os }}'
mount:
- '.cache'
- name: build
image: electronuserland/builder:wine-mono
pull: true
environment:
YARN_CACHE_FOLDER: .cache/yarn/
depends_on:
- fetch-tags
- restore-cache
commands:
- export VERSION=${DRONE_TAG##v}
- if [ -z "$$VERSION" ]; then export VERSION=unstable; fi
# TODO: Move to a yarn script
- wget https://dl.vikunja.io/frontend/vikunja-frontend-$$VERSION.zip
- unzip vikunja-frontend-$$VERSION.zip -d frontend
- sed -i 's/\\/api\\/v1//g' frontend/index.html
# Make sure that the -unstable suffix is added to release files
- sed -i "s/\$${version}/$$VERSION/g" package.json
- yarn install
- yarn dist --linux --windows
- name: rebuild-cache
image: meltwater/drone-cache:dev
pull: true
environment:
AWS_ACCESS_KEY_ID:
from_secret: cache_aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: cache_aws_secret_access_key
settings:
rebuild: true
bucket: kolaente.dev-drone-dependency-cache
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
path_style: true
cache_key: '{{ .Repo.Name }}_{{ checksum "yarn.lock" }}_{{ arch }}_{{ os }}'
mount:
- '.cache'
depends_on:
- build
- name: release-latest
image: plugins/s3
pull: true
settings:
bucket: vikunja-releases
access_key:
from_secret: aws_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
path_style: true
strip_prefix: dist/
source: dist/*
target: /desktop/unstable/
when:
event:
exclude:
- tag
depends_on: [ build ]
- name: release-version
image: plugins/s3
pull: true
settings:
bucket: vikunja-releases
access_key:
from_secret: aws_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
path_style: true
strip_prefix: dist/
source: dist/*
target: /desktop/${DRONE_TAG##v}/
when:
event:
- tag
depends_on: [ build ]
# Disabled until we have a working mac runner
#---
#kind: pipeline
#type: exec
#name: release-macos
#
#trigger:
# ref:
# - refs/heads/main
# - "refs/tags/**"
#
#platform:
# os: darwin
# arch: amd64
#
#steps:
# - name: build
# environment:
# ACCESS_KEY:
# from_secret: aws_access_key_id
# SECRET_KEY:
# from_secret: aws_secret_access_key
# commands:
# - git fetch --tags
# - export VERSION=${DRONE_TAG##v}
# - if [ -z "$$VERSION" ]; then export VERSION=unstable; fi
# # TODO: Move to a yarn script
# - wget https://dl.vikunja.io/frontend/vikunja-frontend-$$VERSION.zip
# - unzip vikunja-frontend-$$VERSION.zip -d frontend
# - sed -i '' 's/\\/api\\/v1//g' frontend/index.html
# # Make sure that the -unstable suffix is added to release files
# - sed -i '' "s/\$${version}/$$VERSION/g" package.json
# - yarn install
# - yarn dist --mac
# - mc config host add scw-fr-par https://s3.fr-par.scw.cloud $ACCESS_KEY $SECRET_KEY --api S3v4
# - mc cp ./dist/*.dmg scw-fr-par/vikunja-releases/desktop/$VERSION/
# - mc cp ./dist/*.dmg.blockmap scw-fr-par/vikunja-releases/desktop/$VERSION/
---
kind: signature
hmac: f5aa08e285044e34b02b197a309bb8682b8cc9adf630dabaa18cc09cc6b50cf6
...
+617
View File
@@ -0,0 +1,617 @@
kind: pipeline
name: testing
workspace:
base: /go
path: src/code.vikunja.io/api
services:
- name: test-mysql-unit
image: mariadb:10
environment:
MYSQL_ROOT_PASSWORD: vikunjatest
MYSQL_DATABASE: vikunjatest
- name: test-mysql-integration
image: mariadb:10
environment:
MYSQL_ROOT_PASSWORD: vikunjatest
MYSQL_DATABASE: vikunjatest
- name: test-postgres-unit
image: postgres:12
environment:
POSTGRES_PASSWORD: vikunjatest
POSTGRES_DB: vikunjatest
- name: test-postgres-integration
image: postgres:12
environment:
POSTGRES_PASSWORD: vikunjatest
POSTGRES_DB: vikunjatest
trigger:
branch:
include:
- master
event:
include:
- push
- pull_request
steps:
- name: fetch-tags
image: docker:git
commands:
- git fetch --tags
- name: build
image: vikunja/golang-build:latest
pull: true
environment:
GOFLAGS: '-mod=vendor'
commands:
- make generate
- make lint
- make fmt-check
# - make got-swag # Commented out until we figured out how to get this working on drone
- make ineffassign-check
- make misspell-check
- make goconst-check
- make gocyclo-check
- make static-check
- wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $GOPATH/bin v2.2.0 # Need to manually install as it does not support being installed via go modules like the rest.
- make gosec-check
- make build
when:
event: [ push, tag, pull_request ]
- name: test
image: vikunja/golang-build:latest
pull: true
commands:
- make test
depends_on: [ build ]
when:
event: [ push, tag, pull_request ]
- name: test-sqlite
image: vikunja/golang-build:latest
pull: true
environment:
VIKUNJA_TESTS_USE_CONFIG: 1
VIKUNJA_DATABASE_TYPE: sqlite
commands:
- make test
depends_on: [ build ]
when:
event: [ push, tag, pull_request ]
- name: test-mysql
image: vikunja/golang-build:latest
pull: true
environment:
VIKUNJA_TESTS_USE_CONFIG: 1
VIKUNJA_DATABASE_TYPE: mysql
VIKUNJA_DATABASE_HOST: test-mysql-unit
VIKUNJA_DATABASE_USER: root
VIKUNJA_DATABASE_PASSWORD: vikunjatest
VIKUNJA_DATABASE_DATABASE: vikunjatest
commands:
- make test
depends_on: [ build ]
when:
event: [ push, tag, pull_request ]
- name: test-postgres
image: vikunja/golang-build:latest
pull: true
environment:
VIKUNJA_TESTS_USE_CONFIG: 1
VIKUNJA_DATABASE_TYPE: postgres
VIKUNJA_DATABASE_HOST: test-postgres-unit
VIKUNJA_DATABASE_USER: postgres
VIKUNJA_DATABASE_PASSWORD: vikunjatest
VIKUNJA_DATABASE_DATABASE: vikunjatest
VIKUNJA_DATABASE_SSLMODE: disable
commands:
- make test
depends_on: [ build ]
when:
event: [ push, tag, pull_request ]
- name: integration-test
image: vikunja/golang-build:latest
pull: true
commands:
- make integration-test
depends_on: [ build ]
when:
event: [ push, tag, pull_request ]
- name: integration-test-sqlite
image: vikunja/golang-build:latest
pull: true
environment:
VIKUNJA_TESTS_USE_CONFIG: 1
VIKUNJA_DATABASE_TYPE: sqlite
commands:
- make integration-test
depends_on: [ build ]
when:
event: [ push, tag, pull_request ]
- name: integration-test-mysql
image: vikunja/golang-build:latest
pull: true
environment:
VIKUNJA_TESTS_USE_CONFIG: 1
VIKUNJA_DATABASE_TYPE: mysql
VIKUNJA_DATABASE_HOST: test-mysql-integration
VIKUNJA_DATABASE_USER: root
VIKUNJA_DATABASE_PASSWORD: vikunjatest
VIKUNJA_DATABASE_DATABASE: vikunjatest
commands:
- make integration-test
depends_on: [ build ]
when:
event: [ push, tag, pull_request ]
- name: integration-test-postgres
image: vikunja/golang-build:latest
pull: true
environment:
VIKUNJA_TESTS_USE_CONFIG: 1
VIKUNJA_DATABASE_TYPE: postgres
VIKUNJA_DATABASE_HOST: test-postgres-integration
VIKUNJA_DATABASE_USER: postgres
VIKUNJA_DATABASE_PASSWORD: vikunjatest
VIKUNJA_DATABASE_DATABASE: vikunjatest
VIKUNJA_DATABASE_SSLMODE: disable
commands:
- make integration-test
depends_on: [ build ]
when:
event: [ push, tag, pull_request ]
---
########
# Build a release when pushing to master
# We need to copy this because drone currently can't run a pipeline on either a push to master or a tag.
########
kind: pipeline
name: deploy-master
depends_on:
- testing
workspace:
base: /go
path: src/code.vikunja.io/api
trigger:
branch:
- master
event:
- push
steps:
# Needed to get the versions right as they depend on tags
- name: fetch-tags
image: docker:git
commands:
- git fetch --tags
- name: before-static-build
image: techknowlogick/xgo:latest
pull: true
commands:
- export PATH=$PATH:$GOPATH/bin
- make generate
- make release-dirs
depends_on: [ fetch-tags ]
- name: static-build-windows
image: techknowlogick/xgo:latest
pull: true
environment:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
# Leaving this here until we know how to resolve this properly.
GOPATH: /srv/app
commands:
- export PATH=$PATH:$GOPATH/bin
- make release-windows
depends_on: [ before-static-build ]
- name: static-build-linux
image: techknowlogick/xgo:latest
pull: true
environment:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
# Leaving this here until we know how to resolve this properly.
GOPATH: /srv/app
commands:
- export PATH=$PATH:$GOPATH/bin
- make release-linux
depends_on: [ before-static-build ]
- name: static-build-darwin
image: techknowlogick/xgo:latest
pull: true
environment:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
# Leaving this here until we know how to resolve this properly.
GOPATH: /srv/app
commands:
- export PATH=$PATH:$GOPATH/bin
- make release-darwin
depends_on: [ before-static-build ]
- name: after-build-compress
image: kolaente/upx
pull: true
depends_on:
- static-build-windows
- static-build-linux
- static-build-darwin
commands:
- make release-compress
- name: after-build-static
image: techknowlogick/xgo:latest
pull: true
depends_on:
- after-build-compress
commands:
- make release-copy
- make release-check
- make release-os-package
- make release-zip
- name: sign-release
image: plugins/gpgsign:1
pull: true
depends_on: [ after-build-static ]
settings:
key:
from_secret: gpg_privkey
passphrase:
from_secret: gpg_password
files:
- dist/zip/*
detach_sign: true
# Push the releases to our pseudo-s3-bucket
- name: release-latest
image: plugins/s3:1
pull: true
settings:
bucket: vikunja
access_key:
from_secret: aws_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://storage.kolaente.de
path_style: true
strip_prefix: dist/zip/
source: dist/zip/*
target: /api/master/
depends_on: [ sign-release ]
# Build a debian package and push it to our bucket
- name: build-deb
image: kolaente/fpm
pull: true
commands:
- make build-deb
depends_on: [ static-build-linux ]
- name: deb-structure
image: kolaente/reprepro
pull: true
environment:
GPG_PRIVATE_KEY:
from_secret: gpg_privatekey
commands:
- export GPG_TTY=$(tty)
- gpg -qk
- echo "use-agent" >> ~/.gnupg/gpg.conf
- gpgconf --kill gpg-agent
- echo $GPG_PRIVATE_KEY > ~/frederik.gpg
- gpg --import ~/frederik.gpg
- mkdir debian/conf -p
- cp build/reprepro-dist-conf debian/conf/distributions
- make reprepro
depends_on: [ build-deb ]
# Push the releases to our pseudo-s3-bucket
- name: release-deb
image: plugins/s3:1
pull: true
settings:
bucket: vikunja
access_key:
from_secret: aws_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://storage.kolaente.de
path_style: true
strip_prefix: debian
source: debian/*/*/*/*/*
target: /deb/
depends_on: [ deb-structure ]
# Build the docker image and push it to docker hub
- name: docker
image: plugins/docker
pull: true
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: vikunja/api
auto_tag: true
depends_on: [ fetch-tags ]
- name: telegram
image: appleboy/drone-telegram
depends_on:
- release-latest
settings:
token:
from_secret: TELEGRAM_TOKEN
to:
from_secret: TELEGRAM_TO
message: >
{{repo.owner}}/{{repo.name}}: \[{{build.status}}] Build {{build.number}}
{{commit.author}} pushed to {{commit.branch}} {{commit.sha}}: `{{commit.message}}`
Build started at {{datetime build.started "2006-Jan-02T15:04:05Z" "GMT+2"}} finished at {{datetime build.finished "2006-Jan-02T15:04:05Z" "GMT+2"}}.
when:
status:
- success
- failure
---
########
# Build a release when tagging
# We need to copy this because drone currently can't run a pipeline on either a push to master or a tag.
########
kind: pipeline
name: deploy-version
depends_on:
- testing
workspace:
base: /go
path: src/code.vikunja.io/api
trigger:
event:
- tag
steps:
- name: fetch-tags
image: docker:git
commands:
- git fetch --tags
- name: before-static-build
image: techknowlogick/xgo:latest
pull: true
commands:
- make generate
- make release-dirs
depends_on: [ fetch-tags ]
- name: static-build-windows
image: techknowlogick/xgo:latest
pull: true
environment:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
# Leaving this here until we know how to resolve this properly.
GOPATH: /srv/app
commands:
- export PATH=$PATH:$GOPATH/bin
- make release-windows
depends_on: [ before-static-build ]
- name: static-build-linux
image: techknowlogick/xgo:latest
pull: true
environment:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
# Leaving this here until we know how to resolve this properly.
GOPATH: /srv/app
commands:
- export PATH=$PATH:$GOPATH/bin
- make release-linux
depends_on: [ before-static-build ]
- name: static-build-darwin
image: techknowlogick/xgo:latest
pull: true
environment:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
# Leaving this here until we know how to resolve this properly.
GOPATH: /srv/app
commands:
- export PATH=$PATH:$GOPATH/bin
- make release-darwin
depends_on: [ before-static-build ]
- name: after-build-compress
image: kolaente/upx
pull: true
depends_on:
- static-build-windows
- static-build-linux
- static-build-darwin
commands:
- make release-compress
- name: after-build-static
image: techknowlogick/xgo:latest
pull: true
depends_on:
- after-build-compress
commands:
- make release-copy
- make release-check
- make release-os-package
- make release-zip
- name: sign-release
image: plugins/gpgsign:1
pull: true
depends_on: [ after-build-static ]
settings:
key:
from_secret: gpg_privkey
passphrase:
from_secret: gpg_password
files:
- dist/zip/*
detach_sign: true
# Push the releases to our pseudo-s3-bucket
- name: release-version
image: plugins/s3:1
pull: true
settings:
bucket: vikunja
access_key:
from_secret: aws_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://storage.kolaente.de
path_style: true
strip_prefix: dist/zip/
source: dist/zip/*
target: /api/${DRONE_TAG##v}/
depends_on: [ sign-release ]
# Build a debian package and push it to our bucket
- name: build-deb
image: kolaente/fpm
pull: true
commands:
- make build-deb
depends_on: [ static-build-linux ]
- name: deb-structure
image: kolaente/reprepro
pull: true
environment:
GPG_PRIVATE_KEY:
from_secret: gpg_privatekey
commands:
- export GPG_TTY=$(tty)
- gpg -qk
- echo "use-agent" >> ~/.gnupg/gpg.conf
- gpgconf --kill gpg-agent
- echo $GPG_PRIVATE_KEY > ~/frederik.gpg
- gpg --import ~/frederik.gpg
- mkdir debian/conf -p
- cp build/reprepro-dist-conf debian/conf/distributions
- make reprepro
depends_on: [ build-deb ]
# Push the releases to our pseudo-s3-bucket
- name: release-deb
image: plugins/s3:1
pull: true
settings:
bucket: vikunja
access_key:
from_secret: aws_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://storage.kolaente.de
path_style: true
strip_prefix: debian
source: debian/*/*/*/*/*
target: /deb/
depends_on: [ deb-structure ]
# Build the docker image and push it to docker hub
- name: docker
image: plugins/docker
pull: true
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: vikunja/api
auto_tag: true
depends_on: [ fetch-tags ]
- name: telegram
image: appleboy/drone-telegram
depends_on:
- docker
- release-version
settings:
token:
from_secret: TELEGRAM_TOKEN
to:
from_secret: TELEGRAM_TO
message: >
{{repo.owner}}/{{repo.name}}: \[{{build.status}}] Build {{build.number}}
{{commit.author}} pushed to {{commit.branch}} {{commit.sha}}: `{{commit.message}}`
Build started at {{datetime build.started "2006-Jan-02T15:04:05Z" "GMT+2"}} finished at {{datetime build.finished "2006-Jan-02T15:04:05Z" "GMT+2"}}.
when:
status:
- success
- failure
---
kind: pipeline
name: deploy-docs
workspace:
base: /go
path: src/code.vikunja.io/api
clone:
depth: 50
trigger:
event:
- push
branch:
- master
steps:
- name: submodules
image: docker:git
commands:
- git submodule update --init
- git submodule update --recursive --remote
- name: theme
image: kolaente/yarn
pull: true
group: build-static
commands:
- cd docs/themes/vikunja
- yarn --production=false
- ./node_modules/.bin/gulp
- name: build
image: monachus/hugo:v0.54.0
pull: true
commands:
- cd docs
- hugo
- mv public/docs/* public # Hugo seems to be not capable of setting a different theme for a home page, so we do this ugly hack to fix it.
- name: docker
image: plugins/docker
pull: true
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: vikunja/docs
context: docs/
dockerfile: docs/Dockerfile
+12
View File
@@ -0,0 +1,12 @@
# Description
# Checklist
* [ ] I added or improved tests
* [ ] I pushed new or updated dependencies to the repo using `go mod vendor`
* [ ] I added or improved docs for my feature
* [ ] Swagger (including `make do-the-swag`)
* [ ] Error codes
* [ ] New config options
+20 -4
View File
@@ -1,6 +1,22 @@
node_modules/
.idea/
frontend/
.idea/*/*
.idea/httpRequests
config.yml
config.yaml
!docs/config.yml
*.db
Run
dist/
*.zip
*.tgz
cover.*
/vikunja
Test_*
bin/
secrets
*.deb
debian/
logs/
docs/public/
docs/resources/
pkg/static/templates_vfsdata.go
files/
!pkg/files/
+3
View File
@@ -0,0 +1,3 @@
[submodule "docs/themes/vikunja"]
path = docs/themes/vikunja
url = ../theme.git
+349 -242
View File
@@ -5,273 +5,380 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
All releases can be found on https://code.vikunja.io/desktop/releases.
All releases can be found on https://code.vikunja.io/api/releases.
The releases aim at the api and frontend versions which is why there are missing versions.
## [0.13] - 2020-05-12
## [0.21.0] - 2023-07-07
#### Added
### Dependencies
* Add 2fa for authentification (#383)
* Add categories to error docs
* Add changing email for users
* Add community link
* Add configuration options for log level
* Add creating a new first bucket when creating a new list
* Add docs for changing frontend url
* Add endpoint to disable totp auth
* Add endpoint to get the current users totp status
* Add explanation to docs about cors
* Add github token for renovate (#164)
* Add gosec static analysis
* Add moving tasks between lists (#389)
* Add real buckets for tasks which don't have one (#446)
* Add traefik 2 example configuration
* Configure Renovate (#159)
* Kanban (#393)
* Task filters (#243)
* Task Position (#412)
* *(deps)* Update dependency electron to v22.1.0 (#134)
* *(deps)* Update dependency electron to v22.2.0 (#135)
* *(deps)* Update dependency electron to v23 (#136)
* *(deps)* Update dependency electron to v23.1.0 (#138)
* *(deps)* Update dependency electron to v23.1.1 (#139)
* *(deps)* Update dependency electron to v23.1.2 (#140)
* *(deps)* Update dependency electron to v23.1.3 (#141)
* *(deps)* Update dependency electron to v23.1.4 (#142)
* *(deps)* Update dependency electron to v23.2.0 (#143)
* *(deps)* Update dependency express to v4.18.2 (#144)
* *(deps)* Update dependency electron to v23.2.1 (#145)
* *(deps)* Update dependency electron to v23.2.2 (#146)
* *(deps)* Update dependency electron to v24 (#147)
* *(deps)* Update dependency electron to v24.1.1 (#148)
* *(deps)* Update dependency electron to v24.1.2 (#149)
* *(deps)* Update dependency electron to v24.1.3 (#150)
* *(deps)* Update dependency electron to v24.3.1 (#151)
* *(deps)* Update dependency electron to v24.4.0 (#152)
* *(deps)* Update dependency electron to v25 (#153)
* *(deps)* Update dependency electron to v25.0.1 (#155)
* *(deps)* Update dependency electron to v25.1.0 (#156)
* *(deps)* Update dependency electron to v25.1.1 (#158)
* *(deps)* Update dependency electron to v25.2.0 (#159)
* *(deps)* Update dependency electron-builder to v24 (#157)
* *(deps)* Update dependency connect-history-api-fallback to v2 (#103)
#### Fixed
### Miscellaneous Tasks
* Add checking and logging when trying to put a task into a nonexisting bucket
* Fix bucket ID being reset with no need to do so
* Fix creating new things with a link share auth
* Fix dependencies
* Fix gosec in drone
* Fix link share creation & creating admin link shares without admin rights
* Fix moving tasks back into the empty (ID: 0) bucket
* Fix moving tasks in buckets
* Fix not moving its bucket when moving a task between lists
* Fix pagination count for task collection
* Fix parsing array style comparators by query param
* Fix reference to reverse proxies in docs
* Fix removing the last bucket
* Fix replace statements for tail
* Fix team rights not updating for namespace rights
* Fix tests after renaming json fields to snake_case
* Fix total label count when getting all labels (#477)
* Remove setting task bucket to 0
* Task Filter Fixes (#495)
* Remove sponsor ([c02c5d0](c02c5d009ffcef7984c2feebf7df4f25444b24e1))
#### Changed
## [0.20.3] - 2023-01-24
* Change all json fields to snake_case
* Change totp secret datatype from varchar to text
* Update alpine Docker tag to v3.11 (#160)
* Update docs theme
* Update github.com/c2h5oh/datasize commit hash to 28bbd47 (#212)
* Update github.com/gordonklaus/ineffassign commit hash to 7953dde (#233)
* Update github.com/jgautheron/goconst commit hash to cda7ea3 (#228)
* Update github.com/shurcooL/httpfs commit hash to 8d4bc4b (#229)
* Update golang.org/x/crypto commit hash to 056763e (#222)
* Update golang.org/x/crypto commit hash to 06a226f (#504)
* Update golang.org/x/crypto commit hash to 0848c95 (#371)
* Update golang.org/x/crypto commit hash to 3c4aac8 (#419)
* Update golang.org/x/crypto commit hash to 44a6062 (#429)
* Update golang.org/x/crypto commit hash to 4b2356b (#475)
* Update golang.org/x/crypto commit hash to 4bdfaf4 (#438)
* Update golang.org/x/crypto commit hash to 729f1e8 (#458)
* Update golang.org/x/crypto commit hash to a76a400 (#411)
* Update golang.org/x/lint commit hash to 738671d (#223)
* Update module go-redis/redis to v6.15.7 (#234)
* Update module go-redis/redis to v6.15.7 (#290)
* Update module go-redis/redis to v7 (#277)
* Update module go-redis/redis to v7 (#309)
* Update module go-testfixtures/testfixtures/v3 to v3.1.2 (#457)
* Update module go-testfixtures/testfixtures/v3 to v3.2.0 (#505)
* Update module imdario/mergo to v0.3.9 (#238)
* Update module labstack/echo/v4 to v4.1.16 (#241)
* Update module lib/pq to v1.4.0 (#428)
* Update module lib/pq to v1.5.0 (#476)
* Update module lib/pq to v1.5.1 (#485)
* Update module lib/pq to v1.5.2 (#491)
* Update module olekukonko/tablewriter to v0.0.4 (#240)
* Update module prometheus/client_golang to v0.9.4 (#245)
* Update module prometheus/client_golang to v1
* Update module prometheus/client_golang to v1.6.0 (#463)
* Update module spf13/cobra to v0.0.7 (#271)
* Update module spf13/viper to v1.6.2 (#272)
* Update module spf13/viper to v1.6.3 (#291)
* Update module spf13/viper to v1.7.0 (#494)
* Update module stretchr/testify to v1.5.1 (#274)
* Update Renovate Configuration (#161)
* Update src.techknowlogick.com/xgo commit hash to bb0faa3 (#279)
* Update src.techknowlogick.com/xgo commit hash to c43d4c4 (#224)
* Update xorm redis cacher to use the xorm logger instead of a special seperate one
* Update xorm to v1 (#323)
### Bug Fixes
## [0.12] - 2020-04-04
* Open links in OS default browser ([9915318](99153187d77d5b2311bc2a87864f70b9d2563370))
#### Added
### Dependencies
* Add support for archiving lists and namespaces (#152)
* Colors for lists and namespaces (#155)
* Add build time to compile flags
* Add proxying gravatar requests for user avatars (#148)
* Add empty avatar provider (#149)
* expand relative path ~/.config/vikunja to $HOME/.config/vikunja **WINDOWS** (#147)
* Show lists as archived if their namespace is archived
* *(deps)* Update dependency electron to v22.0.1 (#131)
* *(deps)* Update dependency electron to v22.0.2 (#132)
* *(deps)* Update dependency electron to v22.0.3 (#133)
#### Fixed
## [0.20.2] - 2022-12-18
* Workaround for timezones on windows (#151)
* Fix getting one namespace
* Fix getting the authenticated user with caldav
* Fix searching for config in home directories
* Fix updating lists with an identifier
### Dependencies
#### Changed
* *(deps)* Update dependency electron to v21.3.1 (#128)
* *(deps)* Update dependency electron to v22 (#129)
* Change release bucket
## [0.20.1] - 2022-11-11
### Dependencies
* *(deps)* Update dependency electron to v21.2.1 (#125)
* *(deps)* Update dependency electron to v21.2.2 (#126)
## [0.20.0] - 2022-10-28
### Dependencies
* *(deps)* Update dependency electron to v21.1.0 (#120)
* *(deps)* Update dependency electron-builder to v23.6.0 (#122)
* *(deps)* Update dependency electron to v21.1.1 (#123)
* *(deps)* Update dependency electron to v21.2.0 (#124)
## [0.19.1 - 2022-08-17]
### Dependencies
* *(deps)* Update dependency electron to v20.0.2 (#111)
* *(deps)* Update dependency electron to v20.0.3 (#112)
* *(deps)* Update dependency electron to v20.1.1 (#113)
* *(deps)* Update dependency electron to v20.1.2 (#114)
* *(deps)* Update dependency electron to v20.1.3 (#115)
* *(deps)* Update dependency electron to v20.1.4 (#116)
* *(deps)* Update dependency electron to v20.2.0 (#117)
* *(deps)* Update dependency electron to v21 (#118)
* *(deps)* Update dependency electron to v21.0.1 (#119)
### Features
* Add sponsor to readme (relm) ([5b4d5c7](5b4d5c784b4ea447ea928c8c9ee83a58b51f10f4))
### Miscellaneous Tasks
* Disable mac builds ([0563fb2](0563fb2ee5ae16357cdd9463be33ca3f3977c596))
## [0.19.0 - 2022-08-03]
### Dependencies
* *(deps)* Update dependency electron-builder to v22.13.1 (#61)
* *(deps)* Update dependency electron to v15.2.0 (#60)
* *(deps)* Update dependency electron to v15.3.0 (#63)
* *(deps)* Update dependency electron to v15.3.1 (#64)
* *(deps)* Update dependency electron to v15.3.2 (#66)
* *(deps)* Update dependency electron to v16 (#65)
* *(deps)* Update dependency electron to v16.0.1 (#67)
* *(deps)* Update dependency electron-builder to v22.14.5 (#68)
* *(deps)* Update dependency electron to v16.0.2 (#69)
* *(deps)* Update dependency electron to v16.0.3 (#71)
* *(deps)* Update dependency electron to v16.0.4 (#72)
* *(deps)* Update dependency electron to v16.0.5 (#73)
* *(deps)* Update dependency electron to v16.0.6 (#74)
* *(deps)* Update dependency electron to v16.0.7 (#75)
* *(deps)* Update dependency electron to v16.0.8 (#76)
* *(deps)* Update dependency electron to v17 (#77)
* *(deps)* Update dependency electron-builder to v22.14.13 (#78)
* *(deps)* Update dependency electron to v17.0.1 (#79)
* *(deps)* Update dependency electron to v17.1.0 (#80)
* *(deps)* Update dependency electron to v17.1.1 (#81)
* *(deps)* Update dependency electron to v17.1.2 (#82)
* *(deps)* Update dependency electron to v17.2.0 (#83)
* *(deps)* Update dependency electron to v17.3.0 (#84)
* *(deps)* Update dependency electron to v18 (#85)
* *(deps)* Update dependency electron to v18.0.1 (#86)
* *(deps)* Update dependency electron to v18.0.2 (#87)
* *(deps)* Update dependency electron to v18.0.3 (#88)
* *(deps)* Update dependency electron-builder to v23 (#89)
* *(deps)* Update dependency electron to v18.0.4 (#90)
* *(deps)* Update dependency electron to v18.1.0 (#91)
* *(deps)* Update dependency electron to v18.2.0 (#92)
* *(deps)* Update dependency electron to v18.2.2 (#93)
* *(deps)* Update dependency electron to v18.2.3 (#94)
* *(deps)* Update dependency electron to v18.2.4 (#95)
* *(deps)* Update dependency electron to v18.3.1 (#96)
* *(deps)* Update dependency electron to v19 (#97)
* *(deps)* Update dependency electron to v19.0.2 (#98)
* *(deps)* Update dependency electron to v19.0.3 (#99)
* *(deps)* Update dependency electron to v19.0.4 (#100)
* *(deps)* Update dependency electron to v19.0.6 (#101)
* *(deps)* Update dependency electron-builder to v23.1.0 (#102)
* *(deps)* Update dependency electron to v19.0.7 (#104)
* *(deps)* Update dependency electron to v19.0.8 (#105)
* *(deps)* Update dependency electron to v19.0.9 (#106)
* *(deps)* Update dependency electron to v19.0.10 (#107)
* *(deps)* Update dependency electron-builder to v23.3.3 (#108)
* *(deps)* Update dependency electron to v20 (#109)
* *(deps)* Update dependency electron to v20.0.1 (#110)
### Miscellaneous Tasks
* *(ci)* Use latest s3 plugin
* *(ci)* Sign drone config
### Other
* *(other)* Update dependency electron to v14.0.1 (#58)
* *(other)* Update dependency electron to v15 (#59)
## [0.18.0 - 2021-09-05]
## [0.11] - 2020-03-01
### Added
* Add drone pipeline for PR
* Enable mac builds
### Changed
* Cleanup
* Fix sed for macos
* Install yarn on mac
* Only upload .dmg files for macos builds
* Sign drone config
### Dependency Updates
* Update dependency electron-builder to v22.11.7 (#45)
* Update dependency electron to v13.0.1 (#41)
* Update dependency electron to v13.1.0 (#42)
* Update dependency electron to v13.1.1 (#43)
* Update dependency electron to v13.1.2 (#44)
* Update dependency electron to v13.1.3 (#46)
* Update dependency electron to v13.1.4 (#47)
* Update dependency electron to v13.1.5 (#48)
* Update dependency electron to v13.1.6 (#49)
* Update dependency electron to v13.1.7 (#50)
* Update dependency electron to v13.1.8 (#51)
* Update dependency electron to v13.1.9 (#52)
* Update dependency electron to v13.2.0 (#53)
* Update dependency electron to v13.2.1 (#54)
* Update dependency electron to v13.2.2 (#55)
* Update dependency electron to v13.2.3 (#56)
* Update dependency electron to v13 (#39)
* Update dependency electron to v14 (#57)
## [0.17.0 - 2021-05-20]
For a list of changes in this release, see [the frontend changelog](https://kolaente.dev/vikunja/frontend/releases/tag/v0.17.0).
### Added
* Add darwin release pipeline
* Add pipeline type
### Changed
* Change release target path for unstable releases
* Change version to download to unstable
* Disable the mac builds for now
* Move release steps in one pipeline step for macos
* Switch main branch to main
* Switch to wine-mono for building
* Add config options for cors handling (#124)
* Add config options for task attachments (#125)
* Add generate as a make dependency for make build
* Add logging for invalid model errors (#126)
* Add more logging to web handler methods
* Add postgres support (#135)
* Add rate limit by ip for non-authenticated routes (#127)
* Better efficency for loading teams (#128)
* Expand relative path ~/.config/vikunja to $HOME/.config/vikunja (#146)
* Task Comments (#138)
### Fixed
* Fix missing application icon on Linux. (#19)
* Fix version in package.json
### Dependency Updates
* Update dependency electron-builder to v22.10.5 (#23)
* Update dependency electron-builder to v22.11.1 (#31)
* Update dependency electron-builder to v22.11.2 (#33)
* Update dependency electron-builder to v22.11.3 (#34)
* Update dependency electron-builder to v22.11.4 (#35)
* Update dependency electron-builder to v22.11.5 (#37)
* Update dependency electron to v11.2.0 (#12)
* Update dependency electron to v11.2.1 (#14)
* Update dependency electron to v11.2.2 (#20)
* Update dependency electron to v11.2.3 (#21)
* Update dependency electron to v11.3.0 (#22)
* Update dependency electron to v12.0.1 (#25)
* Update dependency electron to v12.0.2 (#26)
* Update dependency electron to v12.0.3 (#27)
* Update dependency electron to v12.0.4 (#28)
* Update dependency electron to v12.0.5 (#29)
* Update dependency electron to v12.0.6 (#30)
* Update dependency electron to v12.0.7 (#32)
* Update dependency electron to v12.0.8 (#36)
* Update dependency electron to v12.0.9 (#38)
* Update dependency electron to v12 (#24)
## [0.16.0 - 2021-01-10]
For a list of changes in this release, see [the frontend changelog](https://kolaente.dev/vikunja/frontend/releases/tag/v0.16.0).
### Added
* Add yarn cache to drone
* Configure Renovate (#1)
* Fix typo in docker-compose example (#140)
* Fix frontend url for wunderlist migration in docs
* Fix inserting task structure with related tasks (#142)
* Fix time zone settings not working in Docker
* Fix updating dates when marking a task as done (#145)
* Make sure the author is returned when creating a new comment
* Remove double user field
### Changed
* Change license to GPLv3
* Pin dependencies (#2)
* Update dependency electron to v10.1.5 (#3)
* Update dependency electron to v11.0.1 (#5)
* Update dependency electron to v11.0.2 (#6)
* Update dependency electron to v11.0.3 (#7)
* Update dependency electron to v11.0.4 (#8)
* Update dependency electron to v11.1.0 (#9)
* Update dependency electron to v11.1.1 (#10)
* Update dependency electron to v11 (#4)
* Explicitly disable wunderlist migration by default (#141)
* Migration Improvements (#122)
* Refactor User and DB handling (#123)
* Return iso dates for everything date related from the api (#130)
* Update copyright header
* Update theme
* Update xorm to use the new import path (#133)
* Use relative url in .gitmodules (#132)
## [0.15.0 - 2020-10-19]
## [0.10] - 2020-01-19
First initial release.
### Added
For a list of changes in this release, see [the frontend changelog](https://kolaente.dev/vikunja/frontend/releases/tag/v0.15.0).
* Migration (#120)
* Endpoint to get tasks on a list (#108)
* Sort Order for tasks (#110)
* Add files volume to docker compose docs
* Add motd config option to docs
* Add option to disable registration (#117)
* Add task identifier (#115)
* Add tests for md5 generation (#111)
* Add user token renew (#113)
### Fixed
* Fix new tasks not getting a new task index (#116)
* Fix owner field being null for user shared namespaces (#119)
* Fix passing sort_by and order_by as query path arrays
* Fix sorting tasks by bool values
* Fix task collection tests
* Consistent copyright text in file headers (#112)
### Changed
* Task collection improvements (#109)
* Update copyright year (#118)
* Update docs with a traefik configuration
* Use redis INCRBY and DECRBY when updating metrics values (#121)
* Use utf8mb4 instead of plain utf8 (#114)
* Update docs theme
## [0.9] - 2019-11-24
### Added
* Task Attachments (#104)
* Task Relations (#103)
* Add endpoint to get a single task (#106)
* Add file volume to the docker image
* Added extra depth to logging to correctly show the functions calling the logger in logs
* Added more infos to a link share auth (#98)
* Added percent done to tasks (#102)
### Fixed
* Fix default logging settings (#107)
* Fixed a bug where adding assignees or reminders via an update would re-create them and not respect already inserted ones, leaving a lot of garbage
* Fixed a bug where deleting an attachment would cause a nil panic
* Fixed building docs theme
* Fixed error when setting max file size on 32-Bit systems
* Fixed labels being displayed multiple times if they were associated with more than one task (#99)
* Fixed metrics on/off setting
* Fixed migration for task relations
* Fixed not getting all labels when retrieving a list with all tasks
* Fixed panic when using link share and metrics
* Fixed rate limit panic when authenticating with a link share auth token (#97)
* Fixed removing reminders
* Small link share fixes (#96)
### Changed
* Improve pagination (#105)
* Moved `teams_{namespace|list}_*` to `{namespace|list}_teams_*` for better consistency (#101)
* Refactored getting all lists for a namespace (#100)
* Refactored getting task IDs for labels
* Switched default logger to stdout instead of stderr
* update docs theme
### Misc
* Move from markdown lists to Vikunja for roadmap
## [0.8] - 2019-09-01
### Added
* Better Caldav support (#73)
* Added settings for max open/idle connections and max connection lifetime (#74)
* /info endpoint (#85)
* Added http endpoint to list all users on a list (#87)
* Rate limits (#91)
* Sharing of lists via public links (#94)
### Changed
* Reminders now use an extra table (#75)
* Use the username instead of a full user object when adding a user to a team or giving it rights (#76)
* Add the md5-hashed user email to user objects for use with gravatar (#78)
* Use the auth methods to get IDs to avoid unneeded casts
* Better config handling with constants (#83)
* Statically compile templates in the final binary (#84)
* Use longtext instead of varchar(1000) on description fields (#88)
* Logger refactoring (#90)
### Fixed
* Fixed `listID` not being returned in tasks
* Fixed tests (#72)
* Fixed metrics endpoint not working
* Fixed check if the user really exists before updating/deleting its rights (#77)
* Fixed duedate spelling issue (#79)
### Misc
* Integration tests (#71)
* Make sure the version works when building in drone
* Switched to another version of xgo
* Simplified the docker image (#80)
* Update echo (#82)
* Compress binaries after building them (#81)
* Simplify structure by having less files (#86)
* Limit the test pipeline to run only on pull requests (#89)
* GetUser now returns a pointer (#93)
* Refactor ListTask to Task (#92)
## [0.7] - 2019-04-05
### Added
* DB migrations (#67)
* More cli options for Vikunja (#66 #68)
* Use query params to sort tasks instead of url params (#61)
* More config paths (#55)
### Fixed
* Fixed Priority not updating when setting it to 0
* Fixed getting lists by namespace
* Fixed rights check (#70 #62)
* Fixed labels not being queried correctly on tasks
* Fixed bulk update label tasks
### Changed
* Hide a user's email address everywhere (#69)
* Refactored `canRead()` to get the list before checking rights #65
* Let rights methods return errors (#64 #63)
* Improved Swagger docs for label tasks
* Docs improvements (#58)
* Logging Handling (#57)
* Rights performance improvements (#54)
### Misc
* Releases also as Debian packages (#56)
## [0.6] - 2019-01-16
### Added
* Added prometheus endpoint to get metrics (#33)
* More unit tests (#34)
* Tests can now use config files (#36)
* Redoc for swagger ui (#39, #46)
* Start and end dates for tasks (#40)
* Get tasks between a date range (#41)
* Bulk edit for tasks (#42)
* More ci checks (#43)
* Task assignees (#44, #47)
* Task labels (#45, #48)
### Fixed
* Fixed path to get all tasks (echo bug)
* Explicitly get the peudonamespace with all shared lists (#32)
* Properly init tabels Redis
* unexpected EOF when using metrics (#35)
* Task sorting in lists (#36)
* Various user fixes (#38)
* Fixed a bug where updating a list would update it with the same values it had
### Changed
* Simplified list rights check (#50)
* Refactored some structs to not expose unneded values via json (#52)
### Misc
* Updated libraries
* Updated drone to version 1
* Releases are now signed with our pgp key (more info about this on [the download page](https://vikunja.io/en/download/)).
## [0.5] - 2018-12-02
### Added
* Shared lists are now shown in a pseudonamespace with all other namespaces, has the ID -1
* Tasks can have multiple reminders
* Tasks can have subtasks. Subtasks are fully-fleged tasks, but not shown in the task list of a list.
* Tasks can have priorities
### Changed
* Validation not so verbose anymore
* [License](https://git.kolaente.de/vikunja/api/src/branch/master/LICENSE) is now GPLv3
* The crudhandler now has its [own repo](https://git.kolaente.de/vikunja/web) - you can use it in your own projects!
## [0.4] - 2018-11-16
#### Added
* Get all tasks for the authenticated user sorted by their due date
* CalDAV support
* Pagination for everything which returns an array
* Search all the things
* More validation for most of the structs
* Improved Swagger docs (available on `/api/v1/swagger`)
## [0.3] - 2018-11-02
### Added
* Password reset
* Email verification when registering
Misc bugfixes and improvements to the build process
## [0.2] - 2018-10-17
## [0.1] - 2018-09-20
+45
View File
@@ -0,0 +1,45 @@
##############
# Build stage
FROM golang:1-alpine AS build-env
ARG VIKUNJA_VERSION
ENV TAGS "sqlite"
ENV GO111MODULE=on
ENV GOFLAGS=-mod=vendor
# Build deps
RUN apk --no-cache add build-base git
# Setup repo
COPY . ${GOPATH}/src/code.vikunja.io/api
WORKDIR ${GOPATH}/src/code.vikunja.io/api
# Checkout version if set
RUN if [ -n "${VIKUNJA_VERSION}" ]; then git checkout "${VIKUNJA_VERSION}"; fi \
&& make clean generate build
###################
# The actual image
# Note: I wanted to use the scratch image here, but unfortunatly the go-sqlite bindings require cgo and
# because of this, the container would not start when I compiled the image without cgo.
FROM alpine:3.11
LABEL maintainer="maintainers@vikunja.io"
WORKDIR /app/vikunja/
COPY --from=build-env /go/src/code.vikunja.io/api/vikunja .
RUN adduser -S -D vikunja -h /app/vikunja -H \
&& chown vikunja -R /app/vikunja
ENV VIKUNJA_SERVICE_ROOTPATH=/app/vikunja/
# Fix time zone settings not working
RUN apk --no-cache add tzdata
# Files permissions
RUN mkdir /app/vikunja/files && \
chown -R vikunja /app/vikunja/files
VOLUME /app/vikunja/files
USER vikunja
CMD ["/app/vikunja/vikunja"]
EXPOSE 3456
+1 -2
View File
@@ -671,5 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
<https://www.gnu.org/licenses/why-not-lgpl.html>.
+247
View File
@@ -0,0 +1,247 @@
DIST := dist
IMPORT := code.vikunja.io/api
SED_INPLACE := sed -i
ifeq ($(OS), Windows_NT)
EXECUTABLE := vikunja.exe
else
EXECUTABLE := vikunja
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
SED_INPLACE := sed -i ''
endif
endif
GOFILES := $(shell find . -name "*.go" -type f ! -path "./vendor/*" ! -path "*/bindata.go")
GOFMT ?= gofmt -s
GOFLAGS := -v -mod=vendor
EXTRA_GOFLAGS ?=
LDFLAGS := -X "code.vikunja.io/api/pkg/version.Version=$(shell git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')" -X "main.Tags=$(TAGS)" -X "code.vikunja.io/api/pkg/version.BuildTime=$(shell date -R)"
PACKAGES ?= $(filter-out code.vikunja.io/api/pkg/integrations,$(shell go list -mod=vendor ./... | grep -v /vendor/))
SOURCES ?= $(shell find . -name "*.go" -type f)
TAGS ?=
ifeq ($(OS), Windows_NT)
EXECUTABLE := vikunja.exe
else
EXECUTABLE := vikunja
endif
ifneq ($(DRONE_TAG),)
VERSION ?= $(subst v,,$(DRONE_TAG))
else
ifneq ($(DRONE_BRANCH),)
VERSION ?= $(subst release/v,,$(DRONE_BRANCH))
else
VERSION ?= master
endif
endif
ifeq ($(DRONE_WORKSPACE),'')
BINLOCATION := $(EXECUTABLE)
else
BINLOCATION := $(DIST)/binaries/$(EXECUTABLE)-$(VERSION)-linux-amd64
endif
ifeq ($(VERSION),master)
PKGVERSION := $(shell git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')
else
PKGVERSION := $(VERSION)
endif
.PHONY: all
all: build
.PHONY: clean
clean:
go clean ./...
rm -rf $(EXECUTABLE) $(DIST) $(BINDATA)
.PHONY: test
test:
# We run everything sequentially and not in parallel to prevent issues with real test databases
VIKUNJA_SERVICE_ROOTPATH=$(shell pwd) go test $(GOFLAGS) -p 1 -cover -coverprofile cover.out $(PACKAGES)
.PHONY: test-coverage
test-coverage: test
go tool cover -html=cover.out -o cover.html
.PHONY: integration-test
integration-test:
# We run everything sequentially and not in parallel to prevent issues with real test databases
VIKUNJA_SERVICE_ROOTPATH=$(shell pwd) go test $(GOFLAGS) -p 1 code.vikunja.io/api/pkg/integrations
.PHONY: lint
lint:
@hash golint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go install $(GOFLAGS) golang.org/x/lint/golint; \
fi
for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
.PHONY: fmt
fmt:
$(GOFMT) -w $(GOFILES)
.PHONY: fmt-check
fmt-check:
# get all go files and run go fmt on them
@diff=$$($(GOFMT) -d $(GOFILES)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi;
.PHONY: build
build: generate $(EXECUTABLE)
.PHONY: generate
generate:
go generate code.vikunja.io/api/pkg/static
$(EXECUTABLE): $(SOURCES)
go build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
.PHONY: compress-build
compress-build:
upx -9 $(EXECUTABLE)
.PHONY: release
release: release-dirs release-windows release-linux release-darwin release-copy release-check release-os-package release-zip
.PHONY: release-dirs
release-dirs:
mkdir -p $(DIST)/binaries $(DIST)/release $(DIST)/zip
.PHONY: release-windows
release-windows:
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go install $(GOFLAGS) src.techknowlogick.com/xgo; \
fi
xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out vikunja-$(VERSION) .
ifneq ($(DRONE_WORKSPACE),'')
mv /build/* $(DIST)/binaries
endif
.PHONY: release-linux
release-linux:
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go install $(GOFLAGS) src.techknowlogick.com/xgo; \
fi
xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/*' -out vikunja-$(VERSION) .
ifneq ($(DRONE_WORKSPACE),'')
mv /build/* $(DIST)/binaries
endif
.PHONY: release-darwin
release-darwin:
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go install $(GOFLAGS) src.techknowlogick.com/xgo; \
fi
xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out vikunja-$(VERSION) .
ifneq ($(DRONE_WORKSPACE),'')
mv /build/* $(DIST)/binaries
endif
# Compresses all releases made by make release-* but not mips* releases since upx can't handle these.
.PHONY: release-compress
release-compress:
$(foreach file,$(filter-out $(wildcard $(wildcard $(DIST)/binaries/$(EXECUTABLE)-*mips*)),$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*)), upx -9 $(file);)
.PHONY: release-copy
release-copy:
$(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),cp $(file) $(DIST)/release/$(notdir $(file));)
.PHONY: release-check
release-check:
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;)
.PHONY: release-os-package
release-os-package:
$(foreach file,$(filter-out %.sha256,$(wildcard $(DIST)/release/$(EXECUTABLE)-*)),mkdir $(file)-full;mv $(file) $(file)-full/; mv $(file).sha256 $(file)-full/; cp config.yml.sample $(file)-full/config.yml; cp LICENSE $(file)-full/; )
.PHONY: release-zip
release-zip:
$(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),cd $(file); zip -r ../../zip/$(shell basename $(file)).zip *; cd ../../../; )
# Builds a deb package using fpm from a previously created binary (using make build)
.PHONY: build-deb
build-deb:
fpm -s dir -t deb --url https://vikunja.io -n vikunja -v $(PKGVERSION) --license GPLv3 --directories /opt/vikunja --after-install ./build/after-install.sh --description 'Vikunja is an open-source todo application, written in Go. It lets you create lists,tasks and share them via teams or directly between users.' -m maintainers@vikunja.io ./$(BINLOCATION)=/opt/vikunja/vikunja ./config.yml.sample=/etc/vikunja/config.yml;
.PHONY: reprepro
reprepro:
reprepro_expect debian includedeb strech ./$(EXECUTABLE)_$(PKGVERSION)_amd64.deb
.PHONY: got-swag
got-swag: do-the-swag
@diff=$$(git diff docs/swagger/swagger.json); \
if [ -n "$$diff" ]; then \
echo "Please run 'make do-the-swag' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi;
.PHONY: do-the-swag
do-the-swag:
@hash swag > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go install $(GOFLAGS) github.com/swaggo/swag/cmd/swag; \
fi
swag init -g pkg/routes/routes.go -o ./pkg/swagger;
# Fix the generated swagger file, currently a workaround until swaggo can properly use go mod
sed -i '/"definitions": {/a "code.vikunja.io.web.HTTPError": {"type": "object","properties": {"code": {"type": "integer"},"message": {"type": "string"}}},' pkg/swagger/docs.go;
sed -i 's/code.vikunja.io\/web.HTTPError/code.vikunja.io.web.HTTPError/g' pkg/swagger/docs.go;
sed -i 's/package\ docs/package\ swagger/g' pkg/swagger/docs.go;
sed -i 's/` + \\"`\\" + `/` + "`" + `/g' pkg/swagger/docs.go;
.PHONY: misspell-check
misspell-check:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go install $(GOFLAGS) github.com/client9/misspell/cmd/misspell; \
fi
for S in $(GOFILES); do misspell -error $$S || exit 1; done;
.PHONY: ineffassign-check
ineffassign-check:
@hash ineffassign > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go install $(GOFLAGS) github.com/gordonklaus/ineffassign; \
fi
for S in $(GOFILES); do ineffassign $$S || exit 1; done;
.PHONY: gocyclo-check
gocyclo-check:
@hash gocyclo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go get -u github.com/fzipp/gocyclo; \
go install $(GOFLAGS) github.com/fzipp/gocyclo; \
fi
for S in $(GOFILES); do gocyclo -over 27 $$S || exit 1; done;
.PHONY: static-check
static-check:
@hash staticcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go get -u honnef.co/go/tools; \
go install $(GOFLAGS) honnef.co/go/tools/cmd/staticcheck; \
fi
staticcheck $(PACKAGES);
.PHONY: gosec-check
gosec-check:
@hash gosec > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
echo "Please manually install gosec by running"; \
echo "curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | bash -s -- -b $GOPATH/bin v2.2.0"; \
exit 1; \
fi
gosec ./...
.PHONY: goconst-check
goconst-check:
@hash goconst > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go get -u github.com/jgautheron/goconst/cmd/goconst; \
go install $(GOFLAGS) github.com/jgautheron/goconst/cmd/goconst; \
fi;
for S in $(PACKAGES); do goconst $$S || exit 1; done;
+71 -18
View File
@@ -1,27 +1,80 @@
# Vikunja desktop
<img src="https://vikunja.io/images/vikunja-logo.svg" alt="" style="display: block;width: 50%;margin: 0 auto;" width="50%"/>
[![Build Status](https://drone.kolaente.de/api/badges/vikunja/desktop/status.svg)](https://drone.kolaente.de/vikunja/desktop)
[![Build Status](https://drone1.kolaente.de/api/badges/vikunja/api/status.svg)](https://drone1.kolaente.de/vikunja/api)
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](LICENSE)
[![Download](https://img.shields.io/badge/download-v0.21.0-brightgreen.svg)](https://dl.vikunja.io)
[![Download](https://img.shields.io/badge/download-v0.13-brightgreen.svg)](https://dl.vikunja.io)
[![Docker Pulls](https://img.shields.io/docker/pulls/vikunja/api.svg)](https://hub.docker.com/r/vikunja/api/)
[![Swagger Docs](https://img.shields.io/badge/swagger-docs-brightgreen.svg)](https://try.vikunja.io/api/v1/docs)
[![Go Report Card](https://goreportcard.com/badge/git.kolaente.de/vikunja/api)](https://goreportcard.com/report/git.kolaente.de/vikunja/api)
The Vikunja frontend all repackaged as an electron app to run as a desktop app!
# Vikunja API
## Dev
> The Todo-app to organize your life.
As this repo does not contain any code, only a thin wrapper around electron, you will need to do this to get the
actual frontend bundle and build the app:
# Table of contents
```bash
rm -rf frontend vikunja-frontend-master.zip
wget https://dl.vikunja.io/frontend/vikunja-frontend-master.zip
unzip vikunja-frontend-master.zip -d frontend
sed -i 's/\/api\/v1//g' frontend/index.html # Make sure to trigger the "enter the Vikunja url" prompt
```
* [Features](#features)
* [Docs](#docs)
* [Roadmap](#roadmap)
* [Contributing](#contributing)
* [License](#license)
## Building for release
## Features
1. Run the snippet from above, but with a valid frontend version instead of `master`
2. Change the version in `package.json` (That's the one that will be used by electron-builder`
3. `yarn install`
4. `yarn dist --linux --windows`
* Create TODO lists with tasks
* Reminder for tasks
* Namespaces: A "group" which bundels multiple lists
* Share lists and namespaces with teams and users with granular permissions
* Plenty of details for tasks
See [the features page](https://vikunja.io/en/features/) on our website for a more exaustive list or
try it on [try.vikunja.io](https://try.vikunja.io)!
## Docs
* [Installing](https://vikunja.io/docs/installing/)
* [Build from source](https://vikunja.io/docs/build-from-sources/)
* [Development setup](https://vikunja.io/docs/development/)
* [Makefile](https://vikunja.io/docs/makefile/)
* [Testing](https://vikunja.io/docs/testing/)
All docs can be found on [the vikunja home page](https://vikunja.io/docs/).
### Roadmap
> I know, it's still a long way to go. I'm currently working on a lot of "basic" features, the exiting things will come later. Don't worry, they'll come.
* [x] Prioritize tasks
* [x] Subtasks
* [x] Repeating tasks
* [x] Get tasks via caldav
* [x] Get all your tasks for an interval (day/month/period)
* [x] Labels for tasks
* [x] Assign users to tasks
* [x] Attachments on tasks
* [x] More sharing features
* [x] Share with individual users
* [x] Share via a world-readable link with or without password, like Nextcloud
* [x] Disable registration, making an instance "invite-only"
* [ ] SSE to notify multiple clients of updates when something was changed
* [ ] "Smart Lists" - Create lists based on filters
* [ ] IMAP-Integration - Send an email to Vikunja to create a new task
* [ ] Webhooks - Trigger other events when an action is done (like completing a task)
* [ ] Performace statistics - Get an overview and beautiful charts about what you got done this month
* [ ] Activity feeds - Get a quick overview about who did what
* [ ] Bulk-edit multiple tasks at once
* [ ] Team-efforts - Requiring a task to be marked as done by multiple members until it's done
* [ ] Global limits for namespaces/lists/tasks
See [our roadmap](https://my.vikunja.cloud/share/QFyzYEmEYfSyQfTOmIRSwLUpkFjboaBqQCnaPmWd/auth) (hosted on Vikunja!) for even more!
* [ ] [Mobile apps](https://code.vikunja.io/app) (seperate repo) *In Progress*
* [ ] [Webapp](https://code.vikunja.io/frontend) (seperate repo) *In Progress*
## Contributing
Fork -> Push -> Pull-Request. Also see the [dev docs](https://vikunja.io/docs/development/) for more infos.
## License
This project is licensed under the GPLv3 License. See the [LICENSE](LICENSE) file for the full license text.
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
curl -X POST http://localhost:3456/api/v1/register -H 'Content-Type: application/json' -d '{"username":"demo","password":"demo","email":"demo@vikunja.io"}'
BEARER=`curl -X POST -H 'Content-Type: application/json' -d '{"username": "demo", "password":"demo"}' localhost:3456/api/v1/login | jq -r '.token'`
echo "Bearer: $BEARER"
curl -X POST localhost:3456/api/v1/tokenTest -H "Authorization: Bearer $BEARER"
curl -X PUT localhost:3456/api/v1/namespaces/1/lists -H 'Content-Type: application/json' -H "Authorization: Bearer $BEARER" -d '{"title":"lorem"}'
curl -X PUT localhost:3456/api/v1/lists/1 -H 'Content-Type: application/json' -H "Authorization: Bearer $BEARER" -d '{"text":"lorem"}'
curl -X PUT -H "Authorization: Bearer $BEARER" localhost:3456/api/v1/tasks/1/attachments -F 'files=@/home/konrad/Pictures/Wallpaper/greg-rakozy-_Q4mepyyjMw-unsplash.jpg'
+29
View File
@@ -0,0 +1,29 @@
### Authorization by token, part 1. Retrieve and save token.
POST http://localhost:8080/api/v1/login
Content-Type: application/json
{
"username": "user3",
"password": "1234"
}
> {% client.global.set("auth_token", response.body.token); %}
### Register
POST http://localhost:8080/api/v1/register
Content-Type: application/json
{
"username": "user",
"password": "1234",
"email": "5@knt.li"
}
###
# Token test
POST http://localhost:8080/api/v1/tokenTest
Authorization: Bearer {{auth_token}}
Content-Type: application/json
###
+70
View File
@@ -0,0 +1,70 @@
# Get all labels
GET http://localhost:8080/api/v1/labels
Authorization: Bearer {{auth_token}}
###
# Add a new label
PUT http://localhost:8080/api/v1/labels
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"title": "test5"
}
###
# Delete a label
DELETE http://localhost:8080/api/v1/labels/6
Authorization: Bearer {{auth_token}}
###
# Update a label
POST http://localhost:8080/api/v1/labels/1
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"title": "testschinkenbrot",
"description": "käsebrot"
}
###
# Get one label
GET http://localhost:8080/api/v1/labels/1
Authorization: Bearer {{auth_token}}
###
# Get all labels on a task
GET http://localhost:8080/api/v1/tasks/3565/labels
Authorization: Bearer {{auth_token}}
###
# Add a new label to a task
PUT http://localhost:8080/api/v1/tasks/35236365/labels
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"label_id": 1
}
###
# Delete a label from a task
DELETE http://localhost:8080/api/v1/tasks/3565/labels/1
Authorization: Bearer {{auth_token}}
###
# Add a new label to a task
POST http://localhost:8080/api/v1/tasks/3565/labels/bulk
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"labels": [
{"id": 1},
{"id": 2},
{"id": 3}
]
}
###
+177
View File
@@ -0,0 +1,177 @@
# Get all lists
GET http://localhost:8080/api/v1/namespaces/35/lists
Authorization: Bearer {{auth_token}}
###
# Get one list
GET http://localhost:8080/api/v1/lists/3
Authorization: Bearer {{auth_token}}
###
# Add a new list
PUT http://localhost:8080/api/v1/namespaces/35/lists
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"title": "test"
}
###
# Add a new item
PUT http://localhost:8080/api/v1/lists/1
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"text": "Task",
"description": "Schinken"
}
###
# Delete a task from a list
DELETE http://localhost:8080/api/v1/lists/14
Authorization: Bearer {{auth_token}}
###
# Get all teams who have access to that list
GET http://localhost:8080/api/v1/lists/28/teams
Authorization: Bearer {{auth_token}}
###
# Give a team access to that list
PUT http://localhost:8080/api/v1/lists/1/teams
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{"team_id":2, "right": 1}
###
# Update a teams access to that list
POST http://localhost:8080/api/v1/lists/1/teams/2
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{"right": 0}
###
# 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/28/users
Authorization: Bearer {{auth_token}}
###
# Give a user access to that list
PUT http://localhost:8080/api/v1/lists/3/users
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{"userID":"user4", "right":1}
###
# Update a users access to that list
POST http://localhost:8080/api/v1/lists/30/users/3
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{"right":2}
###
# Delete a user from a list
DELETE http://localhost:8080/api/v1/lists/28/users/3
Authorization: Bearer {{auth_token}}
###
# Get all pending tasks
GET http://localhost:8080/api/v1/tasks/all
Authorization: Bearer {{auth_token}}
###
# Get all pending tasks with priorities
GET http://localhost:8080/api/v1/tasks/all?sort=priorityasc
Authorization: Bearer {{auth_token}}
###
# Get all pending tasks in a range
GET http://localhost:8080/api/v1/tasks/all/dueadateasc/1546784000/1548784000
Authorization: Bearer {{auth_token}}
###
# Get all pending tasks in caldav
GET http://localhost:8080/api/v1/tasks/caldav
#Authorization: Bearer {{auth_token}}
###
# Update a task
POST http://localhost:8080/api/v1/tasks/3565
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"priority": 0
}
###
# Bulk update multiple tasks at once
POST http://localhost:8080/api/v1/tasks/bulk
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"task_ids": [3518,3519,3521],
"text":"bulkupdated"
}
###
# Get all assignees
GET http://localhost:8080/api/v1/tasks/3565/assignees
Authorization: Bearer {{auth_token}}
###
# Add a bunch of assignees
PUT http://localhost:8080/api/v1/tasks/3565/assignees/bulk
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"assignees": [
{"id": 17}
]
}
###
# Get all users who have access to a list
GET http://localhost:8080/api/v1/lists/3/users
Authorization: Bearer {{auth_token}}
###
+71
View File
@@ -0,0 +1,71 @@
# Get all namespaces
GET http://localhost:8080/api/v1/namespaces
Authorization: Bearer {{auth_token}}
###
# Get one namespaces
GET http://localhost:8080/api/v1/namespaces/-1
Authorization: Bearer {{auth_token}}
###
# Get all users who have access to that namespace
GET http://localhost:8080/api/v1/namespaces/12/users
Authorization: Bearer {{auth_token}}
###
# Give a user access to that namespace
PUT http://localhost:8080/api/v1/namespaces/1/users
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{"user_id":3, "right": 0}
###
# Update a users access to that namespace
POST http://localhost:8080/api/v1/namespaces/1/users/3
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{"right": 2}
###
# Delete a user from a namespace
DELETE http://localhost:8080/api/v1/namespaces/1/users/2
Authorization: Bearer {{auth_token}}
###
# Get all teams who have access to that namespace
GET http://localhost:8080/api/v1/namespaces/1/teams
Authorization: Bearer {{auth_token}}
###
# Give a team access to that namespace
PUT http://localhost:8080/api/v1/namespaces/1/teams
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{"team_id":3, "right": 0}
###
# Update a teams access to that namespace
POST http://localhost:8080/api/v1/namespaces/1/teams/1
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{"right": 0}
###
# Delete a team from a namespace
DELETE http://localhost:8080/api/v1/namespaces/1/teams/2
Authorization: Bearer {{auth_token}}
###
+29
View File
@@ -0,0 +1,29 @@
# Get all teams
GET http://localhost:8080/api/v1/teams
Authorization: Bearer {{auth_token}}
###
# Get one team
GET http://localhost:8080/api/v1/teams/28
Authorization: Bearer {{auth_token}}
###
# Add a new member to that team
PUT http://localhost:8080/api/v1/teams/28/members
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"user_id": 2
}
###
# Delete a member from a team
DELETE http://localhost:8080/api/v1/teams/28/members/2
Authorization: Bearer {{auth_token}}
###
+53
View File
@@ -0,0 +1,53 @@
# Get all users
GET http://localhost:8080/api/v1/user
Authorization: Bearer {{auth_token}}
######
# Search for a user
GET http://localhost:8080/api/v1/users?s=3
Authorization: Bearer {{auth_token}}
###
## Update password
POST http://localhost:8080/api/v1/user/password
Authorization: Bearer {{auth_token}}
Content-Type: application/json
{
"old_password": "1234",
"new_password": "1234"
}
### Request a password to reset a password
POST http://localhost:8080/api/v1/user/password/token
Content-Type: application/json
Accept: application/json
{
"email": "k@knt.li"
}
### Request a token to reset a password
POST http://localhost:8080/api/v1/user/password/reset
Content-Type: application/json
Accept: application/json
{
"token": "eAsZzakgqARnjzXHqsHqZtSUKuiOhoJjHANhgTxUIDBSalhbtdpAdLeywGXzVDBuRQGNpHdMxoHXhLVSlzpJsFvuoJgMdkhRhkNhaQXfufuZCdtUlerZHSJQLgYMUryHIxIREcmZLtWoZVrYyARkCvkyFhcGtoCwQOEjAOEZMQQuxTVoGYfAqcfNggQnerUcXCiRIgRtkusXSnltomhaeyRwAbrckXFeXxUjslgplSGqSTOqJTYuhrSzAVTwNvuYyvuXLaZoNnJEyeVDWlRydnxfgUQjQZOKwCBRWVQPKpZhlslLUyUAMsRQkHITkruQCjDnOGCCRsSNplbNCEuDmMfpWYHSQAcQIDZtbQWkxzpfmHDMQvvKPPrxEnrTErlvTfKDKICFYPQxXNpNE",
"new_password": "1234"
}
### Confirm a users email address
POST http://localhost:8080/api/v1/user/confirm
Content-Type: application/json
Accept: application/json
{
"token": ""
}
###
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
ln -s /opt/vikunja/vikunja /usr/bin/vikunja
# Fix the config to contain proper values
NEW_SECRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
sed -i "s/<jwt-secret>/$NEW_SECRET/g" /etc/vikunja/config.yml
sed -i "s/<rootpath>/\/opt\/vikunja\//g" /etc/vikunja/config.yml
sed -i "s/Path: \"\.\/vikunja.db\"/Path: \"\\/opt\/vikunja\/vikunja.db\"/g" /etc/vikunja/config.yml
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

+8
View File
@@ -0,0 +1,8 @@
Origin: dl.vikunja.io
Label: Vikunja
Codename: strech
Architectures: amd64
Components: main
Description: The debian repo for Vikunja builds.
SignWith: yes
Pull: strech
-59
View File
@@ -1,59 +0,0 @@
[changelog]
body = """
{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits
| filter(attribute="scope")
| sort(attribute="scope") %}
* *({{commit.scope}})* {{ commit.message | upper_first }}
{%- if commit.breaking %}
{% raw %} {% endraw %}- **BREAKING**: {{commit.breaking_description}}
{%- endif -%}
{%- endfor -%}
{%- for commit in commits %}
{%- if commit.scope -%}
{% else -%}
* {{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ commit.id }}))
{% if commit.breaking -%}
{% raw %} {% endraw %}- **BREAKING**: {{commit.breaking_description}}
{% endif -%}
{% endif -%}
{% endfor -%}
{% raw %}\n{% endraw %}\
{% endfor %}\n
"""
#{% for group, commits in commits | group_by(attribute="group") %}
# ### {{ group | upper_first }}
# {% for commit in commits %}\
# - {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ commit.id }}))
# {% endfor %}\
#{% endfor %}\n
# remove the leading and trailing whitespace from the template
trim = true
[git]
conventional_commits = true
filter_unconventional = false
commit_parsers = [
{ message = ".*(deps).*", group = "Dependencies"},
{ message = "^feat", group = "Features"},
{ message = "^fix", group = "Bug Fixes"},
{ message = "^doc", group = "Documentation"},
{ message = "^perf", group = "Performance"},
{ message = "^refactor", group = "Refactor"},
{ message = "^style", group = "Styling"},
{ message = "^test", group = "Testing"},
{ message = "^chore\\(release\\): prepare for", skip = true},
{ message = "^chore", group = "Miscellaneous Tasks"},
{ body = ".*security", group = "Security"},
{ message = ".*", group = "Other", default_scope = "other"}, # Everything that's not a conventional commit goes into the "Other" category
]
+166
View File
@@ -0,0 +1,166 @@
service:
# This token is used to verify issued JWT tokens.
# Default is a random token which will be generated at each startup of vikunja.
# (This means all already issued tokens will be invalid once you restart vikunja)
JWTSecret: "<jwt-secret>"
# The interface on which to run the webserver
interface: ":3456"
# The URL of the frontend, used to send password reset emails.
frontendurl: ""
# The base path on the file system where the binary and assets are.
# Vikunja will also look in this path for a config file, so you could provide only this variable to point to a folder
# with a config file which will then be used.
rootpath: <rootpath>
# The max number of items which can be returned per page
maxitemsperpage: 50
# If set to true, enables a /metrics endpoint for prometheus to collect metrics about the system
# You'll need to use redis for this in order to enable common metrics over multiple nodes
enablemetrics: false
# Enable the caldav endpoint, see the docs for more details
enablecaldav: true
# Set the motd message, available from the /info endpoint
motd: ""
# Enable sharing of lists via a link
enablelinksharing: true
# Whether to let new users registering themselves or not
enableregistration: true
# Whether to enable task attachments or not
enabletaskattachments: true
# The time zone all timestamps are in
timezone: GMT
# Whether task comments should be enabled or not
enabletaskcomments: true
database:
# Database type to use. Supported types are mysql, postgres and sqlite.
type: "sqlite"
# Database user which is used to connect to the database.
user: "vikunja"
# Databse password
password: ""
# Databse host
host: "localhost"
# Databse to use
database: "vikunja"
# When using sqlite, this is the path where to store the data
Path: "./vikunja.db"
# Sets the max open connections to the database. Only used when using mysql and postgres.
maxopenconnections: 100
# Sets the maximum number of idle connections to the db.
maxidleconnections: 50
# The maximum lifetime of a single db connection in miliseconds.
maxconnectionlifetime: 10000
# Secure connection mode. Only used with postgres.
# (see https://pkg.go.dev/github.com/lib/pq?tab=doc#hdr-Connection_String_Parameters)
sslmode: disable
cache:
# If cache is enabled or not
enabled: false
# Cache type. Possible values are memory or redis, you'll need to enable redis below when using redis
type: memory
# When using memory this defines the maximum size an element can take
maxelementsize: 1000
redis:
# Whether to enable redis or not
enabled: false
# The host of the redis server including its port.
host: 'localhost:6379'
# The password used to authenicate against the redis server
password: ''
# 0 means default database
db: 0
cors:
# Whether to enable or disable cors headers.
# Note: If you want to put the frontend and the api on seperate domains or ports, you will need to enable this.
# Otherwise the frontend won't be able to make requests to the api through the browser.
enable: true
# A list of origins which may access the api.
origins:
- "*"
# How long (in seconds) the results of a preflight request can be cached.
maxage: 0
mailer:
# Whether to enable the mailer or not. If it is disabled, all users are enabled right away and password reset is not possible.
enabled: false
# SMTP Host
host: ""
# SMTP Host port
port: 587
# SMTP username
username: "user"
# SMTP password
password: ""
# Wether to skip verification of the tls certificate on the server
skiptlsverify: false
# The default from address when sending emails
fromemail: "mail@vikunja"
# The length of the mail queue.
queuelength: 100
# The timeout in seconds after which the current open connection to the mailserver will be closed.
queuetimeout: 30
log:
# A folder where all the logfiles should go.
path: <rootpath>logs
# Whether to show any logging at all or none
enabled: true
# Where the normal log should go. Possible values are stdout, stderr, file or off to disable standard logging.
standard: "stdout"
# Change the log level. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG.
level: "INFO"
# Whether or not to log database queries. Useful for debugging. Possible values are stdout, stderr, file or off to disable database logging.
database: "off"
# The log level for database log messages. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG.
databaselevel: "WARNING"
# Whether to log http requests or not. Possible values are stdout, stderr, file or off to disable http logging.
http: "stdout"
# Echo has its own logging which usually is unnessecary, which is why it is disabled by default. Possible values are stdout, stderr, file or off to disable standard logging.
echo: "off"
ratelimit:
# whether or not to enable the rate limit
enabled: false
# The kind on which rates are based. Can be either "user" for a rate limit per user or "ip" for an ip-based rate limit.
kind: user
# The time period in seconds for the limit
period: 60
# The max number of requests a user is allowed to do in the configured time period
limit: 100
# The store where the limit counter for each user is stored. Possible values are "memory" or "redis"
store: memory
files:
# The path where files are stored
basepath: ./files # relative to the binary
# The maximum size of a file, as a human-readable string.
# Warning: The max size is limited 2^64-1 bytes due to the underlying datatype
maxsize: 20MB
migration:
# These are the settings for the wunderlist migrator
wunderlist:
# Wheter to enable the wunderlist migrator or not
enable: false
# The client id, required for making requests to the wunderlist api
# You need to register your vikunja instance at https://developer.wunderlist.com/apps/new to get this
clientid:
# The client secret, also required for making requests to the wunderlist api
clientsecret:
# The url where clients are redirected after they authorized Vikunja to access their wunderlist stuff.
# This needs to match the url you entered when registering your Vikunja instance at wunderlist.
# This is usually the frontend url where the frontend then makes a request to /migration/wunderlist/migrate
# with the code obtained from the wunderlist api.
# Note that the vikunja frontend expects this to be /migrate/wunderlist
redirecturl:
avatar:
# Switch between avatar providers. Possible values are gravatar and default.
# gravatar will fetch the avatar based on the user email.
# default will return a default avatar for every request.
provider: gravatar
# When using gravatar, this is the duration in seconds until a cached gravatar user avatar expires
gravatarexpiration: 3600
-9
View File
@@ -1,9 +0,0 @@
{ pkgs ? import <nixpkgs> {}
}:
pkgs.mkShell {
name="electron-dev";
buildInputs = [
pkgs.electron
];
}
+3
View File
@@ -0,0 +1,3 @@
FROM nginx
ADD public /usr/share/nginx/html/docs
ADD nginx.conf /etc/nginx/conf.d/default.conf
+42
View File
@@ -0,0 +1,42 @@
baseurl: https://vikunja.io/docs/
title: Vikunja
theme: vikunja
enableRobotsTXT: true
canonifyURLs: true
pygmentsUseClasses: true
permalinks:
post: /:year/:month/:title/
doc: /:slug/
page: /:slug/
default: /:slug/
params:
description: The to-do app to organize your life
author: The Vikunja Authors
website: https://vikunja.io
fanthomEnabled: false
fathomUrl: fathom.kolaente.de
fathomSiteID: RYKSD
menu:
page:
- name: Home
url: https://vikunja.io/en/
weight: 10
- name: Features
url: https://vikunja.io/en/features
weight: 20
- name: Download
url: https://vikunja.io/en/download
weight: 30
- name: Docs
url: https://vikunja.io/docs
weight: 40
- name: Code
url: https://code.vikunja.io/
weight: 50
- name: Community
url: https://community.vikunja.io/
weight: 60
+25
View File
@@ -0,0 +1,25 @@
---
date: "2019-02-12:00:00+02:00"
title: "Docs"
draft: false
url: "/docs"
type: "doc"
weight: 10
---
# Documentation
This is the documentation for Vikunja.
You can find available articles in the menu on the left.
## About
To learn more about the what, why and how, take a look at [the features page](https://vikunja.io/en/features).
## Start
A good starting point if you want to install and host Vikunja on your server are [the install documentation](installing)
and [available configuration options](config-options).
## Developing
If you want to start contributing to Vikunja, take a look at [the development docs](development).
+34
View File
@@ -0,0 +1,34 @@
---
date: "2019-03-31:00:00+01:00"
title: "Adding new cli commands"
draft: false
type: "doc"
menu:
sidebar:
parent: "development"
---
# Adding new cli commands
All cli-related functions are located in `pkg/cmd`.
Each cli command usually calls a function in another package.
For example, the `vikunja migrate` command calls `migration.Migrate()`.
Vikunja uses the amazing [cobra](https://github.com/spf13/cobra) library for its cli.
Please refer to its documentation for informations about how to use flags etc.
To add a new cli command, add something like the following:
{{< highlight golang >}}
func init() {
rootCmd.AddCommand(myCmd)
}
var myCmd = &cobra.Command{
Use: "My-command",
Short: "A short description about your command.",
Run: func(cmd *cobra.Command, args []string) {
// Call other functions
},
}
{{</ highlight >}}
@@ -0,0 +1,71 @@
---
date: "2019-03-29:00:00+02:00"
title: "Database migrations"
draft: false
type: "doc"
menu:
sidebar:
parent: "development"
---
# Database Migrations
Vikunja runs all database migrations automatically on each start if needed.
Additionally, they can also be run directly by using the `migrate` command.
We use [xormigrate](https://github.com/techknowlogick/xormigrate) to handle migrations,
which is based on gormigrate.
## Add a new migration
All migrations are stored in `pkg/migrations` and files should have the same name as their id.
Each migration should have a function to apply and roll it back, as well as a numeric id (the datetime)
and a more in-depth description of what the migration actually does.
To easily get a new id, run the following on any unix system:
{{< highlight bash >}}
date +%Y%m%d%H%M%S
{{< /highlight >}}
New migrations should be added via the `init()` function to the `migrations` variable.
All migrations are sorted before being executed, since `init()` does not guarantee the order.
When you're adding a new struct, you also need to add it to the `models.GetTables()` function
to ensure it will be created on new installations.
### Example
{{< highlight golang >}}
package migration
import (
"github.com/go-xorm/xorm"
"src.techknowlogick.com/xormigrate"
)
// Used for rollback
type teamMembersMigration20190328074430 struct {
Updated int64 `xorm:"updated"`
}
func (teamMembersMigration20190328074430) TableName() string {
return "team_members"
}
func init() {
migrations = append(migrations, &xormigrate.Migration{
ID: "20190328074430",
Description: "Remove updated from team_members",
Migrate: func(tx *xorm.Engine) error {
return dropTableColum(tx, "team_members", "updated")
},
Rollback: func(tx *xorm.Engine) error {
return tx.Sync2(teamMembersMigration20190328074430{})
},
})
}
{{< /highlight >}}
You should always copy the changed parts of the struct you're changing when adding migraitons.
@@ -0,0 +1,68 @@
---
date: "2019-02-12:00:00+02:00"
title: "Development"
toc: true
draft: false
type: "doc"
menu:
sidebar:
parent: "development"
name: "Development"
---
# Development
We use go modules to vendor libraries for Vikunja, so you'll need at least go `1.11` to use these.
If you don't intend to add new dependencies, go `1.9` and above should be fine.
To contribute to Vikunja, fork the project and work on the master branch.
A lot of developing tasks are automated using a Makefile, so make sure to [take a look at it]({{< ref "make.md">}}).
## Libraries
We keep all libraries used for Vikunja around in the `vendor/` folder to still be able to build the project even if
some maintainers take their libraries down like [it happened in the past](https://github.com/jteeuwen/go-bindata/issues/5).
## Tests
See [testing]({{< ref "test.md">}}).
#### Development using go modules
If you're able to use go modules, you can clone the project wherever you want to and work from there.
However, when building or running tests, please supply the `-mod=vendor` flag to go so it builds using the
dependencies from the `vendor/` folder.
#### Development-setup without go modules
Some internal packages are referenced using their respective package URL. This can become problematic.
To “trick” the Go tool into thinking this is a clone from the official repository, download the source code
into `$GOPATH/code.vikunja.io/api`. Fork the Vikunja repository, it should then be possible to switch the source directory on the command line.
{{< highlight bash >}}
cd $GOPATH/src/code.vikunja.io/api
{{< /highlight >}}
To be able to create pull requests, the forked repository should be added as a remote to the Vikunja sources, otherwise changes can’t be pushed.
{{< highlight bash >}}
git remote rename origin upstream
git remote add origin git@git.kolaente.de:<USERNAME>/api.git
git fetch --all --prune
{{< /highlight >}}
This should provide a working development environment for Vikunja. Take a look at the Makefile to get an overview about
the available tasks. The most common tasks should be `make test` which will start our test environment and `make build`
which will build a vikunja binary into the working directory. Writing test cases is not mandatory to contribute, but it
is highly encouraged and helps developers sleep at night.
That’s it! You are ready to hack on Vikunja. Test changes, push them to the repository, and open a pull request.
## Static assets
Each Vikunja release contains all static assets directly compiled into the binary.
To prevent this during development, use the `dev` tag when developing.
See the [make docs](make.md#statically-compile-all-templates-into-the-binary) about how to compile with static assets for a release.
+151
View File
@@ -0,0 +1,151 @@
---
date: "2019-02-12:00:00+02:00"
title: "Makefile"
draft: false
type: "doc"
menu:
sidebar:
parent: "development"
---
# Makefile
We scripted a lot of tasks used mostly for developing into the makefile. This documents explains what
taks are available and what they do.
## CI
These tasks are automatically run in our CI every time someone pushes to master or you update a pull request:
* `make lint`
* `make fmt-check`
* `make ineffassign-check`
* `make misspell-check`
* `make goconst-check`
* `make generate`
* `make build`
### clean
{{< highlight bash >}}
make clean
{{< /highlight >}}
Clears all builds and binaries.
### test
{{< highlight bash >}}
make test
{{< /highlight >}}
Runs all tests in Vikunja.
### Format the code
{{< highlight bash >}}
make fmt
{{< /highlight >}}
Formats all source code using `go fmt`.
#### Check formatting
{{< highlight bash >}}
make fmt-check
{{< /highlight >}}
Checks if the code needs to be formatted. Fails if it does.
### Build Vikunja
{{< highlight bash >}}
make build
{{< /highlight >}}
Builds a `vikunja`-binary in the root directory of the repo for the platform it is run on.
### Statically compile all templates into the binary
{{< highlight bash >}}
make generate
{{< /highlight >}}
This generates static code with all templates, meaning no template need to be referenced at runtime.
### Compress the built binary
{{< highlight bash >}}
make compress-build
{{< /highlight >}}
Go binaries are very big.
To make the vikunja binary smaller, we can compress it using [upx](https://upx.github.io/).
### Build Releases
{{< highlight bash >}}
make release
{{< /highlight >}}
Builds binaries for all platforms and zips them with a copy of the `templates/` folder.
All built zip files are stored into `dist/zips/`. Binaries are stored in `dist/binaries/`,
binaries bundled with `templates` are stored in `dist/releases/`.
All cross-platform binaries built using this series of commands are built with the help of
[xgo](https://github.com/techknowlogick/xgo). The make command will automatically install the
binary to be able to use it.
`make release` is actually just a shortcut to execute `make release-dirs release-windows release-linux release-darwin release-copy release-check release-os-package release-zip`.
* `release-dirs` creates all directories needed
* `release-windows`/`release-linux`/`release-darwin` execute xgo to build for their respective platforms
* `release-copy` bundles binaries with a copy of `templates/` to then be zipped
* `release-check` creates sha256 checksums for each binary which will be included in the zip file
* `release-os-package` bundles a binary with a copy of the `templates/` folder, the `sha256` checksum file, a sample `config.yml` and a copy of the license in a folder for each architecture
* `release-compress` compresses all build binaries, see `compress-build`
* `release-zip` makes a zip file for the files created by `release-os-package`
### Build debian packages
{{< highlight bash >}}
make build-deb
{{< /highlight >}}
Will build a `.deb` package into the current folder. You need to have [fpm](https://fpm.readthedocs.io/en/latest/intro.html) installed to be able to do this.
#### Make a debian repo
{{< highlight bash >}}
make reprepro
{{< /highlight >}}
Takes an already built debian package and creates a debian repo structure around it.
Used to be run inside a [docker container](https://git.kolaente.de/konrad/reprepro-docker) in the CI process when releasing.
### Generate swagger definitions from code comments
{{< highlight bash >}}
make do-the-swag
{{< /highlight >}}
Generates swagger definitions from the comments in the code.
#### Check if swagger generation is needed
{{< highlight bash >}}
make got-swag
{{< /highlight >}}
This command is currently more an experiment, use it with caution.
It may bring up wrong results.
### Code-Checks
* `misspell-check`: Checks for commonly misspelled words
* `ineffassign-check`: Checks for ineffectual assignments in the code using [ineffassign](https://github.com/gordonklaus/ineffassign).
* `gocyclo-check`: Calculates cyclomatic complexities of functions using [gocyclo](https://github.com/fzipp/gocyclo).
* `static-check`: Analyzes the code for bugs, improvements and more using [staticcheck](https://staticcheck.io/docs/).
* `gosec-check`: Inspects source code for security problems by scanning the Go AST using the [gosec tool](https://github.com/securego/gosec).
* `goconst-check`: Finds repeated strings that could be replaced by a constant using [goconst](https://github.com/jgautheron/goconst/).
+96
View File
@@ -0,0 +1,96 @@
---
date: "2020-01-19:16:00+02:00"
title: "Migrations"
draft: false
type: "doc"
menu:
sidebar:
parent: "development"
---
# Writing a migrator for Vikunja
It is possible to migrate data from other to-do services to Vikunja.
To make this easier, we have put together a few helpers which are documented on this page.
In general, each migrator implements a migrator interface which is then called from a client.
The interface makes it possible to use helper methods which handle http an focus only on the implementation of the migrator itself.
### Structure
All migrator implementations live in their own package in `pkg/modules/migration/<name-of-the-service>`.
When creating a new migrator, you should place all related code inside that module.
### Migrator interface
The migrator interface is defined as follows:
```go
// Migrator is the basic migrator interface which is shared among all migrators
type Migrator interface {
// Migrate is the interface used to migrate a user's tasks from another platform to vikunja.
// The user object is the user who's tasks will be migrated.
Migrate(user *models.User) error
// AuthURL returns a url for clients to authenticate against.
// The use case for this are Oauth flows, where the server token should remain hidden and not
// known to the frontend.
AuthURL() string
// Name holds the name of the migration.
// This is used to show the name to users and to keep track of users who already migrated.
Name() string
}
```
### Defining http routes
Once your migrator implements the migration interface, it becomes possible to use the helper http handlers.
Their usage is very similar to the [general web handler](https://kolaente.dev/vikunja/web#user-content-defining-routes-using-the-standard-web-handler):
The `RegisterRoutes(m)` method registers all routes with the scheme `/[MigratorName]/(auth|migrate|status)` for the
authUrl, Status and Migrate methods.
```go
// This is an example for the Wunderlist migrator
if config.MigrationWunderlistEnable.GetBool() {
wunderlistMigrationHandler := &migrationHandler.MigrationWeb{
MigrationStruct: func() migration.Migrator {
return &wunderlist.Migration{}
},
}
wunderlistMigrationHandler.RegisterRoutes(m)
}
```
You should also document the routes with [swagger annotations]({{< ref "../practical-instructions/swagger-docs.md" >}}).
### Insertion helper method
There is a method available in the `migration` package which takes a fully nested Vikunja structure and creates it with all relations.
This means you start by adding a namespace, then add lists inside of that namespace, then tasks in the lists and so on.
The root structure must be present as `[]*models.NamespaceWithLists`.
Then call the method like so:
```go
fullVikunjaHierachie, err := convertWunderlistToVikunja(wContent)
if err != nil {
return
}
err = migration.InsertFromStructure(fullVikunjaHierachie, user)
```
### Configuration
You should add at least an option to enable or disable the migration.
Chances are, you'll need some more options for things like client ID and secret
(if the other service uses oAuth as an authentication flow).
The easiest way to implement an on/off switch is to check whether your migration service is enabled or not when
registering the routes, and then simply don't registering the routes in the case it is disabled.
#### Making the migrator public in `/info`
You should make your migrator available in the `/info` endpoint so that frontends can display options to enable them or not.
To do this, add an entry to `pkg/routes/api/v1/info.go`.
+199
View File
@@ -0,0 +1,199 @@
---
date: "2019-02-12:00:00+02:00"
title: "Project structure"
draft: false
type: "doc"
menu:
sidebar:
parent: "development"
---
# Project structure
In general, this api repo has the following structure:
* `docker`
* `docs`
* `pkg`
* `caldav`
* `cmd`
* `config`
* `db`
* `fixtures`
* `files`
* `integration`
* `log`
* `mail`
* `metrics`
* `migration`
* `models`
* `modules`
* `migration`
* `handler`
* `wunderlist`
* `red`
* `routes`
* `api/v1`
* `static`
* `swagger`
* `user`
* `utils`
* `version`
* `REST-Tests`
* `templates`
* `vendor`
This document will explain what these mean and what you can find where.
## Root level
The root directory is where [the config file]({{< ref "../setup/config.md">}}), [Makefile]({{< ref "make.md">}}), license, drone config,
application entry point (`main.go`) and so on are located.
## docker
This directory holds additonal files needed to build and run the docker container, mainly service configuration to properly run Vikunja inside a docker
container.
## pkg
This is where most of the magic happens. Most packages with actual code are located in this folder.
### caldav
This folder holds a simple caldav implementation which is responsible for returning the caldav feature.
### cmd
This package contains all cli-related files and functions.
To learn more about how to add a new command, see [the cli docs]({{< ref "cli.md">}}).
To learn more about how to use this cli, see [the cli usage docs]({{< ref "../usage/cli.md">}}).
### config
This package configures the config. It sets default values and sets up viper and tells it where to look for config files,
how to interpret which env variables for config etc.
If you want to add a new config parameter, you should add default value in this package.
### db
This package contains the db connection handling and db fixtures for testing.
Each other package gets its db connection object from this package.
### files
This package is responsible for all file-related things.
This means it handles saving and retrieving files from the db and the underlying file system.
### integration
All integration tests live here.
See [integration tests]({{< ref "test.md" >}}#integration-tests) for more details.
### log
Similar to `config`, this will set up the logging, based on differen logging backends.
This init is called in `main.go` after the config init is done.
### mail
This package handles all mail sending. To learn how to send a mail, see [sending emails]({{< ref "../practical-instructions/mail.md">}}).
### metrics
This package handles all metrics which are exposed to the prometheus endpoint.
To learn how it works and how to add new metrics, take a look at [how metrics work]({{< ref "../practical-instructions/metrics.md">}}).
### migration
This package handles all migrations.
All migrations are stored and executed here.
To learn more, take a look at the [migrations docs]({{< ref "../development/db-migrations.md">}}).
### models
This is where most of the magic happens.
When adding new features or upgrading existing ones, that most likely happens here.
Because this package is pretty huge, there are several documents and how-to's about it:
* [Adding a feature]({{< ref "../practical-instructions/feature.md">}})
* [Making calls to the database]({{< ref "../practical-instructions/database.md">}})
### modules
#### migration
See [writing a migrator]({{< ref "migration.md" >}}).
### red (redis)
This package initializes a connection to a redis server.
This inizialization is automatically done at the startup of vikunja.
It also has a function (`GetRedis()`) which returns a redis client object you can then use in your package
to talk to redis.
It uses the [go-redis](https://github.com/go-redis/redis) library, please see their configuration on how to use it.
### routes
This package defines all routes which are available for vikunja clients to use.
To add a new route, see [adding a new route]({{< ref "../practical-instructions/feature.md">}}).
#### api/v1
This is where all http-handler functions for the api are stored.
Every handler function which does not use the standard web handler should live here.
### static
All static files generated by `make generate` live here.
### swagger
This is where the [generated]({{< ref "make.md#generate-swagger-definitions-from-code-comments">}} [api docs]({{< ref "../usage/api.md">}}) live.
You usually don't need to touch this package.
### user
All user-related things like registration etc. live in this package.
### utils
A small package, containing some helper functions:
* `MakeRandomString`: Generates a random string of a given length.
* `Sha256`: Calculates a sha256 hash from a given string.
See their function definitions for instructions on how to use them.
### version
The single purpouse of this package is to hold the current vikunja version which gets overridden through build flags
each time `make release` or `make build` is run.
It is a seperate package to avoid import cycles with other packages.
## REST-Tests
Holds all kinds of test files to directly test the api from inside of [jetbrains ide's](https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html).
These files are currently more an experiment, maybe we will drop them in the future to use something we could integrate in the testing process with drone.
Therefore, this has no claim to be complete yet even working, you're free to change whatever is needed to get it working for you.
## templates
Holds the email templates used to send plain text and html emails for new user registration and password changes.
## vendor
All libraries needed to build Vikunja.
We keep all libraries used for Vikunja around in the `vendor/` folder to still be able to build the project even if
some maintainers take their libraries down like [it happened in the past](https://github.com/jteeuwen/go-bindata/issues/5).
When adding a new dependency, make sure to run `go mod vendor` to put it inside this directory.
+70
View File
@@ -0,0 +1,70 @@
---
date: "2019-02-12:00:00+02:00"
title: "Testing"
draft: false
type: "doc"
menu:
sidebar:
parent: "development"
---
# Testing
You can run unit tests with [our `Makefile`]({{< ref "make.md">}}) with
{{< highlight bash >}}
make test
{{< /highlight >}}
### Running tests with config
You can run tests with all available config variables if you want, enabeling you to run tests for a lot of scenarios.
To use the normal config set the enviroment variable `VIKUNJA_TESTS_USE_CONFIG=1`.
### Show sql queries
When `UNIT_TESTS_VERBOSE=1` is set, all sql queries will be shown when tests are run.
### Fixtures
All tests are run against a set of db fixtures.
These fixtures are defined in `pkg/models/fixtures` in YAML-Files which represent the database structure.
When you add a new test case which requires new database entries to test against, update these files.
# Integration tests
All integration tests live in `pkg/integrations`.
You can run them by executing `make integration-test`.
The integration tests use the same config and fixtures as the unit tests and therefor have the same options available,
see at the beginning of this document.
To run integration tests, use `make integration-test`.
# Initializing db fixtures when writing tests
All db fixtures for all tests live in the `pkg/db/fixtures/` folder as yaml files.
Each file has the same name as the table the fixtures are for.
You should put new fixtures in this folder.
When initializing db fixtures, you are responsible for defining which tables your package needs in your test init function.
Usually, this is done as follows (this code snippet is taken from the `user` package):
```go
err = db.InitTestFixtures("users")
if err != nil {
log.Fatal(err)
}
```
In your actual tests, you then load the fixtures into the in-memory db like so:
```go
db.LoadAndAssertFixtures(t)
```
This will load all fixtures you defined in your test init method.
You should always use this method to load fixtures, the only exception is when your package tests require extra test
fixtures other than db fixtures (like files).
@@ -0,0 +1,38 @@
---
date: "2019-02-12:00:00+02:00"
title: "Database"
draft: false
type: "doc"
menu:
sidebar:
parent: "practical instructions"
---
# Database
Vikunja uses [xorm](http://xorm.io/) as an abstraction layer to handle the database connection.
Please refer to [their](http://xorm.io/docs/) documentation on how to exactly use it.
Inside the `models` package, a variable `x` is available which contains a pointer to an instance of `xorm.Engine`.
This is used whenever you make a call to the database to get or update data.
This xorm instance is set up and initialized every time vikunja is started.
### Adding new database tables
To add a new table to the database, add a an instance of your struct to the `tables` variable in the
init function in `pkg/models/models.go`. Xorm will sync them automatically.
You also need to add a pointer to the `tablesWithPointer` slice to enable caching for all instances of this struct.
To learn more about how to configure your struct to create "good" tables, refer to [the xorm documentaion](http://xorm.io/docs/).
### Adding data to test fixtures
Adding data for test fixtures is done in via `yaml` files insinde of `pkg/models/fixtures`.
The name of the yaml file should equal the table name in the database.
Adding values to it is done via array definition inside of the yaml file.
**Note**: Table and column names need to be in snake_case as that's what is used internally in the database
and for mapping values from the database to xorm so your structs can use it.
@@ -0,0 +1,72 @@
---
date: "2019-02-12:00:00+02:00"
title: "Custom Errors"
draft: false
type: "doc"
menu:
sidebar:
parent: "practical instructions"
---
# Custom Errors
All custom errors are defined in `pkg/models/errors.go`.
You should add new ones in this file.
Custom errors usually have fields for the http return code, a [vikunja-specific error code]({{< ref "../usage/errors.md">}})
and a human-readable error message about what went wrong.
An error consists of multiple functions and definitions:
{{< highlight golang >}}
// This struct holds any information about this specific error.
// In this case, it contains the user ID of a nonexistand user.
// This type should always be a struct, even if it has no values in it.
// ErrUserDoesNotExist represents a "UserDoesNotExist" kind of error.
type ErrUserDoesNotExist struct {
UserID int64
}
// This function is mostly used in unit tests to check if a returned error is of that type.
// Every error type should have one of these.
// The name should always start with IsErr... followed by the name of the error.
// IsErrUserDoesNotExist checks if an error is a ErrUserDoesNotExist.
func IsErrUserDoesNotExist(err error) bool {
_, ok := err.(ErrUserDoesNotExist)
return ok
}
// This is the definition of the actual error type.
// Your error type is _required_ to implement this in order to be able to be returned as an "error" from functions.
func (err ErrUserDoesNotExist) Error() string {
return fmt.Sprintf("User does not exist [user id: %d]", err.UserID)
}
// This const holds the vikunja error code used to be able to identify this error without having to
// rely on an error string.
// This needs to be unique, so you should check whether the error code exists or not.
// The general convention for error codes is as follows:
// * Every "group" errors lives in a thousend something. For example all user issues are 1000-something, all
// list errors are 3000-something and so on.
// * New error codes should be the current max error code + 1. Don't take free numbers to prevent old errors
// which are depricated and removed from being "new ones". For example, if there are error codes 1001, 1002, 1004,
// a new error should be 1005 and not 1003.
// ErrCodeUserDoesNotExist holds the unique world-error code of this error
const ErrCodeUserDoesNotExist = 1005
// This is the implementation which returns an http error which is then passed to the client.
// Here you define the http status code with which one the error will be returned, the vikunja error code and
// a human-readable error message.
// HTTPError holds the http error description
func (err ErrUserDoesNotExist) HTTPError() web.HTTPError {
return web.HTTPError{
HTTPCode: http.StatusNotFound,
Code: ErrCodeUserDoesNotExist,
Message: "The user does not exist.",
}
}
{{< /highlight >}}
@@ -0,0 +1,33 @@
---
date: "2019-02-12:00:00+02:00"
title: "Add a new api endpoint"
draft: false
type: "doc"
menu:
sidebar:
parent: "practical instructions"
---
# Add a new api endpoint/feature
Most of the api endpoints/features of Vikunja are using the [common web handler](https://code.vikunja.io/web).
This is a library created by Vikunja in an effort to facilitate the creation of REST endpoints.
This works by abstracting the handling of CRUD-Requests, including rights check.
You can learn more about the web handler on [the project's repo](https://code.vikunja.io/web).
### Helper for pagination
Pagination limits can be calculated with a helper function, `getLimitFromPageIndex(pageIndex)`
(only available in the `models` package) from any page number.
It returns the `limit` (max-length) and `offset` parameters needed for SQL-Queries.
You can feed this function directly into xorm's `Limit`-Function like so:
{{< highlight golang >}}
lists := []List{}
err := x.Limit(getLimitFromPageIndex(pageIndex, itemsPerPage)).Find(&lists)
{{< /highlight >}}
// TODO: Add a full example from start to finish, like a tutorial on how to create a new endpoint?
@@ -0,0 +1,84 @@
---
date: "2019-02-12:00:00+02:00"
title: "Mailer"
draft: false
type: "doc"
menu:
sidebar:
parent: "practical instructions"
---
# Mailer
This document explains how to use the mailer to send emails and what to do to create a new kind of email to be sent.
## Sending emails
**Note:** You should use mail templates whenever possible (see below).
To send an email, use the function `mail.SendMail(options)`. The options are defined as follows:
{{< highlight golang >}}
type Opts struct {
To string // The email address of the recipent
Subject string // The subject of the mail
Message string // The plaintext message in the mail
HTMLMessage string // The html message
ContentType ContentType // The content type of the mail. Can be either mail.ContentTypePlain, mail.ContentTypeHTML, mail.ContentTypeMultipart. You should set this according to the kind of mail you want to send.
Boundary string
Headers []*header // Other headers to set in the mail.
}
{{< /highlight >}}
## Sending emails based on a template
For each mail with a template, there are two email templates: One for plaintext emails, one for html emails.
These are located in the `templates/mail` folder and follow the conventions of `template-name.{plain|hmtl}.tmpl`,
both the plaintext and html templates are in the same folder.
To send a mail based on a template, use the function `mail.SendMailWithTemplate(to, subject, tpl string, data map[string]interface{})`.
`to` and `subject` are pretty much self-explanatory, `tpl` is the name of the template, without `.html.tmpl` or `.plain.tmpl`.
`data` is a map you can pass additional data to your template.
#### Sending a mail with a template
A basic html email template would look like this:
{{< highlight go-html-template >}}
{{template "mail-header.tmpl" .}}
<p>
Hey there!<br/>
This is a minimal html email example.<br/>
{{.Something}}
</p>
{{template "mail-footer.tmpl"}}
{{< /highlight >}}
And the corresponding plaintext template:
{{< highlight go-text-template >}}
Hey there!
This is a minimal html email example.
{{.Something}}
{{< /highlight >}}
You would then call this like so:
{{< highlight golang >}}
data := make(map[string]interface{})
data["Something"] = "I am some computed value"
to := "test@example.com"
subject := "A simple test mail"
tpl := "demo" // Assuming you saved the templates as demo.plain.tmpl and demo.html.tmpl
mail.SendMailWithTemplate(to, subject, tpl, data)
{{< /highlight >}}
The function does not return an error. If an error occures when sending a mail, it is logged but not returned because sending the mail happens asinchrounly.
Notice the `mail-header.tmpl` and `mail-footer.tmpl` in the template. These populate some basic css, a box for your content and the vikunja logo.
All that's left for you is to put the content in, which then will appear in a beautifully-styled box.
Remeber, these are email templates. This is different from normal html/css, you cannot use whatever you want (because most of the clients are wayyy to outdated).
@@ -0,0 +1,46 @@
---
date: "2019-02-12:00:00+02:00"
title: "Metrics"
draft: false
type: "doc"
menu:
sidebar:
parent: "practical instructions"
---
# Metrics
Metrics work by exposing a `/metrics` endpoint which can then be accessed by prometheus.
To keep the load on the database minimal, metrics are stored and updated in redis.
The `metrics` package provides several functions to create and update metrics.
## New metrics
First, define a `const` with the metric key in redis. This is done in `pkg/metrics/metrics.go`.
To expose a new metric, you need to register it in the `init` function inside of the `metrics` package like so:
{{< highlight golang >}}
// Register total user count metric
promauto.NewGaugeFunc(prometheus.GaugeOpts{
Name: "vikunja_team_count", // The key of the metric. Must be unique.
Help: "The total number of teams on this instance", // A description about the metric itself.
}, func() float64 {
count, _ := GetCount(TeamCountKey) // TeamCountKey is the const we defined earlier.
return float64(count)
})
{{< /highlight >}}
Then you'll need to set the metrics initial value on every startup of vikunja.
This is done in `pkg/routes/routes.go` to avoid cyclic imports.
If metrics are enabled, it checks if a redis connection is available and then sets the initial values.
A convenience function is available if the metric is based on a database struct.
Because metrics are stored in redis, you are responsible to increase or decrease these based on criteria you define.
To do this, use `metrics.UpdateCount(value, key)` where `value` is the amount you want to cange it (you can pass
negative values to decrease it) and `key` it the redis key used to define the metric.
# Using it
A Prometheus config with a Grafana template is available at [our git repo](https://git.kolaente.de/vikunja/monitoring).
@@ -0,0 +1,31 @@
---
date: "2019-02-12:00:00+02:00"
title: "Adding new config options"
draft: false
type: "doc"
menu:
sidebar:
parent: "practical instructions"
---
# Adding new config options
Vikunja uses [viper](https://github.com/spf13/viper) to handle configuration options.
It handles parsing all different configuration sources.
The configuration is done in sections. These are represented with a `.` in viper.
Take a look at `pkg/config/config.go` to understand how these are set.
To add a new config option, you should add a default value to `pkg/config/config.go`.
Default values should always enable the feature to work somehow, or turn it off completely if it always needs
additional configuration.
Make sure to add the new config option to [the config document]({{< ref "../setup/config.md">}}) and the default config file
(`config.yml.sample` at the root of the repository) to make sure it is well documented.
If you're using a computed value as a default, make sure to update the sample config file and debian
post-install scripts to reflect that.
To get a configured option, use `viper.Get("config.option")`.
Take a look at [viper's documentation](https://github.com/spf13/viper#getting-values-from-viper) to learn of the
different ways available to get config options.
@@ -0,0 +1,47 @@
---
date: "2019-02-12:00:00+02:00"
title: "Modifying swagger api docs"
draft: false
type: "doc"
menu:
sidebar:
parent: "practical instructions"
---
# Adding/editing swagger api docs
The api documentation is generated using [swaggo](https://github.com/swaggo/swag) from comments.
### Documenting structs
You should always comment every field which will be exposed as a json in the api.
These comments will show up in the documentation, it'll make it easier for developers using the api.
As an example, this is the definition of a list with all comments:
{{< highlight golang >}}
// List represents a list of tasks
type List struct {
// The unique, numeric id of this list.
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"list"`
// The title of the list. You'll see this in the namespace overview.
Title string `xorm:"varchar(250)" json:"title" valid:"required,runelength(3|250)" minLength:"3" maxLength:"250"`
// The description of the list.
Description string `xorm:"varchar(1000)" json:"description" valid:"runelength(0|1000)" maxLength:"1000"`
OwnerID int64 `xorm:"int(11) INDEX" json:"-"`
NamespaceID int64 `xorm:"int(11) INDEX" json:"-" param:"namespace"`
// The user who created this list.
Owner User `xorm:"-" json:"owner" valid:"-"`
// An array of tasks which belong to the list.
Tasks []*ListTask `xorm:"-" json:"tasks"`
// A unix timestamp when this list was created. You cannot change this value.
Created int64 `xorm:"created" json:"created"`
// A unix timestamp when this list was last updated. You cannot change this value.
Updated int64 `xorm:"updated" json:"updated"`
web.CRUDable `xorm:"-" json:"-"`
web.Rights `xorm:"-" json:"-"`
}
{{< /highlight >}}
+52
View File
@@ -0,0 +1,52 @@
---
date: "2019-02-12:00:00+02:00"
title: "What to backup"
draft: false
type: "doc"
menu:
sidebar:
parent: "setup"
---
# What to backup
Vikunja does not store any data outside of the database.
So, all you need to backup are the contents of that database and maybe the config file.
## MySQL
To create a backup from mysql use the `mysqldump` command:
{{< highlight bash >}}
mysqldump -u <user> -p -h <db-host> <database> > vkunja-backup.sql
{{< /highlight >}}
You will be prompted for the password of the mysql user.
To restore it, simply pipe it back into the `mysql` command:
{{< highlight bash >}}
mysql -u <user> -p -h <db-host> <database> < vkunja-backup.sql
{{< /highlight >}}
## PostgreSQL
To create a backup from PostgreSQL use the `pg_dump` command:
{{< highlight bash >}}
pg_dump -U <user> -h <db-host> <database> > vikunja-backup.sql
{{< /highlight >}}
You might be prompted for the password of the database user.
To restore it, simply pipe it back into the `psql` command:
{{< highlight bash >}}
psql -U <user> -h <db-host> <database> < vikunja-backup.sql
{{< /highlight >}}
For more information, please visit the [relevant PostgreSQL documentation](https://www.postgresql.org/docs/12/backup-dump.html).
## SQLite
To backup sqllite databases, it is enough to copy the database elsewhere.
@@ -0,0 +1,29 @@
---
date: "2019-02-12:00:00+02:00"
title: "Build from sources"
draft: false
type: "doc"
menu:
sidebar:
parent: "setup"
---
# Build Vikunja from source
Vikunja being a go application, has no other dependencies than go itself.
All libraries are bundeled inside the repo in the `vendor/` folder, so all it boils down to are these steps:
1. Make sure [Go](https://golang.org/doc/install) is properly installed on your system. You'll need at least Go `1.9`.
2. Make sure [Make](https://www.gnu.org/software/make/) is properly installed on your system.
3. Clone the repo with `git clone https://code.vikunja.io/api`
3. Run `make build` in the source of this repo. This will build a binary in the root of the repo which will be able to run on your system.
*Note:* Static ressources such as email templates are built into the binary.
For these to work, you may need to run `make generate` before building the vikunja binary.
When builing entirely with `make`, you dont need to do this, `make generate` will be run automatically when running `make build`.
# Build for different architectures
To build for other platforms and architectures than the one you're currently on, simply run `make release` or `make release-{linux|windows|darwin}`.
More options are available, please refer to the [makefile docs]({{< ref "../development/make.md">}}) for more details.
+210
View File
@@ -0,0 +1,210 @@
---
date: "2019-02-12:00:00+02:00"
title: "Config options"
draft: false
type: "doc"
menu:
sidebar:
parent: "setup"
---
# Configuration options
You can either use a `config.yml` file in the root directory of vikunja or set all config option with
environment variables. If you have both, the value set in the config file is used.
Variables are nested in the `config.yml`, these nested variables become `VIKUNJA_FIRST_CHILD` when configuring via
environment variables. So setting
{{< highlight bash >}}
export VIKUNJA_FIRST_CHILD=true
{{< /highlight >}}
is the same as defining it in a `config.yml` like so:
{{< highlight yaml >}}
first:
child: true
{{< /highlight >}}
## Config file locations
Vikunja will search on various places for a config file:
* Next to the location of the binary
* In the `service.rootpath` location set in a config (remember you can set config arguments via environment variables)
* In `/etc/vikunja`
* In `~/.config/vikunja`
# Default configuration with explanations
This is the same as the `config.yml.sample` file you'll find in the root of vikunja.
{{< highlight yaml >}}
service:
# This token is used to verify issued JWT tokens.
# Default is a random token which will be generated at each startup of vikunja.
# (This means all already issued tokens will be invalid once you restart vikunja)
JWTSecret: "cei6gaezoosah2bao3ieZohkae5aicah"
# The interface on which to run the webserver
interface: ":3456"
# The URL of the frontend, used to send password reset emails.
frontendurl: ""
# The base path on the file system where the binary and assets are.
# Vikunja will also look in this path for a config file, so you could provide only this variable to point to a folder
# with a config file which will then be used.
rootpath: <the path of the executable>
# The max number of items which can be returned per page
maxitemsperpage: 50
# If set to true, enables a /metrics endpoint for prometheus to collect metrics about the system
# You'll need to use redis for this in order to enable common metrics over multiple nodes
enablemetrics: false
# Enable the caldav endpoint, see the docs for more details
enablecaldav: true
# Set the motd message, available from the /info endpoint
motd: ""
# Enable sharing of lists via a link
enablelinksharing: true
# Whether to let new users registering themselves or not
enableregistration: true
# Whether to enable task attachments or not
enabletaskattachments: true
# The time zone all timestamps are in
timezone: GMT
# Whether task comments should be enabled or not
enabletaskcomments: true
database:
# Database type to use. Supported types are mysql, postgres and sqlite.
type: "sqlite"
# Database user which is used to connect to the database.
user: "vikunja"
# Databse password
password: ""
# Databse host
host: "localhost"
# Databse to use
database: "vikunja"
# When using sqlite, this is the path where to store the data
Path: "./vikunja.db"
# Sets the max open connections to the database. Only used when using mysql and postgres.
maxopenconnections: 100
# Sets the maximum number of idle connections to the db.
maxidleconnections: 50
# The maximum lifetime of a single db connection in miliseconds.
maxconnectionlifetime: 10000
# Secure connection mode. Only used with postgres.
# (see https://pkg.go.dev/github.com/lib/pq?tab=doc#hdr-Connection_String_Parameters)
sslmode: disable
cache:
# If cache is enabled or not
enabled: false
# Cache type. Possible values are memory or redis, you'll need to enable redis below when using redis
type: memory
# When using memory this defines the maximum size an element can take
maxelementsize: 1000
redis:
# Whether to enable redis or not
enabled: false
# The host of the redis server including its port.
host: 'localhost:6379'
# The password used to authenicate against the redis server
password: ''
# 0 means default database
db: 0
cors:
# Whether to enable or disable cors headers.
# Note: If you want to put the frontend and the api on seperate domains or ports, you will need to enable this.
# Otherwise the frontend won't be able to make requests to the api through the browser.
enable: true
# A list of origins which may access the api.
origins:
- *
# How long (in seconds) the results of a preflight request can be cached.
maxage: 0
mailer:
# Whether to enable the mailer or not. If it is disabled, all users are enabled right away and password reset is not possible.
enabled: false
# SMTP Host
host: ""
# SMTP Host port
port: 587
# SMTP username
username: "user"
# SMTP password
password: ""
# Wether to skip verification of the tls certificate on the server
skiptlsverify: false
# The default from address when sending emails
fromemail: "mail@vikunja"
# The length of the mail queue.
queuelength: 100
# The timeout in seconds after which the current open connection to the mailserver will be closed.
queuetimeout: 30
log:
# A folder where all the logfiles should go.
path: <rootpath>logs
# Whether to show any logging at all or none
enabled: true
# Where the normal log should go. Possible values are stdout, stderr, file or off to disable standard logging.
standard: "stdout"
# Change the log level. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG.
level: "INFO"
# Whether or not to log database queries. Useful for debugging. Possible values are stdout, stderr, file or off to disable database logging.
database: "off"
# The log level for database log messages. Possible values (case-insensitive) are CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG.
databaselevel: "WARNING"
# Whether to log http requests or not. Possible values are stdout, stderr, file or off to disable http logging.
http: "stdout"
# Echo has its own logging which usually is unnessecary, which is why it is disabled by default. Possible values are stdout, stderr, file or off to disable standard logging.
echo: "off"
ratelimit:
# whether or not to enable the rate limit
enabled: false
# The kind on which rates are based. Can be either "user" for a rate limit per user or "ip" for an ip-based rate limit.
kind: user
# The time period in seconds for the limit
period: 60
# The max number of requests a user is allowed to do in the configured time period
limit: 100
# The store where the limit counter for each user is stored. Possible values are "memory" or "redis"
store: memory
files:
# The path where files are stored
basepath: ./files # relative to the binary
# The maximum size of a file, as a human-readable string.
# Warning: The max size is limited 2^64-1 bytes due to the underlying datatype
maxsize: 20MB
migration:
# These are the settings for the wunderlist migrator
wunderlist:
# Wheter to enable the wunderlist migrator or not
enable: false
# The client id, required for making requests to the wunderlist api
# You need to register your vikunja instance at https://developer.wunderlist.com/apps/new to get this
clientid:
# The client secret, also required for making requests to the wunderlist api
clientsecret:
# The url where clients are redirected after they authorized Vikunja to access their wunderlist stuff.
# This needs to match the url you entered when registering your Vikunja instance at wunderlist.
# This is usually the frontend url where the frontend then makes a request to /migration/wunderlist/migrate
# with the code obtained from the wunderlist api.
# Note that the vikunja frontend expects this to be /migrate/wunderlist
redirecturl:
avatar:
# Switch between avatar providers. Possible values are gravatar and default.
# gravatar will fetch the avatar based on the user email.
# default will return a default avatar for every request.
provider: gravatar
# When using gravatar, this is the duration in seconds until a cached gravatar user avatar expires
gravatarexpiration: 3600
{{< /highlight >}}
@@ -0,0 +1,214 @@
---
date: "2019-02-12:00:00+02:00"
title: "Full docker example"
draft: false
type: "doc"
menu:
sidebar:
parent: "setup"
---
# Full docker example
This docker compose configuration will run Vikunja with backend and frontend with a mariadb as database.
It uses an nginx container or traefik on the host to proxy backend and frontend into a single port.
For all available configuration options, see [configuration]({{< ref "config.md">}}).
### Redis
To use redis, you'll need to add this to the config examples below:
{{< highlight yaml >}}
version: '3'
services:
api:
image: vikunja/api
environment:
VIKUNJA_REDIS_ENABLED: 1
VIKUNJA_REDIS_HOST: 'redis:6379'
VIKUNJA_CACHE_ENABLED: 1
VIKUNJA_CACHE_TYPE: redis
redis:
image: redis
{{< /highlight >}}
## Example with traefik 2
This example assumes [traefik](https://traefik.io) version 2 installed and configured to [use docker as a configuration provider](https://docs.traefik.io/providers/docker/).
We also make a few assumtions here which you'll most likely need to adjust for your traefik setup:
* Your domain is `vikunja.example.com`
* The entrypoint you want to make vikunja available from is called `https`
* The tls cert resolver is called `acme`
{{< highlight yaml >}}
version: '3'
services:
api:
image: vikunja/api
environment:
VIKUNJA_DATABASE_HOST: db
VIKUNJA_DATABASE_PASSWORD: supersecret
VIKUNJA_DATABASE_TYPE: mysql
VIKUNJA_DATABASE_USER: vikunja
VIKUNJA_DATABASE_DATABASE: vikunja
volumes:
- ./files:/app/vikunja/files
networks:
- web
- default
depends_on:
- db
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.vikunja-api.rule=Host(`vikunja.example.com`) && PathPrefix(`/api/v1`)"
- "traefik.http.routers.vikunja-api.entrypoints=https"
- "traefik.http.routers.vikunja-api.tls.certResolver=acme"
frontend:
image: vikunja/frontend
labels:
- "traefik.enable=true"
- "traefik.http.routers.vikunja-frontend.rule=Host(`vikunja.example.com`)"
- "traefik.http.routers.vikunja-frontend.entrypoints=https"
- "traefik.http.routers.vikunja-frontend.tls.certResolver=acme"
networks:
- web
- default
restart: unless-stopped
db:
image: mariadb:10
environment:
MYSQL_ROOT_PASSWORD: supersupersecret
MYSQL_USER: vikunja
MYSQL_PASSWORD: supersecret
MYSQL_DATABASE: vikunja
volumes:
- ./db:/var/lib/mysql
restart: unless-stopped
command: --max-connections=1000
networks:
web:
external: true
{{< /highlight >}}
## Example with traefik 1
This example assumes [traefik](https://traefik.io) in version 1 installed and configured to [use docker as a configuration provider](https://docs.traefik.io/v1.7/configuration/backends/docker/).
{{< highlight yaml >}}
version: '3'
services:
api:
image: vikunja/api
environment:
VIKUNJA_DATABASE_HOST: db
VIKUNJA_DATABASE_PASSWORD: supersecret
VIKUNJA_DATABASE_TYPE: mysql
VIKUNJA_DATABASE_USER: vikunja
VIKUNJA_DATABASE_DATABASE: vikunja
volumes:
- ./files:/app/vikunja/files
networks:
- web
- default
depends_on:
- db
restart: unless-stopped
labels:
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.frontend.rule=Host:vikunja.example.com;PathPrefix:/api/v1"
- "traefik.port=3456"
- "traefik.protocol=http"
frontend:
image: vikunja/frontend
labels:
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.frontend.rule=Host:vikunja.example.com;PathPrefix:/"
- "traefik.port=80"
- "traefik.protocol=http"
networks:
- web
- default
restart: unless-stopped
db:
image: mariadb:10
environment:
MYSQL_ROOT_PASSWORD: supersupersecret
MYSQL_USER: vikunja
MYSQL_PASSWORD: supersecret
MYSQL_DATABASE: vikunja
volumes:
- ./db:/var/lib/mysql
restart: unless-stopped
command: --max-connections=1000
networks:
web:
external: true
{{< /highlight >}}
## Example with nginx as proxy
You'll need to save this nginx configuration on your host under `nginx.conf`
(or elsewhere, but then you'd need to adjust the proxy mount at the bottom of the compose file):
{{< highlight conf >}}
server {
listen 80;
location / {
proxy_pass http://frontend:80;
}
location /api/ {
proxy_pass http://api:3456;
}
}
{{< /highlight >}}
`docker-compose.yml` config:
{{< highlight yaml >}}
version: '3'
services:
db:
image: mariadb:10
environment:
MYSQL_ROOT_PASSWORD: supersecret
MYSQL_DATABASE: vikunja
volumes:
- ./db:/var/lib/mysql
api:
image: vikunja/api
environment:
VIKUNJA_DATABASE_HOST: db
VIKUNJA_DATABASE_PASSWORD: supersecret
VIKUNJA_DATABASE_TYPE: mysql
VIKUNJA_DATABASE_USER: root
VIKUNJA_DATABASE_DATABASE: vikunja
volumes:
- ./files:/app/vikunja/files
depends_on:
- db
frontend:
image: vikunja/frontend
proxy:
image: nginx
ports:
- 80:80
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- api
- frontend
{{< /highlight >}}
+161
View File
@@ -0,0 +1,161 @@
---
date: "2019-02-12:00:00+02:00"
title: "Install Backend"
draft: false
type: "doc"
menu:
sidebar:
parent: "setup"
---
# Backend
## Install from binary
Download a copy of Vikunja from the [download page](https://vikunja.io/en/download/) for your architecture.
{{< highlight bash >}}
wget <download-url>
{{< /highlight >}}
### Verify the GPG signature
Starting with version `0.7`, all releases are signed using pgp.
Releases from `master` will always be signed.
To validate the downloaded zip file use the signiture file `.asc` and the key `FF054DACD908493A`:
{{< highlight bash >}}
gpg --keyserver keyserver.ubuntu.com --recv FF054DACD908493A
gpg --verify vikunja-0.7-linux-amd64-full.zip.asc vikunja-0.7-linux-amd64-full.zip
{{< /highlight >}}
### Set it up
Once you've verified the signature, you need to unzip it and make it executable, you'll also need to
create a symlink to it so you can execute Vikunja by typing `vikunja` on your system.
We'll install vikunja to `/opt/vikunja`, change the path where needed if you want to install it elsewhere.
{{< highlight bash >}}
mkdir -p /opt/vikunja
unzip <vikunja-zip-file> -d /opt/vikunja
chmod +x /opt/vikunja
ln -s /opt/vikunja/vikunja /usr/bin/vikunja
{{< /highlight >}}
### Systemd service
Take the following `service` file and adapt it to your needs:
{{< highlight service >}}
[Unit]
Description=Vikunja
After=syslog.target
After=network.target
# Depending on how you configured Vikunja, you may want to uncomment these:
#Requires=mysql.service
#Requires=mariadb.service
#Requires=postgresql.service
#Requires=redis.service
[Service]
RestartSec=2s
Type=simple
WorkingDirectory=/opt/vikunja
ExecStart=/usr/bin/vikunja
Restart=always
# If you want to bind Vikunja to a port below 1024 uncomment
# the two values below
###
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
{{< /highlight >}}
If you've installed Vikunja to a directory other than `/opt/vikunja`, you need to adapt `WorkingDirectory` accordingly.
Save the file to `/etc/systemd/system/vikunja.service`
After you made all nessecary modifications, it's time to start the service:
{{< highlight bash >}}
sudo systemctl enable vikunja
sudo systemctl start vikunja
{{< /highlight >}}
### Build from source
To build vikunja from source, see [building from source]({{< ref "build-from-source.md">}}).
### Updating
Simply replace the binary and templates with the new version, then restart Vikunja.
It will automatically run all nessecary database migrations.
**Make sure to take a look at the changelog for the new version to not miss any manual steps the update may involve!**
## Docker
(Note: this assumes some familarity with docker)
Usage with docker is pretty straightforward:
{{< highlight bash >}}
docker run -p 3456:3456 vikunja/api
{{< /highlight >}}
to run with a standard configuration.
This will expose
You can mount a local configuration like so:
{{< highlight bash >}}
docker run -p 3456:3456 -v /path/to/config/on/host.yml:/app/vikunja/config.yml:ro vikunja/api
{{< /highlight >}}
Though it is recommended to use eviroment variables or `.env` files to configure Vikunja in docker.
See [config]({{< ref "config.md">}}) for a list of available configuration options.
### Docker compose
To run the backend with a mariadb database you can use this example [docker-compose](https://docs.docker.com/compose/) file:
{{< highlight yaml >}}
version: '2'
services:
api:
image: vikunja/api:latest
environment:
VIKUNJA_DATABASE_HOST: db
VIKUNJA_DATABASE_PASSWORD: supersecret
VIKUNJA_DATABASE_TYPE: mysql
VIKUNJA_DATABASE_USER: root
VIKUNJA_SERVICE_JWTSECRET: <generated secret>
db:
image: mariadb:10
environment:
MYSQL_ROOT_PASSWORD: supersecret
MYSQL_DATABASE: vikunja
volumes:
- ./db:/var/lib/mysql
{{< /highlight >}}
See [full docker example]({{< ref "full-docker-example.md">}}) for more varations of this config.
## Debian packages
Since version 0.7 Vikunja is also released as debian packages.
To install these, grab a copy from [the download page](https://vikunja.io/en/download/) and run
{{< highlight bash >}}
dpkg -i vikunja.deb
{{< /highlight >}}
This will install the backend to `/opt/vikunja`.
To configure it, use the config file in `/etc/vikunja/config.yml`.
## Configuration
See [available configuration options]({{< ref "config.md">}}).
+135
View File
@@ -0,0 +1,135 @@
---
date: "2019-02-12:00:00+02:00"
title: "Install Frontend"
draft: false
type: "doc"
menu:
sidebar:
parent: "setup"
---
# Frontend
Installing the frontend is just a matter of hosting a bunch of static files somewhere.
With nginx or apache, you have to [download](https://vikunja.io/en/download/) the frontend files first.
Unzip them and store them somewhere your server can access them.
You also need to configure a rewrite condition to internally redirect all requests to `index.html` which handles all urls.
## API URL configuration
By default, the frontend assumes it can reach the api at `/api/v1` relative to the frontend url.
This means that if you make the frontend available at, say `https://vikunja.example.com`, it tries to reach the api
at `https://vikunja.example.com/api/v1`.
In this scenario it is not possible for the frontend and the api to live on seperate servers or even just seperate
ports on the same server with [the use of a reverse proxy]({{< ref "reverse-proxies.md">}}).
To make configurations like this possible, the api url can be set in the `index.html` file of the frontend releases.
Just open the file with a text editor - there are comments which will explain how to set the url.
**Note:** This needs to be done again after every update.
(If you have a good idea for a better solution than this, we'd love to [hear it](https://vikunja.io/contact/))
## Docker
The docker image is based on nginx and just contains all nessecary files for the frontend.
To run it, all you need is
{{< highlight bash >}}
docker run -p 80:80 vikunja/frontend
{{< /highlight >}}
which will run the docker image and expose port 80 on the host.
See [full docker example]({{< ref "full-docker-example.md">}}) for more varations of this config.
### API URL configuration in docker
When running the frontend with docker, it is possible to set the environment variable `$VIKUNJA_API_URL` to the api url.
It is therefore not needed to change the url manually inside the docker container.
## NGINX
Below are two example configurations which you can put in your `nginx.conf`:
You may need to adjust `server_name` and `root` accordingly.
After configuring them, you need to reload nginx (`service nginx reload`).
### with gzip enabled (recommended)
{{< highlight conf >}}
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml;
server {
listen 80;
server_name localhost;
location / {
root /path/to/vikunja/static/frontend/files;
try_files $uri $uri/ /;
index index.html index.htm;
}
}
{{< /highlight >}}
### without gzip
{{< highlight conf >}}
server {
listen 80;
server_name localhost;
location / {
root /path/to/vikunja/static/frontend/files;
try_files $uri $uri/ /;
index index.html index.htm;
}
}
{{< /highlight >}}
## Apache
Apache needs to have `mod_rewrite` enabled for this to work properly:
{{< highlight bash >}}
a2enmod rewrite
service apache2 restart
{{< /highlight >}}
Put the following config in `cat /etc/apache2/sites-available/vikunja.conf`:
{{< highlight aconf >}}
<VirtualHost *:80>
ServerName localhost
DocumentRoot /path/to/vikunja/static/frontend/files
RewriteEngine On
RewriteRule ^\/?(config\.json|favicon\.ico|css|fonts|images|img|js) - [L]
RewriteRule ^(.*)$ /index.html [QSA,L]
</VirtualHost>
{{< /highlight >}}
You probably want to adjust `ServerName` and `DocumentRoot`.
Once you've customized your config, you need to enable it:
{{< highlight bash >}}
a2ensite vikunja
service apache2 reload
{{< /highlight >}}
## Updating
To update, it should be enough to download the new files and overwrite the old ones.
The paths contain hashes, so all caches are invalidated automatically.
+40
View File
@@ -0,0 +1,40 @@
---
date: "2019-02-12:00:00+02:00"
title: "Installing"
draft: false
type: "doc"
menu:
sidebar:
parent: "setup"
weight: 10
---
# Installing
Vikunja consists of two parts: [Backend](https://code.vikunja.io/api) and [frontend](https://code.vikunja.io/frontend).
While the backend is required, the frontend is not.
You don't neccesarily need to have a web-frontend, using Vikunja via the [mobile app](https://code.vikunja.io/app) is totally fine.
However, using the web frontend is highly reccommended.
Vikunja can be installed in various forms.
This document provides an overview and instructions for the different methods.
* [Backend]({{< ref "install-backend.md">}})
* [Installing from binary]({{< ref "install-backend.md#install-from-binary">}})
* [Verify the GPG signature]({{< ref "install-backend.md#verify-the-gpg-signature">}})
* [Set it up]({{< ref "install-backend.md#set-it-up">}})
* [Systemd service]({{< ref "install-backend.md#systemd-service">}})
* [Updating]({{< ref "install-backend.md#updating">}})
* [Build from source]({{< ref "install-backend.md#build-from-source">}})
* [Docker]({{< ref "install-backend.md#docker">}})
* [Debian packages]({{< ref "install-backend.md#debian-packages">}})
* [Configuration]({{< ref "config.md">}})
* [Frontend]({{< ref "install-frontend.md">}})
* [Docker]({{< ref "install-frontend.md#docker">}})
* [NGINX]({{< ref "install-frontend.md#nginx">}})
* [Apache]({{< ref "install-frontend.md#apache">}})
* [Updating]({{< ref "install-frontend.md#updating">}})
* [Reverse proxies]({{< ref "reverse-proxies.md">}})
* [Full docker example]({{< ref "full-docker-example.md">}})
* [Backups]({{< ref "backups.md">}})
+95
View File
@@ -0,0 +1,95 @@
---
date: "2019-02-12:00:00+02:00"
title: "Reverse Proxy"
draft: false
type: "doc"
menu:
sidebar:
parent: "setup"
---
# Setup behind a reverse proxy which also serves the frontend
These examples assume you have an instance of the backend running on your server listening on port `3456`.
If you've changed this setting, you need to update the server configurations accordingly.
## NGINX
Below are two example configurations which you can put in your `nginx.conf`:
You may need to adjust `server_name` and `root` accordingly.
### with gzip enabled (recommended)
{{< highlight conf >}}
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml;
server {
listen 80;
server_name localhost;
location / {
root /path/to/vikunja/static/frontend/files;
try_files $uri $uri/ /;
index index.html index.htm;
}
location /api/ {
proxy_pass http://localhost:3456;
}
}
{{< /highlight >}}
### without gzip
{{< highlight conf >}}
server {
listen 80;
server_name localhost;
location / {
root /path/to/vikunja/static/frontend/files;
try_files $uri $uri/ /;
index index.html index.htm;
}
location /api/ {
proxy_pass http://localhost:3456;
}
}
{{< /highlight >}}
## Apache
Put the following config in `cat /etc/apache2/sites-available/vikunja.conf`:
{{< highlight aconf >}}
<VirtualHost *:80>
ServerName localhost
<Proxy *>
Order Deny,Allow
Allow from all
</Proxy>
ProxyPass /api http://localhost:3456/api
ProxyPassReverse /api http://localhost:3456/api
DocumentRoot /var/www/html
RewriteEngine On
RewriteRule ^\/?(config\.json|favicon\.ico|css|fonts|images|img|js|api) - [L]
RewriteRule ^(.*)$ /index.html [QSA,L]
</VirtualHost>
{{< /highlight >}}
**Note:** The apache modules `proxy` and `proxy_http` must be enabled for this.
For more details see the [frontend apache configuration]({{< ref "install-frontend.md#apache">}}).
+19
View File
@@ -0,0 +1,19 @@
---
date: "2019-02-12:00:00+02:00"
title: "API Documentation"
draft: false
type: "doc"
menu:
sidebar:
parent: "usage"
---
# API Documentation
You can find the api docs under `http://vikunja.tld/api/v1/docs` of your instance.
A public instance is available on [try.vikunja.io](http://try.vikunja.io/api/v1/docs).
These docs are autgenerated from annotations in the code with swagger.
The specification is hosted at `http://vikunja.tld/api/v1/docs.json`.
You can use this to embed it into other openapi compatible applications if you want.
+140
View File
@@ -0,0 +1,140 @@
---
date: "2019-05-12:00:00+01:00"
title: "Caldav"
draft: false
type: "doc"
menu:
sidebar:
parent: "usage"
---
# Caldav
> **Warning:** The caldav integration is in an early alpha stage and has bugs.
> It works well with some clients while having issues with others.
> If you encounter issues, please [report them](https://code.vikunja.io/api/issues/new?body=[caldav])
Vikunja supports managing tasks via the [caldav VTODO](https://tools.ietf.org/html/rfc5545#section-3.6.2) extension.
## URLs
All urls are located under the `/dav` subspace.
Urls are:
* `/principals/<username>/`: Returns urls for list discovery. *Use this url to initially make connections to new clients.*
* `/lists/`: Used to manage lists
* `/lists/<List ID>/`: Used to manage a single list
* `/lists/<List ID>/<Task UID>`: Used to manage a task on a list
## Supported properties
Vikunja currently supports the following properties:
* `UID`
* `SUMMARY`
* `DESCRIPTION`
* `PRIORITY`
* `COMPLETED`
* `DUE`
* `DTSTART`
* `DURATION`
* `ORGANIZER`
* `RELATED-TO`
* `CREATED`
* `DTSTAMP`
* `LAST-MODIFIED`
Vikunja **currently does not** support these properties:
* `ATTACH`
* `CATEGORIES`
* `CLASS`
* `COMMENT`
* `GEO`
* `LOCATION`
* `PERCENT-COMPLETE`
* `RESOURCES`
* `STATUS`
* `CONTACT`
* `RECURRENCE-ID`
* `URL`
* Recurrence
* `SEQUENCE`
## Tested Clients
#### Working
* [Evolution](https://wiki.gnome.org/Apps/Evolution/)
#### Not working
* [Tasks (Android)](https://tasks.org/)
## Dev logs
The whole thing is not optimized at all and probably pretty inefficent.
Request body and headers are logged if the debug output is enabled.
```
Creating a new task:
PUT /dav/lists/1/cd4dd0e1b3c19cc9d787829b6e08be536e3df3a4.ics
Body:
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
VERSION:2.0
BEGIN:VTODO
UID:cd4dd0e1b3c19cc9d787829b6e08be536e3df3a4
DTSTAMP:20190508T134538Z
SUMMARY:test2000
PRIORITY:0
CLASS:PUBLIC
CREATED:20190508T134710Z
LAST-MODIFIED:20190508T134710Z
END:VTODO
END:VCALENDAR
Marking a task as done:
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
VERSION:2.0
BEGIN:VTODO
UID:3ada92f28b4ceda38562ebf047c6ff05400d4c572352a
DTSTAMP:20190511T183631
DTSTART:19700101T000000
DTEND:19700101T000000
SUMMARY:sdgs
ORGANIZER;CN=:user
CREATED:20190511T183631
PRIORITY:0
LAST-MODIFIED:20190512T193428Z
COMPLETED:20190512T193428Z
PERCENT-COMPLETE:100
STATUS:COMPLETED
END:VTODO
END:VCALENDAR
Requests from the app:::
[CALDAV] Request Body: <?xml version="1.0" encoding="UTF-8" ?><propfind xmlns="DAV:" xmlns:CAL="urn:ietf:params:xml:ns:caldav" xmlns:CARD="urn:ietf:params:xml:ns:carddav"><prop><current-user-principal /></prop></propfind>
[CALDAV] GetResources: rpath: /dav/
2019-05-18T23:25:49.971140654+02:00: WEB ▶ 192.168.1.134 PROPFIND 207 /dav/ 1.021705664s - okhttp/3.12.2
[CALDAV] Request Body: <?xml version="1.0" encoding="UTF-8" ?><propfind xmlns="DAV:" xmlns:CAL="urn:ietf:params:xml:ns:caldav" xmlns:CARD="urn:ietf:params:xml:ns:carddav"><prop><CAL:calendar-home-set /></prop></propfind>
[CALDAV] GetResources: rpath: /dav/
2019-05-18T23:25:52.166996113+02:00: WEB ▶ 192.168.1.134 PROPFIND 207 /dav/ 1.042834467s - okhttp/3.12.2
And then it just stops.
... and complains about not being able to find the home set
... without even requesting it...
```
+84
View File
@@ -0,0 +1,84 @@
---
date: "2019-03-31:00:00+01:00"
title: "CLI"
draft: false
type: "doc"
menu:
sidebar:
parent: "usage"
---
# Command line interface
You can interact with Vikunja using its `cli` interface.
The following commands are available:
* [help](#help)
* [migrate](#migrate)
* [version](#version)
* [web](#web)
If you don't specify a command, the [`web`](#web) command will be executed.
All commands use the same standard [config file]({{< ref "../setup/config.md">}}).
### `help`
Shows more detailed help about any command.
Usage:
{{< highlight bash >}}
$ vikunja help [command]
{{< /highlight >}}
### `migrate`
Run all database migrations which didn't already run.
Usage:
{{< highlight bash >}}
$ vikunja migrate [flags]
$ vikunja migrate [command]
{{< /highlight >}}
#### `migrate list`
Shows a list with all database migrations.
Usage:
{{< highlight bash >}}
$ vikunja migrate list
{{< /highlight >}}
#### `migrate rollback`
Roll migrations back until a certain point.
Usage:
{{< highlight bash >}}
$ vikunja migrate rollback [flags]
{{< /highlight >}}
Flags:
* `-n`, `--name` string: The id of the migration you want to roll back until.
### `version`
Prints the version of Vikunja.
This is either the semantic version (something like `0.7`) or version + git commit hash.
Usage:
{{< highlight bash >}}
$ vikunja version
{{< /highlight >}}
### `web`
Starts Vikunja's REST api server.
Usage:
{{< highlight bash >}}
$ vikunja web
{{< /highlight >}}
+132
View File
@@ -0,0 +1,132 @@
---
date: "2019-02-12:00:00+02:00"
title: "Errors"
draft: false
type: "doc"
menu:
sidebar:
parent: "usage"
---
# Errors
This document describes the different errors Vikunja can return.
### Generic
| 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. |
### 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. |
### 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. |
### 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. |
### 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. |
### 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. |
### 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. |
### 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. |
+25
View File
@@ -0,0 +1,25 @@
---
date: "2019-09-25:00:00+02:00"
title: "Task Relation kinds"
draft: false
type: "doc"
menu:
sidebar:
parent: "usage"
---
# Available task relation kinds
| Code | Description |
|------|-------------|
| subtask | Task is a subtask of the other task. This is the opposite of `parenttask`. |
| parenttask | Task is a parent task of the other task. This is the opposite of `subtask`. |
| related | Both tasks are related to each other. How is not more specified. |
| duplicateof | Task is a duplicate of the other task. This is the opposite of `duplicates`. |
| duplicates | Task duplicates the other task. This is the opposite of `duplicateof`. |
| blocking | Task is blocking the other task. This is the opposite of `blocked`. |
| blocked | Task is blocked by the other task. This is the opposite of `blocking`. |
| precedes | Task precedes the other task. This is the opposite of `follows`. |
| follows | Task follows the other task. This is the opposite of `precedes`. |
| copiedfrom | Task is copied from the other task. This is the opposite of `copiedto`. |
| copiedto | Task is copied to the other task. This is the opposite of `copiedfrom`. |
+29
View File
@@ -0,0 +1,29 @@
---
date: "2019-02-12:00:00+02:00"
title: "Rights"
draft: false
type: "doc"
menu:
sidebar:
parent: "usage"
---
# List and namespace rights for teams and users
Whenever you share a list or namespace with a user or team, you can specify a `rights` parameter.
This parameter controls the rights that team or user is going to have (or has, if you request the current sharing status).
Rights are being specified using integers.
The following values are possible:
| Right (int) | Meaning |
|-------------|---------|
| 0 (Default) | Read only. Anything which is shared with this right cannot be edited. |
| 1 | Read and write. Namespaces or lists shared with this right can be read and written to by the team or user. |
| 2 | Admin. Can do anything like read and write, but can additionally manage sharing options. |
### Team admins
When adding or querying a team, every member has an additional boolean value stating if it is admin or not.
A team admin can also add and remove team members and also change whether a user in the team is admin or not.
+21
View File
@@ -0,0 +1,21 @@
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 404 /docs/404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /docs/contact {
return 301 $scheme://vikunja.io/en/contact;
}
}
Vendored Submodule
+1
Submodule docs/themes/vikunja added at 88977f461b
+94
View File
@@ -0,0 +1,94 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
module code.vikunja.io/api
require (
4d63.com/embedfiles v1.0.0 // indirect
4d63.com/tz v1.1.0
code.vikunja.io/web v0.0.0-20200208214421-c90649369427
gitea.com/xorm/xorm-redis-cache v0.2.0
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
github.com/beevik/etree v1.1.0 // indirect
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee
github.com/client9/misspell v0.3.4
github.com/cweill/gotests v1.5.3
github.com/d4l3k/messagediff v1.2.1 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
github.com/go-openapi/jsonreference v0.19.3 // indirect
github.com/go-openapi/spec v0.19.4 // indirect
github.com/go-redis/redis/v7 v7.2.0
github.com/go-sql-driver/mysql v1.5.0
github.com/go-testfixtures/testfixtures/v3 v3.2.0
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334
github.com/imdario/mergo v0.3.9
github.com/jgautheron/goconst v0.0.0-20200227150835-cda7ea3bf591
github.com/kr/text v0.2.0 // indirect
github.com/labstack/echo/v4 v4.1.16
github.com/labstack/gommon v0.3.0
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef
github.com/lib/pq v1.5.2
github.com/mailru/easyjson v0.7.0 // indirect
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/olekukonko/tablewriter v0.0.4
github.com/onsi/ginkgo v1.12.0 // indirect
github.com/onsi/gomega v1.9.0 // indirect
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/pelletier/go-toml v1.4.0 // indirect
github.com/pquerna/otp v1.2.0
github.com/prometheus/client_golang v1.6.0
github.com/samedi/caldav-go v3.0.0+incompatible
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
github.com/spf13/afero v1.2.2
github.com/spf13/cobra v0.0.7
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.7.0
github.com/stretchr/testify v1.5.1
github.com/swaggo/swag v1.6.3
github.com/ulule/limiter/v3 v3.5.0
github.com/urfave/cli v1.22.2 // indirect
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/d4l3k/messagediff.v1 v1.2.1
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
honnef.co/go/tools v0.0.1-2019.2.3
src.techknowlogick.com/xgo v0.0.0-20200408234745-bb0faa361273
src.techknowlogick.com/xormigrate v1.2.0
xorm.io/builder v0.3.7
xorm.io/core v0.7.3
xorm.io/xorm v1.0.1
)
replace (
github.com/coreos/bbolt => go.etcd.io/bbolt v1.3.4
github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0
github.com/hpcloud/tail => github.com/jeffbean/tail v1.0.1 // See https://github.com/hpcloud/tail/pull/159
github.com/samedi/caldav-go => github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible // Branch: feature/dynamic-supported-components, PR: https://github.com/samedi/caldav-go/pull/6 and https://github.com/samedi/caldav-go/pull/7
gopkg.in/fsnotify.v1 => github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048 // See https://github.com/fsnotify/fsnotify/issues/328 and https://github.com/golang/go/issues/26904
)
go 1.13
+789
View File
@@ -0,0 +1,789 @@
4d63.com/embedfiles v0.0.0-20190311033909-995e0740726f h1:oyYjGRBNq1TxAIG8aHqtxlvqUfzdZf+MbcRb/oweNfY=
4d63.com/embedfiles v0.0.0-20190311033909-995e0740726f/go.mod h1:HxEsUxoVZyRxsZML/S6e2xAuieFMlGO0756ncWx1aXE=
4d63.com/embedfiles v1.0.0 h1:AR4j5WItSJwBX9SapkvmQUGLPlgCHQZaCDQ52zLXzZM=
4d63.com/embedfiles v1.0.0/go.mod h1:U0e+fedkrGPVJiU29PWZQ7pHHZRPiQAzwDJocZ4d3PE=
4d63.com/tz v1.1.0 h1:Hi58WbeFjiUH4XOWuCpl5iSzuUuw1axZzTqIfMKPKrg=
4d63.com/tz v1.1.0/go.mod h1:SHGqVdL7hd2ZaX2T9uEiOZ/OFAUfCCLURdLPJsd8ZNs=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
code.vikunja.io/web v0.0.0-20200208214421-c90649369427 h1:6ps5r0OxZNRdmCavh1k/xMwftN27hHauo+EtdTGxLug=
code.vikunja.io/web v0.0.0-20200208214421-c90649369427/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
gitea.com/xorm/tests v0.7.0 h1:pFcaxTGGAWw3rDuVfhBdyr+mX1uzdTtncyAKxkCQ/IE=
gitea.com/xorm/tests v0.7.0/go.mod h1:ngmhQrSBgihBbOqw1hdReSQJAnTlbStYTn0vruUFwDc=
gitea.com/xorm/xorm-redis-cache v0.2.0 h1:qglRHt6/7vJmDeld6j+n10M9PmruAh+Le2lgNraFu3g=
gitea.com/xorm/xorm-redis-cache v0.2.0/go.mod h1:juYdjkmIKvLbPkdfBVKGVJ2daFQIJAgKsn4mL4ZK8Zk=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee h1:BnPxIde0gjtTnc9Er7cxvBk8DHLWhEux0SxayC8dP6I=
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cweill/gotests v1.5.3 h1:k3t4wW/x/YNixWZJhUIn+mivmK5iV1tJVOwVYkx0UcU=
github.com/cweill/gotests v1.5.3/go.mod h1:XZYOJkGVkCRoymaIzmp9Wyi3rUgfA3oOnkuljYrjFV8=
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADGYw5LqMnHqSkyIELsHCGF6PkrmM31V8rF7o=
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e h1:LzwWXEScfcTu7vUZNlDDWDARoSGEtvlDKK2BYHowNeE=
github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835 h1:roDmqJ4Qes7hrDOsWsMCce0vQHz3xiMPjJ9m4c2eeNs=
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835/go.mod h1:BjL/N0+C+j9uNX+1xcNuM9vdSIcXCZrQZUYbXOFbgN8=
github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc=
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4=
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-redis/redis/v7 v7.2.0 h1:CrCexy/jYWZjW0AyVoHlcJUeZN19VWlbepTh1Vq6dJs=
github.com/go-redis/redis/v7 v7.2.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-testfixtures/testfixtures/v3 v3.1.1 h1:SBIfzULODQQ7JV6AD931MvAz8pnkk6QCfMIcoOBDaXQ=
github.com/go-testfixtures/testfixtures/v3 v3.1.1/go.mod h1:RZctY24ixituGC73XlAV1gkCwYMVwiSwPm26MNlQIhE=
github.com/go-testfixtures/testfixtures/v3 v3.1.2 h1:sACIJoknTtWHbz5wahA6f50IGsz7oBXS+jgm0eKl4eI=
github.com/go-testfixtures/testfixtures/v3 v3.1.2/go.mod h1:RZctY24ixituGC73XlAV1gkCwYMVwiSwPm26MNlQIhE=
github.com/go-testfixtures/testfixtures/v3 v3.2.0 h1:FGAW3z5UzmrZGjR/dZp1u3Tbld0SDmirLO4RrR5++7Q=
github.com/go-testfixtures/testfixtures/v3 v3.2.0/go.mod h1:RZctY24ixituGC73XlAV1gkCwYMVwiSwPm26MNlQIhE=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf h1:vc7Dmrk4JwS0ZPS6WZvWlwDflgDTA26jItmbSj83nug=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 h1:VHgatEHNcBFEB7inlalqfNqw65aNkM1lGX2yt3NmbS8=
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
github.com/jeffbean/tail v1.0.1 h1:mRuCwa9iq5kH1SBFAIWWFsg+NEi5+VVEf2E2ORVkKp8=
github.com/jeffbean/tail v1.0.1/go.mod h1:+MhJ+VPZMpv8Ui6WRzpJFuWFKxBCZgVOo5HAmlw1sFc=
github.com/jgautheron/goconst v0.0.0-20200227150835-cda7ea3bf591 h1:x/BpEhm6aL26o4TLtcU0loJ7B3+69jielrGc70V7Yb4=
github.com/jgautheron/goconst v0.0.0-20200227150835-cda7ea3bf591/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.6/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible h1:PkEEpmbrFXlMul8cOplR8nkcIM/NDbx+H6fq2+vaKAA=
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible/go.mod h1:y1UhTNI4g0hVymJrI6yJ5/ohy09hNBeU8iJEZjgdDOw=
github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048 h1:j/BtLkVyqtAXvlb22nic/pSlWLuGx4gddouWVt65HDI=
github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048/go.mod h1:dv6KyzAg9UuJWiE1pwkvvB2i0TvcQM6QhdsXLZ7K5KI=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f h1:fNJtR+TNyxTdYCZU40fc8Or8RyBqMOKYNv+Zay5gjvk=
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f/go.mod h1:kU/7PwzgNxZH4das4XNsSpBSOD09XIF5YEPzjpkGnGE=
github.com/labstack/echo/v4 v4.1.16 h1:8swiwjE5Jkai3RPfZoahp8kjVCRNq+y7Q0hPji2Kz0o=
github.com/labstack/echo/v4 v4.1.16/go.mod h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI=
github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef h1:RZnRnSID1skF35j/15KJ6hKZkdIC/teQClJK5wP5LU4=
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef/go.mod h1:4LATl0uhhtytR6p9n1AlktDyIz4u2iUnWEdI3L/hXiw=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.4.0 h1:TmtCFbH+Aw0AixwyttznSMQDgbR5Yed/Gg6S8Funrhc=
github.com/lib/pq v1.4.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.5.0 h1:Hq6pEflc2Q3hP5iEH3Q6XopXrJXxjhwbvMpj9eZnpp0=
github.com/lib/pq v1.5.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.5.1 h1:Jn6HYxiYrtQ92CopqJLvfPCJUrrruw1+1cn0jM9dKrI=
github.com/lib/pq v1.5.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.5.2 h1:yTSXVswvWUOQ3k1sd7vJfDrbSl8lKuscqFJRqjC0ifw=
github.com/lib/pq v1.5.2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-oci8 v0.0.0-20191108001511-cbd8d5bc1da0/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shopspring/decimal v0.0.0-20191009025716-f1972eb1d1f5/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.7 h1:FfTH+vuMXOas8jmfb5/M7dzEYx7LpcLb7a0LPe34uOU=
github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.6.3 h1:pDDu1OyEDTKzpJwdq4TiuLyMsUgRa/BT5cn5O62NoHs=
github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw=
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
github.com/swaggo/swag v1.6.3 h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI=
github.com/swaggo/swag v1.6.3/go.mod h1:wcc83tB4Mb2aNiL/HP4MFeQdpHUrca+Rp/DRNgWAUio=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ulule/limiter/v3 v3.5.0 h1:QRAebbswjlezHIfiSQgM8+jMxaz/zsrxGRuiUJ43MHo=
github.com/ulule/limiter/v3 v3.5.0/go.mod h1:TgOUQZKZ2KHjemqrC8UHUbKPqpTmSY43/2wbQ7YN1h8=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y=
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200420192832-a76a400e3025 h1:U821GPBRQKVHpr6Os5UDBgF2FveIjlZYbz+e2n5wmmQ=
golang.org/x/crypto v0.0.0-20200420192832-a76a400e3025/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a h1:y6sBfNd1b9Wy08a6K1Z1DZc4aXABUN5TKjkYhz7UKmo=
golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200422194213-44a606286825 h1:dSChiwOTvzwbHFTMq2l6uRardHH7/E6SqEkqccinS/o=
golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5 h1:Q7tZBpemrlsc2I7IyODzhtallWRSm4Q0d09pL6XbQtU=
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc h1:ZGI/fILM2+ueot/UixBSoj9188jCAxVHEZEGhqq67I4=
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU=
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e h1:ZlQjfVdpDxeqxRfmO30CdqWWzTvgRCj0MxaUVfxEG1k=
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 h1:EBZoQjiKKPaLbPrbpssUfuHtwM6KV/vb4U85g/cigFY=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef h1:RHORRhs540cYZYrzgU2CPUyykkwZM78hGdzocOo9P8A=
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw=
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/d4l3k/messagediff.v1 v1.2.1 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0=
gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
src.techknowlogick.com/xgo v0.0.0-20200408234745-bb0faa361273 h1:dE6ry9rVwDn3soD4wPCXqEG60AZTuhniZzHdnj3c+74=
src.techknowlogick.com/xgo v0.0.0-20200408234745-bb0faa361273/go.mod h1:31CE1YKtDOrKTk9PSnjTpe6YbO6W/0LTYZ1VskL09oU=
src.techknowlogick.com/xormigrate v1.2.0 h1:bq9JaI48bxB+OddMghicjmV7sGmBUogJq4HmTN0DOcw=
src.techknowlogick.com/xormigrate v1.2.0/go.mod h1:7so27LAfBRqAxbma5jKYeL4ykVG1Jhsv9ncSq1KBCs4=
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/core v0.7.3 h1:W8ws1PlrnkS1CZU1YWaYLMQcQilwAmQXU0BJDJon+H0=
xorm.io/core v0.7.3/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
xorm.io/xorm v1.0.1 h1:/lITxpJtkZauNpdzj+L9CN/3OQxZaABrbergMcJu+Cw=
xorm.io/xorm v1.0.1/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY=
+23
View File
@@ -0,0 +1,23 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package main
import "code.vikunja.io/api/pkg/cmd"
func main() {
cmd.Execute()
}
-68
View File
@@ -1,68 +0,0 @@
const {app, BrowserWindow, shell} = require('electron')
const path = require('path')
const express = require('express')
const eApp = express()
const portInUse = require('./portInUse.js')
const frontendPath = 'frontend/'
function createWindow() {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 1680,
height: 960,
webPreferences: {
nodeIntegration: true,
}
})
// Open external links in the browser
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
shell.openExternal(url);
return { action: 'deny' };
});
// Hide the toolbar
mainWindow.setMenuBarVisibility(false)
// We try to use the same port every time and only use a different one if that does not succeed.
let port = 45735
portInUse(port, used => {
if(used) {
console.log(`Port ${port} already used, switching to a random one`)
port = 0 // This lets express choose a random port
}
// Start a local express server to serve static files
eApp.use(express.static(path.join(__dirname, frontendPath)))
// Handle urls set by the frontend
eApp.get('*', (request, response, next) => {
response.sendFile(`${__dirname}/${frontendPath}index.html`);
})
const server = eApp.listen(port, '127.0.0.1', () => {
console.log(`Server started on port ${server.address().port}`)
mainWindow.loadURL(`http://127.0.0.1:${server.address().port}`)
})
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
-61
View File
@@ -1,61 +0,0 @@
{
"name": "vikunja-desktop",
"version": "0.21.0",
"description": "Vikunja's frontend as a standalone desktop application.",
"main": "main.js",
"repository": "https://code.vikunja.io/desktop",
"license": "GPL-3.0-or-later",
"author": {
"email": "maintainers@vikunja.io",
"name": "Vikunja Team"
},
"homepage": "https://vikunja.io",
"scripts": {
"start": "electron .",
"pack": "electron-builder --dir",
"dist": "electron-builder"
},
"build": {
"appId": "io.vikunja.desktop",
"productName": "Vikunja Desktop",
"artifactName": "${productName}-${version}.${ext}",
"icon": "build/icon.icns",
"linux": {
"target": [
"deb",
"AppImage",
"snap",
"pacman",
"apk",
"freebsd",
"rpm",
"zip",
"tar.gz"
],
"category": "Productivity"
},
"win": {
"target": [
"nsis",
"portable",
"msi",
"zip"
]
},
"mac": {
"category": "public.app-category.productivity",
"target": [
"dmg",
"zip"
]
}
},
"devDependencies": {
"electron": "25.2.0",
"electron-builder": "24.4.0"
},
"dependencies": {
"connect-history-api-fallback": "^2.0.0",
"express": "^4.17.1"
}
}
+219
View File
@@ -0,0 +1,219 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package caldav
import (
"code.vikunja.io/api/pkg/timeutil"
"code.vikunja.io/api/pkg/user"
"code.vikunja.io/api/pkg/utils"
"fmt"
"strconv"
"time"
)
// DateFormat ist the caldav date format
const DateFormat = `20060102T150405`
// Event holds a single caldav event
type Event struct {
Summary string
Description string
UID string
Alarms []Alarm
Timestamp timeutil.TimeStamp
Start timeutil.TimeStamp
End timeutil.TimeStamp
}
// Todo holds a single VTODO
type Todo struct {
// Required
Timestamp timeutil.TimeStamp
UID string
// Optional
Summary string
Description string
Completed timeutil.TimeStamp
Organizer *user.User
Priority int64 // 0-9, 1 is highest
RelatedToUID string
Start timeutil.TimeStamp
End timeutil.TimeStamp
DueDate timeutil.TimeStamp
Duration time.Duration
Created timeutil.TimeStamp
Updated timeutil.TimeStamp // last-mod
}
// Alarm holds infos about an alarm from a caldav event
type Alarm struct {
Time timeutil.TimeStamp
Description string
}
// Config is the caldav calendar config
type Config struct {
Name string
ProdID string
}
// ParseEvents parses an array of caldav events and gives them back as string
func ParseEvents(config *Config, events []*Event) (caldavevents string) {
caldavevents += `BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
X-PUBLISHED-TTL:PT4H
X-WR-CALNAME:` + config.Name + `
PRODID:-//` + config.ProdID + `//EN`
for _, e := range events {
if e.UID == "" {
e.UID = makeCalDavTimeFromTimeStamp(e.Timestamp) + utils.Sha256(e.Summary)
}
caldavevents += `
BEGIN:VEVENT
UID:` + e.UID + `
SUMMARY:` + e.Summary + `
DESCRIPTION:` + e.Description + `
DTSTAMP:` + makeCalDavTimeFromTimeStamp(e.Timestamp) + `
DTSTART:` + makeCalDavTimeFromTimeStamp(e.Start) + `
DTEND:` + makeCalDavTimeFromTimeStamp(e.End)
for _, a := range e.Alarms {
if a.Description == "" {
a.Description = e.Summary
}
caldavevents += `
BEGIN:VALARM
TRIGGER:` + calcAlarmDateFromReminder(e.Start, a.Time) + `
ACTION:DISPLAY
DESCRIPTION:` + a.Description + `
END:VALARM`
}
caldavevents += `
END:VEVENT`
}
caldavevents += `
END:VCALENDAR` // Need a line break
return
}
// ParseTodos returns a caldav vcalendar string with todos
func ParseTodos(config *Config, todos []*Todo) (caldavtodos string) {
caldavtodos = `BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
X-PUBLISHED-TTL:PT4H
X-WR-CALNAME:` + config.Name + `
PRODID:-//` + config.ProdID + `//EN`
for _, t := range todos {
if t.UID == "" {
t.UID = makeCalDavTimeFromTimeStamp(t.Timestamp) + utils.Sha256(t.Summary)
}
caldavtodos += `
BEGIN:VTODO
UID:` + t.UID + `
DTSTAMP:` + makeCalDavTimeFromTimeStamp(t.Timestamp) + `
SUMMARY:` + t.Summary
if t.Start != 0 {
caldavtodos += `
DTSTART: ` + makeCalDavTimeFromTimeStamp(t.Start)
}
if t.End != 0 {
caldavtodos += `
DTEND: ` + makeCalDavTimeFromTimeStamp(t.End)
}
if t.Description != "" {
caldavtodos += `
DESCRIPTION:` + t.Description
}
if t.Completed != 0 {
caldavtodos += `
COMPLETED: ` + makeCalDavTimeFromTimeStamp(t.Completed)
}
if t.Organizer != nil {
caldavtodos += `
ORGANIZER;CN=:` + t.Organizer.Username
}
if t.RelatedToUID != "" {
caldavtodos += `
RELATED-TO:` + t.RelatedToUID
}
if t.DueDate != 0 {
caldavtodos += `
DUE:` + makeCalDavTimeFromTimeStamp(t.DueDate)
}
if t.Created != 0 {
caldavtodos += `
CREATED:` + makeCalDavTimeFromTimeStamp(t.Created)
}
if t.Duration != 0 {
caldavtodos += `
DURATION:PT` + fmt.Sprintf("%.6f", t.Duration.Hours()) + `H` + fmt.Sprintf("%.6f", t.Duration.Minutes()) + `M` + fmt.Sprintf("%.6f", t.Duration.Seconds()) + `S`
}
if t.Priority != 0 {
caldavtodos += `
PRIORITY:` + strconv.Itoa(int(t.Priority))
}
caldavtodos += `
LAST-MODIFIED:` + makeCalDavTimeFromTimeStamp(t.Updated)
caldavtodos += `
END:VTODO`
}
caldavtodos += `
END:VCALENDAR` // Need a line break
return
}
func makeCalDavTimeFromTimeStamp(ts timeutil.TimeStamp) (caldavtime string) {
tz, _ := time.LoadLocation("UTC")
return ts.ToTime().In(tz).Format(DateFormat)
}
func calcAlarmDateFromReminder(eventStartUnix, reminderUnix timeutil.TimeStamp) (alarmTime string) {
if eventStartUnix > reminderUnix {
alarmTime += `-`
}
alarmTime += `PT`
diff := eventStartUnix - reminderUnix
if diff < 0 { // Make it positive
diff = diff * -1
}
alarmTime += strconv.Itoa(int(diff/60)) + "M"
return
}
+246
View File
@@ -0,0 +1,246 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package caldav
import "testing"
func TestParseEvents(t *testing.T) {
type args struct {
config *Config
events []*Event
}
tests := []struct {
name string
args args
wantCaldavevents string
}{
{
name: "Test caldavparsing without reminders",
args: args{
config: &Config{
Name: "test",
ProdID: "RandomProdID which is not random",
},
events: []*Event{
{
Summary: "Event #1",
Description: "Lorem Ipsum",
UID: "randommduid",
Timestamp: 1543626724,
Start: 1543626724,
End: 1543627824,
},
{
Summary: "Event #2",
UID: "randommduidd",
Timestamp: 1543726724,
Start: 1543726724,
End: 1543738724,
},
{
Summary: "Event #3 with empty uid",
UID: "20181202T0600242aaef4a81d770c1e775e26bc5abebc87f1d3d7bffaa83",
Timestamp: 1543726824,
Start: 1543726824,
End: 1543727000,
},
},
},
wantCaldavevents: `BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
X-PUBLISHED-TTL:PT4H
X-WR-CALNAME:test
PRODID:-//RandomProdID which is not random//EN
BEGIN:VEVENT
UID:randommduid
SUMMARY:Event #1
DESCRIPTION:Lorem Ipsum
DTSTAMP:20181201T011204
DTSTART:20181201T011204
DTEND:20181201T013024
END:VEVENT
BEGIN:VEVENT
UID:randommduidd
SUMMARY:Event #2
DESCRIPTION:
DTSTAMP:20181202T045844
DTSTART:20181202T045844
DTEND:20181202T081844
END:VEVENT
BEGIN:VEVENT
UID:20181202T0600242aaef4a81d770c1e775e26bc5abebc87f1d3d7bffaa83
SUMMARY:Event #3 with empty uid
DESCRIPTION:
DTSTAMP:20181202T050024
DTSTART:20181202T050024
DTEND:20181202T050320
END:VEVENT
END:VCALENDAR`,
},
{
name: "Test caldavparsing with reminders",
args: args{
config: &Config{
Name: "test2",
ProdID: "RandomProdID which is not random",
},
events: []*Event{
{
Summary: "Event #1",
Description: "Lorem Ipsum",
UID: "randommduid",
Timestamp: 1543626724,
Start: 1543626724,
End: 1543627824,
Alarms: []Alarm{
{Time: 1543626524},
{Time: 1543626224},
{Time: 1543626024},
},
},
{
Summary: "Event #2",
UID: "randommduidd",
Timestamp: 1543726724,
Start: 1543726724,
End: 1543738724,
Alarms: []Alarm{
{Time: 1543626524},
{Time: 1543626224},
{Time: 1543626024},
},
},
{
Summary: "Event #3 with empty uid",
Timestamp: 1543726824,
Start: 1543726824,
End: 1543727000,
Alarms: []Alarm{
{Time: 1543626524},
{Time: 1543626224},
{Time: 1543626024},
{Time: 1543826824},
},
},
{
Summary: "Event #4 without any",
Timestamp: 1543726824,
Start: 1543726824,
End: 1543727000,
},
},
},
wantCaldavevents: `BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
X-PUBLISHED-TTL:PT4H
X-WR-CALNAME:test2
PRODID:-//RandomProdID which is not random//EN
BEGIN:VEVENT
UID:randommduid
SUMMARY:Event #1
DESCRIPTION:Lorem Ipsum
DTSTAMP:20181201T011204
DTSTART:20181201T011204
DTEND:20181201T013024
BEGIN:VALARM
TRIGGER:-PT3M
ACTION:DISPLAY
DESCRIPTION:Event #1
END:VALARM
BEGIN:VALARM
TRIGGER:-PT8M
ACTION:DISPLAY
DESCRIPTION:Event #1
END:VALARM
BEGIN:VALARM
TRIGGER:-PT11M
ACTION:DISPLAY
DESCRIPTION:Event #1
END:VALARM
END:VEVENT
BEGIN:VEVENT
UID:randommduidd
SUMMARY:Event #2
DESCRIPTION:
DTSTAMP:20181202T045844
DTSTART:20181202T045844
DTEND:20181202T081844
BEGIN:VALARM
TRIGGER:-PT1670M
ACTION:DISPLAY
DESCRIPTION:Event #2
END:VALARM
BEGIN:VALARM
TRIGGER:-PT1675M
ACTION:DISPLAY
DESCRIPTION:Event #2
END:VALARM
BEGIN:VALARM
TRIGGER:-PT1678M
ACTION:DISPLAY
DESCRIPTION:Event #2
END:VALARM
END:VEVENT
BEGIN:VEVENT
UID:20181202T0500242aaef4a81d770c1e775e26bc5abebc87f1d3d7bffaa83
SUMMARY:Event #3 with empty uid
DESCRIPTION:
DTSTAMP:20181202T050024
DTSTART:20181202T050024
DTEND:20181202T050320
BEGIN:VALARM
TRIGGER:-PT1671M
ACTION:DISPLAY
DESCRIPTION:Event #3 with empty uid
END:VALARM
BEGIN:VALARM
TRIGGER:-PT1676M
ACTION:DISPLAY
DESCRIPTION:Event #3 with empty uid
END:VALARM
BEGIN:VALARM
TRIGGER:-PT1680M
ACTION:DISPLAY
DESCRIPTION:Event #3 with empty uid
END:VALARM
BEGIN:VALARM
TRIGGER:PT1666M
ACTION:DISPLAY
DESCRIPTION:Event #3 with empty uid
END:VALARM
END:VEVENT
BEGIN:VEVENT
UID:20181202T050024ae7548ce9556df85038abe90dc674d4741a61ce74d1cf
SUMMARY:Event #4 without any
DESCRIPTION:
DTSTAMP:20181202T050024
DTSTART:20181202T050024
DTEND:20181202T050320
END:VEVENT
END:VCALENDAR`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotCaldavevents := ParseEvents(tt.args.config, tt.args.events); gotCaldavevents != tt.wantCaldavevents {
t.Errorf("ParseEvents() = %v, want %v", gotCaldavevents, tt.wantCaldavevents)
}
})
}
}
+98
View File
@@ -0,0 +1,98 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package cmd
import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/files"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/mail"
"code.vikunja.io/api/pkg/migration"
"code.vikunja.io/api/pkg/models"
migrator "code.vikunja.io/api/pkg/modules/migration"
"code.vikunja.io/api/pkg/red"
"code.vikunja.io/api/pkg/user"
"fmt"
"github.com/spf13/cobra"
"os"
)
func init() {
cobra.OnInitialize(initialize)
}
var rootCmd = &cobra.Command{
Use: "vikunja",
Short: "Vikunja is the to-do app to organize your life.",
Long: `Vikunja (/vɪˈkuːnjə/)
The to-do app to organize your life.
Also one of the two wild South American camelids which live in the high
alpine areas of the Andes and a relative of the llama.
Vikunja is a self-hosted To-Do list application with a web app and mobile apps for all platforms. It is licensed under the GPLv3.
Find more info at vikunja.io.`,
Run: webCmd.Run,
}
// Execute starts the application
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
// Initializes all kinds of things in the right order
func initialize() {
// Init the config
config.InitConfig()
// Init redis
red.InitRedis()
// Set logger
log.InitLogger()
// Run the migrations
migration.Migrate(nil)
// Set Engine
err := models.SetEngine()
if err != nil {
log.Fatal(err.Error())
}
err = user.InitDB()
if err != nil {
log.Fatal(err.Error())
}
err = files.SetEngine()
if err != nil {
log.Fatal(err.Error())
}
err = migrator.InitDB()
if err != nil {
log.Fatal(err.Error())
}
// Initialize the files handler
files.InitFileHandler()
// Start the mail daemon
mail.StartMailDaemon()
}
+59
View File
@@ -0,0 +1,59 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package cmd
import (
"code.vikunja.io/api/pkg/migration"
"github.com/spf13/cobra"
)
func init() {
migrateCmd.AddCommand(migrateListCmd)
migrationRollbackCmd.Flags().StringVarP(&rollbackUntilFlag, "name", "n", "", "The id of the migration you want to roll back until.")
_ = migrationRollbackCmd.MarkFlagRequired("name")
migrateCmd.AddCommand(migrationRollbackCmd)
rootCmd.AddCommand(migrateCmd)
}
// TODO: add args to run migrations up or down, until a certain point etc
// Rollback until
// list -> Essentially just show the table, maybe with an extra column if the migration did run or not
var migrateCmd = &cobra.Command{
Use: "migrate",
Short: "Run all database migrations which didn't already run.",
Run: func(cmd *cobra.Command, args []string) {
migration.Migrate(nil)
},
}
var migrateListCmd = &cobra.Command{
Use: "list",
Short: "Show a list with all database migrations.",
Run: func(cmd *cobra.Command, args []string) {
migration.ListMigrations()
},
}
var rollbackUntilFlag string
var migrationRollbackCmd = &cobra.Command{
Use: "rollback",
Short: "Roll migrations back until a certain point.",
Run: func(cmd *cobra.Command, args []string) {
migration.Rollback(rollbackUntilFlag)
},
}
+36
View File
@@ -0,0 +1,36 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package cmd
import (
"code.vikunja.io/api/pkg/version"
"fmt"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(versionCmd)
}
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of Vikunja",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Vikunja api version %s\n", version.Version)
fmt.Printf("Built at %s\n", version.BuildTime)
},
}
+69
View File
@@ -0,0 +1,69 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package cmd
import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/routes"
"code.vikunja.io/api/pkg/swagger"
"code.vikunja.io/api/pkg/version"
"context"
"github.com/spf13/cobra"
"os"
"os/signal"
"time"
)
func init() {
rootCmd.AddCommand(webCmd)
}
var webCmd = &cobra.Command{
Use: "web",
Short: "Starts the rest api web server",
Run: func(cmd *cobra.Command, args []string) {
// Version notification
log.Infof("Vikunja version %s, built at %s", version.Version, version.BuildTime)
// Additional swagger information
swagger.SwaggerInfo.Version = version.Version
// Start the webserver
e := routes.NewEcho()
routes.RegisterRoutes(e)
// Start server
go func() {
if err := e.Start(config.ServiceInterface.GetString()); err != nil {
e.Logger.Info("shutting down...")
}
}()
// Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 10 seconds.
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
log.Infof("Shutting down...")
if err := e.Shutdown(ctx); err != nil {
e.Logger.Fatal(err)
}
},
}
+284
View File
@@ -0,0 +1,284 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package config
import (
"crypto/rand"
"fmt"
"log"
"os"
"path"
"path/filepath"
"strings"
"time"
"github.com/spf13/viper"
)
// Key is used as a config key
type Key string
// These constants hold all config value keys
const (
// #nosec
ServiceJWTSecret Key = `service.JWTSecret`
ServiceInterface Key = `service.interface`
ServiceFrontendurl Key = `service.frontendurl`
ServiceEnableCaldav Key = `service.enablecaldav`
ServiceRootpath Key = `service.rootpath`
ServiceMaxItemsPerPage Key = `service.maxitemsperpage`
ServiceEnableMetrics Key = `service.enablemetrics`
ServiceMotd Key = `service.motd`
ServiceEnableLinkSharing Key = `service.enablelinksharing`
ServiceEnableRegistration Key = `service.enableregistration`
ServiceEnableTaskAttachments Key = `service.enabletaskattachments`
ServiceTimeZone Key = `service.timezone`
ServiceEnableTaskComments Key = `service.enabletaskcomments`
DatabaseType Key = `database.type`
DatabaseHost Key = `database.host`
DatabaseUser Key = `database.user`
DatabasePassword Key = `database.password`
DatabaseDatabase Key = `database.database`
DatabasePath Key = `database.path`
DatabaseMaxOpenConnections Key = `database.maxopenconnections`
DatabaseMaxIdleConnections Key = `database.maxidleconnections`
DatabaseMaxConnectionLifetime Key = `database.maxconnectionlifetime`
DatabaseSslMode Key = `database.sslmode`
CacheEnabled Key = `cache.enabled`
CacheType Key = `cache.type`
CacheMaxElementSize Key = `cache.maxelementsize`
MailerEnabled Key = `mailer.enabled`
MailerHost Key = `mailer.host`
MailerPort Key = `mailer.port`
MailerUsername Key = `mailer.username`
MailerPassword Key = `mailer.password`
MailerSkipTLSVerify Key = `mailer.skiptlsverify`
MailerFromEmail Key = `mailer.fromemail`
MailerQueuelength Key = `mailer.queuelength`
MailerQueueTimeout Key = `mailer.queuetimeout`
RedisEnabled Key = `redis.enabled`
RedisHost Key = `redis.host`
RedisPassword Key = `redis.password`
RedisDB Key = `redis.db`
LogEnabled Key = `log.enabled`
LogStandard Key = `log.standard`
LogLevel Key = `log.level`
LogDatabase Key = `log.database`
LogDatabaseLevel Key = `log.databaselevel`
LogHTTP Key = `log.http`
LogEcho Key = `log.echo`
LogPath Key = `log.path`
RateLimitEnabled Key = `ratelimit.enabled`
RateLimitKind Key = `ratelimit.kind`
RateLimitPeriod Key = `ratelimit.period`
RateLimitLimit Key = `ratelimit.limit`
RateLimitStore Key = `ratelimit.store`
FilesBasePath Key = `files.basepath`
FilesMaxSize Key = `files.maxsize`
MigrationWunderlistEnable Key = `migration.wunderlist.enable`
MigrationWunderlistClientID Key = `migration.wunderlist.clientid`
MigrationWunderlistClientSecret Key = `migration.wunderlist.clientsecret`
MigrationWunderlistRedirectURL Key = `migration.wunderlist.redirecturl`
CorsEnable Key = `cors.enable`
CorsOrigins Key = `cors.origins`
CorsMaxAge Key = `cors.maxage`
AvatarProvider Key = `avatar.provider`
AvatarGravaterExpiration Key = `avatar.gravatarexpiration`
)
// GetString returns a string config value
func (k Key) GetString() string {
return viper.GetString(string(k))
}
// GetBool returns a bool config value
func (k Key) GetBool() bool {
return viper.GetBool(string(k))
}
// GetInt returns an int config value
func (k Key) GetInt() int {
return viper.GetInt(string(k))
}
// GetInt64 returns an int64 config value
func (k Key) GetInt64() int64 {
return viper.GetInt64(string(k))
}
// GetDuration returns a duration config value
func (k Key) GetDuration() time.Duration {
return viper.GetDuration(string(k))
}
// GetStringSlice returns a string slice from a config option
func (k Key) GetStringSlice() []string {
return viper.GetStringSlice(string(k))
}
// Set sets a value
func (k Key) Set(i interface{}) {
viper.Set(string(k), i)
}
// sets the default config value
func (k Key) setDefault(i interface{}) {
viper.SetDefault(string(k), i)
}
// InitDefaultConfig sets default config values
// This is an extra function so we can call it when initializing tests without initializing the full config
func InitDefaultConfig() {
// Service config
random, err := random(32)
if err != nil {
log.Fatal(err.Error())
}
// Service
ServiceJWTSecret.setDefault(random)
ServiceInterface.setDefault(":3456")
ServiceFrontendurl.setDefault("")
ServiceEnableCaldav.setDefault(true)
ex, err := os.Executable()
if err != nil {
panic(err)
}
exPath := filepath.Dir(ex)
ServiceRootpath.setDefault(exPath)
ServiceMaxItemsPerPage.setDefault(50)
ServiceEnableMetrics.setDefault(false)
ServiceMotd.setDefault("")
ServiceEnableLinkSharing.setDefault(true)
ServiceEnableRegistration.setDefault(true)
ServiceEnableTaskAttachments.setDefault(true)
ServiceTimeZone.setDefault("GMT")
ServiceEnableTaskComments.setDefault(true)
// Database
DatabaseType.setDefault("sqlite")
DatabaseHost.setDefault("localhost")
DatabaseUser.setDefault("vikunja")
DatabasePassword.setDefault("")
DatabaseDatabase.setDefault("vikunja")
DatabasePath.setDefault("./vikunja.db")
DatabaseMaxOpenConnections.setDefault(100)
DatabaseMaxIdleConnections.setDefault(50)
DatabaseMaxConnectionLifetime.setDefault(10000)
DatabaseSslMode.setDefault("disable")
// Cacher
CacheEnabled.setDefault(false)
CacheType.setDefault("memory")
CacheMaxElementSize.setDefault(1000)
// Mailer
MailerEnabled.setDefault(false)
MailerHost.setDefault("")
MailerPort.setDefault("587")
MailerUsername.setDefault("user")
MailerPassword.setDefault("")
MailerSkipTLSVerify.setDefault(false)
MailerFromEmail.setDefault("mail@vikunja")
MailerQueuelength.setDefault(100)
MailerQueueTimeout.setDefault(30)
// Redis
RedisEnabled.setDefault(false)
RedisHost.setDefault("localhost:6379")
RedisPassword.setDefault("")
RedisDB.setDefault(0)
// Logger
LogEnabled.setDefault(true)
LogStandard.setDefault("stdout")
LogLevel.setDefault("INFO")
LogDatabase.setDefault("off")
LogDatabaseLevel.setDefault("WARNING")
LogHTTP.setDefault("stdout")
LogEcho.setDefault("off")
LogPath.setDefault(ServiceRootpath.GetString() + "/logs")
// Rate Limit
RateLimitEnabled.setDefault(false)
RateLimitKind.setDefault("user")
RateLimitLimit.setDefault(100)
RateLimitPeriod.setDefault(60)
RateLimitStore.setDefault("memory")
// Files
FilesBasePath.setDefault("files")
FilesMaxSize.setDefault("20MB")
// Cors
CorsEnable.setDefault(true)
CorsOrigins.setDefault([]string{"*"})
CorsMaxAge.setDefault(0)
// Migration
MigrationWunderlistEnable.setDefault(false)
// Avatar
AvatarProvider.setDefault("gravatar")
AvatarGravaterExpiration.setDefault(3600)
}
// InitConfig initializes the config, sets defaults etc.
func InitConfig() {
// Set defaults
InitDefaultConfig()
// Init checking for environment variables
viper.SetEnvPrefix("vikunja")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv()
// Load the config file
viper.AddConfigPath(ServiceRootpath.GetString())
viper.AddConfigPath("/etc/vikunja/")
homeDir, err := os.UserHomeDir()
if err != nil {
log.Printf("No home directory found, not using config from ~/.config/vikunja/. Error was: %s\n", err.Error())
} else {
viper.AddConfigPath(path.Join(homeDir, ".config", "vikunja"))
}
viper.AddConfigPath(".")
viper.SetConfigName("config")
err = viper.ReadInConfig()
if err != nil {
log.Println(err.Error())
log.Println("Using default config.")
return
}
log.Printf("Using config file: %s", viper.ConfigFileUsed())
}
func random(length int) (string, error) {
b := make([]byte, length)
if _, err := rand.Read(b); err != nil {
return "", err
}
return fmt.Sprintf("%X", b), nil
}
+170
View File
@@ -0,0 +1,170 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package db
import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log"
"encoding/gob"
"fmt"
xrc "gitea.com/xorm/xorm-redis-cache"
"net/url"
"strconv"
"strings"
"time"
"xorm.io/core"
"xorm.io/xorm"
"xorm.io/xorm/caches"
_ "github.com/go-sql-driver/mysql" // Because.
_ "github.com/lib/pq" // Because.
_ "github.com/mattn/go-sqlite3" // Because.
)
// We only want one instance of the engine, so we can reate it once and reuse it
var x *xorm.Engine
// CreateDBEngine initializes a db engine from the config
func CreateDBEngine() (engine *xorm.Engine, err error) {
if x != nil {
return x, nil
}
// If the database type is not set, this likely means we need to initialize the config first
if config.DatabaseType.GetString() == "" {
config.InitConfig()
}
// Use Mysql if set
if config.DatabaseType.GetString() == "mysql" {
engine, err = initMysqlEngine()
if err != nil {
return
}
} else if config.DatabaseType.GetString() == "postgres" {
engine, err = initPostgresEngine()
if err != nil {
return
}
} else {
// Otherwise use sqlite
engine, err = initSqliteEngine()
if err != nil {
return
}
}
engine.SetMapper(core.GonicMapper{})
logger := log.NewXormLogger("")
engine.SetLogger(logger)
// Cache
// We have to initialize the cache here to avoid import cycles
if config.CacheEnabled.GetBool() {
switch config.CacheType.GetString() {
case "memory":
cacher := caches.NewLRUCacher(caches.NewMemoryStore(), config.CacheMaxElementSize.GetInt())
engine.SetDefaultCacher(cacher)
case "redis":
cacher := xrc.NewRedisCacher(config.RedisEnabled.GetString(), config.RedisPassword.GetString(), xrc.DEFAULT_EXPIRATION, engine.Logger())
engine.SetDefaultCacher(cacher)
default:
log.Info("Did not find a valid cache type. Caching disabled. Please refer to the docs for poosible cache types.")
}
}
x = engine
return
}
// RegisterTableStructsForCache registers tables in gob encoding for redis cache
func RegisterTableStructsForCache(val interface{}) {
gob.Register(val)
}
func initMysqlEngine() (engine *xorm.Engine, err error) {
// We're using utf8mb here instead of just utf8 because we want to use non-BMP characters.
// See https://stackoverflow.com/a/30074553/10924593 for more info.
connStr := fmt.Sprintf(
"%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=true",
config.DatabaseUser.GetString(),
config.DatabasePassword.GetString(),
config.DatabaseHost.GetString(),
config.DatabaseDatabase.GetString())
engine, err = xorm.NewEngine("mysql", connStr)
if err != nil {
return
}
engine.SetMaxOpenConns(config.DatabaseMaxOpenConnections.GetInt())
engine.SetMaxIdleConns(config.DatabaseMaxIdleConnections.GetInt())
max, err := time.ParseDuration(strconv.Itoa(config.DatabaseMaxConnectionLifetime.GetInt()) + `ms`)
if err != nil {
return
}
engine.SetConnMaxLifetime(max)
return
}
// parsePostgreSQLHostPort parses given input in various forms defined in
// https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
// and returns proper host and port number.
func parsePostgreSQLHostPort(info string) (string, string) {
host, port := "127.0.0.1", "5432"
if strings.Contains(info, ":") && !strings.HasSuffix(info, "]") {
idx := strings.LastIndex(info, ":")
host = info[:idx]
port = info[idx+1:]
} else if len(info) > 0 {
host = info
}
return host, port
}
func initPostgresEngine() (engine *xorm.Engine, err error) {
host, port := parsePostgreSQLHostPort(config.DatabaseHost.GetString())
connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
host,
port,
url.PathEscape(config.DatabaseUser.GetString()),
url.PathEscape(config.DatabasePassword.GetString()),
config.DatabaseDatabase.GetString(),
config.DatabaseSslMode.GetString(),
)
engine, err = xorm.NewEngine("postgres", connStr)
if err != nil {
return
}
engine.SetMaxOpenConns(config.DatabaseMaxOpenConnections.GetInt())
engine.SetMaxIdleConns(config.DatabaseMaxIdleConnections.GetInt())
max, err := time.ParseDuration(strconv.Itoa(config.DatabaseMaxConnectionLifetime.GetInt()) + `ms`)
if err != nil {
return
}
engine.SetConnMaxLifetime(max)
return
}
func initSqliteEngine() (engine *xorm.Engine, err error) {
path := config.DatabasePath.GetString()
if path == "" {
path = "./db.db"
}
return xorm.NewEngine("sqlite3", path)
}
+207
View File
@@ -0,0 +1,207 @@
- id: 1
title: testbucket1
list_id: 1
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 2
title: testbucket2
list_id: 1
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 3
title: testbucket3
list_id: 1
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 4
title: testbucket4 - other list
list_id: 2
created_by_id: 1
created: 1587244432
updated: 1587244432
# The following are not or only partly owned by user 1
- id: 5
title: testbucket5
list_id: 20
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 6
title: testbucket6
list_id: 6
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 7
title: testbucket7
list_id: 7
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 8
title: testbucket8
list_id: 8
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 9
title: testbucket9
list_id: 9
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 10
title: testbucket10
list_id: 10
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 11
title: testbucket11
list_id: 11
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 12
title: testbucket13
list_id: 12
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 13
title: testbucket13
list_id: 13
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 14
title: testbucket14
list_id: 14
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 15
title: testbucket15
list_id: 15
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 16
title: testbucket16
list_id: 16
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 17
title: testbucket17
list_id: 17
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 18
title: testbucket18
list_id: 5
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 19
title: testbucket19
list_id: 21
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 20
title: testbucket20
list_id: 22
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 21
title: testbucket21
list_id: 3
created_by_id: 1
created: 1587244432
updated: 1587244432
# Duplicate buckets to make deletion of one of them possible
- id: 22
title: testbucket22
list_id: 6
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 23
title: testbucket23
list_id: 7
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 24
title: testbucket24
list_id: 8
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 25
title: testbucket25
list_id: 9
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 26
title: testbucket26
list_id: 10
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 27
title: testbucket27
list_id: 11
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 28
title: testbucket28
list_id: 12
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 29
title: testbucket29
list_id: 13
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 30
title: testbucket30
list_id: 14
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 31
title: testbucket31
list_id: 15
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 32
title: testbucket32
list_id: 16
created_by_id: 1
created: 1587244432
updated: 1587244432
- id: 33
title: testbucket33
list_id: 17
created_by_id: 1
created: 1587244432
updated: 1587244432
# This bucket is the last one in its list
- id: 34
title: testbucket34
list_id: 18
created_by_id: 1
created: 1587244432
updated: 1587244432
+5
View File
@@ -0,0 +1,5 @@
- id: 1
name: test
size: 100
created_unix: 1570998791
created_by_id: 1
+16
View File
@@ -0,0 +1,16 @@
- id: 1
task_id: 1
label_id: 4
created: 0
- id: 2
task_id: 2
label_id: 4
created: 0
- id: 3
task_id: 35
label_id: 4
created: 0
- id: 4
task_id: 36
label_id: 4
created: 0
+20
View File
@@ -0,0 +1,20 @@
- id: 1
title: 'Label #1'
created_by_id: 1
updated: 0
created: 0
- id: 2
title: 'Label #2'
created_by_id: 1
updated: 0
created: 0
- id: 3
title: 'Label #3 - other user'
created_by_id: 2
updated: 0
created: 0
- id: 4
title: 'Label #4 - visible via other task'
created_by_id: 2
updated: 0
created: 0
+24
View File
@@ -0,0 +1,24 @@
- id: 1
hash: test
list_id: 1
right: 0
sharing_type: 1
shared_by_id: 1
created: 0
updated: 0
- id: 2
hash: test2
list_id: 2
right: 1
sharing_type: 1
shared_by_id: 1
created: 0
updated: 0
- id: 3
hash: test3
list_id: 3
right: 2
sharing_type: 1
shared_by_id: 1
created: 0
updated: 0
+201
View File
@@ -0,0 +1,201 @@
-
id: 1
title: Test1
description: Lorem Ipsum
identifier: test1
owner_id: 1
namespace_id: 1
updated: 0
created: 0
-
id: 2
title: Test2
description: Lorem Ipsum
identifier: test2
owner_id: 3
namespace_id: 1
updated: 0
created: 0
-
id: 3
title: Test3
description: Lorem Ipsum
identifier: test3
owner_id: 3
namespace_id: 2
updated: 0
created: 0
-
id: 4
title: Test4
description: Lorem Ipsum
identifier: test4
owner_id: 3
namespace_id: 3
updated: 0
created: 0
-
id: 5
title: Test5
description: Lorem Ipsum
identifier: test5
owner_id: 5
namespace_id: 5
updated: 0
created: 0
-
id: 6
title: Test6
description: Lorem Ipsum
identifier: test6
owner_id: 6
namespace_id: 6
updated: 0
created: 0
-
id: 7
title: Test7
description: Lorem Ipsum
identifier: test7
owner_id: 6
namespace_id: 6
updated: 0
created: 0
-
id: 8
title: Test8
description: Lorem Ipsum
identifier: test8
owner_id: 6
namespace_id: 6
updated: 0
created: 0
-
id: 9
title: Test9
description: Lorem Ipsum
identifier: test9
owner_id: 6
namespace_id: 6
updated: 0
created: 0
-
id: 10
title: Test10
description: Lorem Ipsum
identifier: test10
owner_id: 6
namespace_id: 6
updated: 0
created: 0
-
id: 11
title: Test11
description: Lorem Ipsum
identifier: test11
owner_id: 6
namespace_id: 6
updated: 0
created: 0
-
id: 12
title: Test12
description: Lorem Ipsum
identifier: test12
owner_id: 6
namespace_id: 7
updated: 0
created: 0
-
id: 13
title: Test13
description: Lorem Ipsum
identifier: test13
owner_id: 6
namespace_id: 8
updated: 0
created: 0
-
id: 14
title: Test14
description: Lorem Ipsum
identifier: test14
owner_id: 6
namespace_id: 9
updated: 0
created: 0
-
id: 15
title: Test15
description: Lorem Ipsum
identifier: test15
owner_id: 6
namespace_id: 10
updated: 0
created: 0
-
id: 16
title: Test16
description: Lorem Ipsum
identifier: test16
owner_id: 6
namespace_id: 11
updated: 0
created: 0
-
id: 17
title: Test17
description: Lorem Ipsum
identifier: test17
owner_id: 6
namespace_id: 12
updated: 0
created: 0
# This list is owned by user 7, and several other users have access to it via different methods.
# It is used to test the listUsers method.
-
id: 18
title: Test18
description: Lorem Ipsum
identifier: test18
owner_id: 7
namespace_id: 13
updated: 0
created: 0
-
id: 19
title: Test19
description: Lorem Ipsum
identifier: test19
owner_id: 7
namespace_id: 14
updated: 0
created: 0
-
id: 20
title: Test20
description: Lorem Ipsum
identifier: test20
owner_id: 13
namespace_id: 15
updated: 0
created: 0
-
id: 21
title: Test21 archived through namespace
description: Lorem Ipsum
identifier: test21
owner_id: 1
namespace_id: 16
updated: 0
created: 0
-
id: 22
title: Test22 archived individually
description: Lorem Ipsum
identifier: test22
owner_id: 1
namespace_id: 1
is_archived: 1
updated: 0
created: 0
+84
View File
@@ -0,0 +1,84 @@
- id: 1
name: testnamespace
description: Lorem Ipsum
owner_id: 1
updated: 0
created: 0
- id: 2
name: testnamespace2
description: Lorem Ipsum
owner_id: 2
updated: 0
created: 0
- id: 3
name: testnamespace3
description: Lorem Ipsum
owner_id: 3
updated: 0
created: 0
- id: 6
name: testnamespace6
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 7
name: testnamespace7
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 8
name: testnamespace8
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 9
name: testnamespace9
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 10
name: testnamespace10
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 11
name: testnamespace11
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 12
name: testnamespace12
description: Lorem Ipsum
owner_id: 6
updated: 0
created: 0
- id: 13
name: testnamespace13
description: Lorem Ipsum
owner_id: 7
updated: 0
created: 0
- id: 14
name: testnamespace14
description: Lorem Ipsum
owner_id: 7
updated: 0
created: 0
- id: 15
name: testnamespace15
description: Lorem Ipsum
owner_id: 13
updated: 0
created: 0
- id: 16
name: Archived testnamespace16
owner_id: 1
is_archived: 1
updated: 0
created: 0
+16
View File
@@ -0,0 +1,16 @@
- id: 1
task_id: 30
user_id: 1
created: 0
- id: 2
task_id: 30
user_id: 2
created: 0
- id: 3
task_id: 35
user_id: 2
created: 0
- id: 4
task_id: 36
user_id: 2
created: 0
+11
View File
@@ -0,0 +1,11 @@
- id: 1
task_id: 1
file_id: 1
created_by_id: 1
created: 0
# The file for this attachment does not exist
- id: 2
task_id: 1
file_id: 9999
created_by_id: 1
created: 0
+96
View File
@@ -0,0 +1,96 @@
- id: 1
comment: Lorem Ipsum Dolor Sit Amet
author_id: 1
task_id: 1
created: 1582135626
updated: 1582135626
- id: 2
comment: comment 2
author_id: 5
task_id: 14
created: 1582135626
updated: 1582135626
- id: 3
comment: comment 3
author_id: 5
task_id: 15
created: 1582135626
updated: 1582135626
- id: 4
comment: comment 4
author_id: 6
task_id: 16
created: 1582135626
updated: 1582135626
- id: 5
comment: comment 5
author_id: 6
task_id: 17
created: 1582135626
updated: 1582135626
- id: 6
comment: comment 6
author_id: 6
task_id: 18
created: 1582135626
updated: 1582135626
- id: 7
comment: comment 7
author_id: 6
task_id: 19
created: 1582135626
updated: 1582135626
- id: 8
comment: comment 8
author_id: 6
task_id: 20
created: 1582135626
updated: 1582135626
- id: 9
comment: comment 9
author_id: 6
task_id: 21
created: 1582135626
updated: 1582135626
- id: 10
comment: comment 10
author_id: 6
task_id: 22
created: 1582135626
updated: 1582135626
- id: 11
comment: comment 11
author_id: 6
task_id: 23
created: 1582135626
updated: 1582135626
- id: 12
comment: comment 12
author_id: 6
task_id: 24
created: 1582135626
updated: 1582135626
- id: 13
comment: comment 13
author_id: 6
task_id: 25
created: 1582135626
updated: 1582135626
- id: 14
comment: comment 14
author_id: 6
task_id: 26
created: 1582135626
updated: 1582135626
- id: 15
comment: comment 15
author_id: 1
task_id: 35
created: 1582135626
updated: 1582135626
- id: 16
comment: comment 16
author_id: 1
task_id: 36
created: 1582135626
updated: 1582135626
+36
View File
@@ -0,0 +1,36 @@
- id: 1
task_id: 1
other_task_id: 29
relation_kind: 'subtask'
created_by_id: 1
created: 0
- id: 2
task_id: 29
other_task_id: 1
relation_kind: 'parenttask'
created_by_id: 1
created: 0
- id: 3
task_id: 35
other_task_id: 1
relation_kind: 'related'
created_by_id: 1
created: 0
- id: 4
task_id: 35
other_task_id: 1
relation_kind: 'related'
created_by_id: 1
created: 0
- id: 5
task_id: 36
other_task_id: 1
relation_kind: 'related'
created_by_id: 1
created: 0
- id: 6
task_id: 36
other_task_id: 1
relation_kind: 'related'
created_by_id: 1
created: 0
+8
View File
@@ -0,0 +1,8 @@
- id: 1
task_id: 27
reminder_unix: 1543626724
created: 1543626724
- id: 2
task_id: 27
reminder_unix: 1543626824
created: 1543626724
+339
View File
@@ -0,0 +1,339 @@
- id: 1
text: 'task #1'
description: 'Lorem Ipsum'
done: false
created_by_id: 1
list_id: 1
index: 1
created: 1543626724
updated: 1543626724
bucket_id: 1
- id: 2
text: 'task #2 done'
done: true
created_by_id: 1
list_id: 1
index: 2
created: 1543626724
updated: 1543626724
bucket_id: 1
- id: 3
text: 'task #3 high prio'
done: false
created_by_id: 1
list_id: 1
index: 3
created: 1543626724
updated: 1543626724
priority: 100
bucket_id: 2
- id: 4
text: 'task #4 low prio'
done: false
created_by_id: 1
list_id: 1
index: 4
created: 1543626724
updated: 1543626724
priority: 1
bucket_id: 2
- id: 5
text: 'task #5 higher due date'
done: false
created_by_id: 1
list_id: 1
index: 5
created: 1543626724
updated: 1543626724
due_date_unix: 1543636724
bucket_id: 2
- id: 6
text: 'task #6 lower due date'
done: false
created_by_id: 1
list_id: 1
index: 6
created: 1543626724
updated: 1543626724
due_date_unix: 1543616724
bucket_id: 3
- id: 7
text: 'task #7 with start date'
done: false
created_by_id: 1
list_id: 1
index: 7
created: 1543626724
updated: 1543626724
start_date_unix: 1544600000
bucket_id: 3
- id: 8
text: 'task #8 with end date'
done: false
created_by_id: 1
list_id: 1
index: 8
created: 1543626724
updated: 1543626724
end_date_unix: 1544700000
bucket_id: 3
- id: 9
text: 'task #9 with start and end date'
done: false
created_by_id: 1
list_id: 1
index: 9
created: 1543626724
updated: 1543626724
start_date_unix: 1544600000
end_date_unix: 1544700000
bucket_id: 1
- id: 10
text: 'task #10 basic'
done: false
created_by_id: 1
list_id: 1
index: 10
bucket_id: 1
created: 1543626724
updated: 1543626724
- id: 11
text: 'task #11 basic'
done: false
created_by_id: 1
list_id: 1
index: 11
bucket_id: 1
created: 1543626724
updated: 1543626724
- id: 12
text: 'task #12 basic'
done: false
created_by_id: 1
list_id: 1
index: 12
bucket_id: 1
created: 1543626724
updated: 1543626724
- id: 13
text: 'task #13 basic other list'
done: false
created_by_id: 1
list_id: 2
index: 1
bucket_id: 4
created: 1543626724
updated: 1543626724
- id: 14
text: 'task #14 basic other list'
done: false
created_by_id: 5
list_id: 5
index: 1
bucket_id: 18
created: 1543626724
updated: 1543626724
- id: 15
text: 'task #15'
done: false
created_by_id: 6
list_id: 6
index: 1
bucket_id: 6
created: 1543626724
updated: 1543626724
- id: 16
text: 'task #16'
done: false
created_by_id: 6
list_id: 7
index: 1
bucket_id: 7
created: 1543626724
updated: 1543626724
- id: 17
text: 'task #17'
done: false
created_by_id: 6
list_id: 8
index: 1
bucket_id: 8
created: 1543626724
updated: 1543626724
- id: 18
text: 'task #18'
done: false
created_by_id: 6
list_id: 9
index: 1
bucket_id: 9
created: 1543626724
updated: 1543626724
- id: 19
text: 'task #19'
done: false
created_by_id: 6
list_id: 10
index: 1
bucket_id: 10
created: 1543626724
updated: 1543626724
- id: 20
text: 'task #20'
done: false
created_by_id: 6
list_id: 11
index: 1
bucket_id: 11
created: 1543626724
updated: 1543626724
- id: 21
text: 'task #21'
done: false
created_by_id: 6
list_id: 12
index: 1
bucket_id: 12
created: 1543626724
updated: 1543626724
- id: 22
text: 'task #22'
done: false
created_by_id: 6
list_id: 13
index: 1
bucket_id: 13
created: 1543626724
updated: 1543626724
- id: 23
text: 'task #23'
done: false
created_by_id: 6
list_id: 14
index: 1
bucket_id: 14
created: 1543626724
updated: 1543626724
- id: 24
text: 'task #24'
done: false
created_by_id: 6
list_id: 15
index: 1
bucket_id: 15
created: 1543626724
updated: 1543626724
- id: 25
text: 'task #25'
done: false
created_by_id: 6
list_id: 16
index: 1
bucket_id: 16
created: 1543626724
updated: 1543626724
- id: 26
text: 'task #26'
done: false
created_by_id: 6
list_id: 17
index: 1
bucket_id: 17
created: 1543626724
updated: 1543626724
- id: 27
text: 'task #27 with reminders'
done: false
created_by_id: 1
list_id: 1
index: 12
bucket_id: 1
created: 1543626724
updated: 1543626724
- id: 28
text: 'task #28 with repeat after'
done: false
created_by_id: 1
repeat_after: 3600
list_id: 1
index: 13
bucket_id: 1
created: 1543626724
updated: 1543626724
- id: 29
text: 'task #29 with parent task (1)'
done: false
created_by_id: 1
list_id: 1
index: 14
bucket_id: 1
created: 1543626724
updated: 1543626724
- id: 30
text: 'task #30 with assignees'
done: false
created_by_id: 1
list_id: 1
index: 15
bucket_id: 1
created: 1543626724
updated: 1543626724
- id: 31
text: 'task #31 with color'
done: false
created_by_id: 1
list_id: 1
index: 16
hex_color: f0f0f0
bucket_id: 1
created: 1543626724
updated: 1543626724
- id: 32
text: 'task #32'
done: false
created_by_id: 1
list_id: 3
index: 1
bucket_id: 21
created: 1543626724
updated: 1543626724
- id: 33
text: 'task #33 with percent done'
done: false
created_by_id: 1
list_id: 1
index: 17
percent_done: 0.5
bucket_id: 1
created: 1543626724
updated: 1543626724
# This task is forbidden for user1
- id: 34
text: 'task #34'
done: false
created_by_id: 13
list_id: 20
index: 20
bucket_id: 5
created: 1543626724
updated: 1543626724
- id: 35
text: 'task #35'
done: false
created_by_id: 1
list_id: 21
index: 1
bucket_id: 19
created: 1543626724
updated: 1543626724
- id: 36
text: 'task #36'
done: false
created_by_id: 1
list_id: 22
index: 1
bucket_id: 20
created: 1543626724
updated: 1543626724
+48
View File
@@ -0,0 +1,48 @@
- id: 1
team_id: 1
list_id: 3
right: 0
updated: 0
created: 0
# This team has read only access on list 6
- id: 2
team_id: 2
list_id: 6
right: 0
updated: 0
created: 0
# This team has write access on list 7
- id: 3
team_id: 3
list_id: 7
right: 1
updated: 0
created: 0
# This team has admin access on list 8
- id: 4
team_id: 4
list_id: 8
right: 2
updated: 0
created: 0
# Readonly acces on list 19
- id: 5
team_id: 8
list_id: 19
right: 2
updated: 0
created: 0
# Write acces on list 19
- id: 6
team_id: 9
list_id: 19
right: 1
updated: 0
created: 0
# Admin acces on list 19
- id: 7
team_id: 10
list_id: 19
right: 2
updated: 0
created: 0
+57
View File
@@ -0,0 +1,57 @@
-
team_id: 1
user_id: 1
admin: true
created: 0
-
team_id: 1
user_id: 2
created: 0
-
team_id: 2
user_id: 1
created: 0
-
team_id: 3
user_id: 1
created: 0
-
team_id: 4
user_id: 1
created: 0
-
team_id: 5
user_id: 1
created: 0
-
team_id: 6
user_id: 1
created: 0
-
team_id: 7
user_id: 1
created: 0
-
team_id: 8
user_id: 1
created: 0
-
team_id: 9
user_id: 2
created: 0
-
team_id: 10
user_id: 3
created: 0
-
team_id: 11
user_id: 8
created: 0
-
team_id: 12
user_id: 9
created: 0
-
team_id: 13
user_id: 10
created: 0
+52
View File
@@ -0,0 +1,52 @@
- id: 1
team_id: 1
namespace_id: 3
right: 0
updated: 0
created: 0
- id: 2
team_id: 2
namespace_id: 3
right: 0
updated: 0
created: 0
- id: 3
team_id: 5
namespace_id: 7
right: 0
updated: 0
created: 0
- id: 4
team_id: 6
namespace_id: 8
right: 1
updated: 0
created: 0
- id: 5
team_id: 7
namespace_id: 9
right: 2
updated: 0
created: 0
- id: 6
team_id: 11
namespace_id: 14
right: 0
updated: 0
created: 0
- id: 7
team_id: 12
namespace_id: 14
right: 1
updated: 0
created: 0
- id: 8
team_id: 13
namespace_id: 14
right: 2
updated: 0
created: 0
+40
View File
@@ -0,0 +1,40 @@
- id: 1
name: testteam1
description: Lorem Ipsum
created_by_id: 1
- id: 2
name: testteam2_read_only_on_list6
created_by_id: 1
- id: 3
name: testteam3_write_on_list7
created_by_id: 1
- id: 4
name: testteam4_admin_on_list8
created_by_id: 1
- id: 5
name: testteam2_read_only_on_namespace7
created_by_id: 1
- id: 6
name: testteam3_write_on_namespace8
created_by_id: 1
- id: 7
name: testteam4_admin_on_namespace9
created_by_id: 1
- id: 8
name: testteam8
created_by_id: 7
- id: 9
name: testteam9
created_by_id: 7
- id: 10
name: testteam10
created_by_id: 7
- id: 11
name: testteam11
created_by_id: 7
- id: 12
name: testteam12
created_by_id: 7
- id: 13
name: testteam13
created_by_id: 7
+97
View File
@@ -0,0 +1,97 @@
-
id: 1
username: 'user1'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user1@example.com'
is_active: true
updated: 0
created: 0
-
id: 2
username: 'user2'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user2@example.com'
updated: 0
created: 0
-
id: 3
username: 'user3'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user3@example.com'
password_reset_token: passwordresettesttoken
updated: 0
created: 0
-
id: 4
username: 'user4'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user4@example.com'
email_confirm_token: tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael
updated: 0
created: 0
-
id: 5
username: 'user5'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user5@example.com'
email_confirm_token: tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael
is_active: false
updated: 0
created: 0
# This use is used to create a whole bunch of lists which are then shared directly with a user
- id: 6
username: 'user6'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user6@example.com'
is_active: true
updated: 0
created: 0
- id: 7
username: 'user7'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user7@example.com'
is_active: true
updated: 0
created: 0
- id: 8
username: 'user8'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user8@example.com'
is_active: true
updated: 0
created: 0
- id: 9
username: 'user9'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user9@example.com'
is_active: true
updated: 0
created: 0
- id: 10
username: 'user10'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user10@example.com'
is_active: true
updated: 0
created: 0
- id: 11
username: 'user11'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user11@example.com'
is_active: true
updated: 0
created: 0
- id: 12
username: 'user12'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user12@example.com'
is_active: true
updated: 0
created: 0
- id: 13
username: 'user13'
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
email: 'user14@example.com'
is_active: true
updated: 0
created: 0
+48
View File
@@ -0,0 +1,48 @@
- id: 1
user_id: 1
list_id: 3
right: 0
updated: 0
created: 0
- id: 2
user_id: 2
list_id: 3
right: 0
updated: 0
created: 0
- id: 3
user_id: 1
list_id: 9
right: 0
updated: 0
created: 0
- id: 4
user_id: 1
list_id: 10
right: 1
updated: 0
created: 0
- id: 5
user_id: 1
list_id: 11
right: 2
updated: 0
created: 0
- id: 6
user_id: 4
list_id: 19
right: 0
updated: 0
created: 0
- id: 7
user_id: 5
list_id: 19
right: 1
updated: 0
created: 0
- id: 8
user_id: 6
list_id: 19
right: 2
updated: 0
created: 0
+52
View File
@@ -0,0 +1,52 @@
- id: 1
user_id: 1
namespace_id: 3
right: 0
updated: 0
created: 0
- id: 2
user_id: 2
namespace_id: 3
right: 0
updated: 0
created: 0
- id: 3
user_id: 1
namespace_id: 10
right: 0
updated: 0
created: 0
- id: 4
user_id: 1
namespace_id: 11
right: 1
updated: 0
created: 0
- id: 5
user_id: 1
namespace_id: 12
right: 2
updated: 0
created: 0
- id: 6
user_id: 11
namespace_id: 14
right: 0
updated: 0
created: 0
- id: 7
user_id: 12
namespace_id: 14
right: 1
updated: 0
created: 0
- id: 8
user_id: 13
namespace_id: 14
right: 2
updated: 0
created: 0
+70
View File
@@ -0,0 +1,70 @@
// Copyright2018-2020 Vikunja and contriubtors. All rights reserved.
//
// This file is part of Vikunja.
//
// Vikunja is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vikunja 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
package db
import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log"
"os"
"xorm.io/core"
"xorm.io/xorm"
)
// CreateTestEngine creates an instance of the db engine which lives in memory
func CreateTestEngine() (engine *xorm.Engine, err error) {
if x != nil {
return x, nil
}
if os.Getenv("VIKUNJA_TESTS_USE_CONFIG") == "1" {
config.InitConfig()
engine, err = CreateDBEngine()
if err != nil {
return nil, err
}
} else {
engine, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
if err != nil {
return nil, err
}
}
engine.SetMapper(core.GonicMapper{})
logger := log.NewXormLogger("DEBUG")
logger.ShowSQL(os.Getenv("UNIT_TESTS_VERBOSE") == "1")
engine.SetLogger(logger)
x = engine
return
}
// InitTestFixtures populates the db with all fixtures from the fixtures folder
func InitTestFixtures(tablenames ...string) (err error) {
// Create all fixtures
config.InitDefaultConfig()
// We need to set the root path even if we're not using the config, otherwise fixtures are not loaded correctly
config.ServiceRootpath.Set(os.Getenv("VIKUNJA_SERVICE_ROOTPATH"))
// Sync fixtures
err = InitFixtures(tablenames...)
if err != nil {
log.Fatal(err)
}
return nil
}
+115
View File
@@ -0,0 +1,115 @@
// Copyright 2018-2020 Vikunja and contriubtors. All rights reserved.
//
// This file is part of Vikunja.
//
// Vikunja is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vikunja 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
package db
import (
"code.vikunja.io/api/pkg/config"
"fmt"
"github.com/go-testfixtures/testfixtures/v3"
"github.com/stretchr/testify/assert"
"path/filepath"
"testing"
"xorm.io/xorm/schemas"
)
var fixtures *testfixtures.Loader
// InitFixtures initialize test fixtures for a test database
func InitFixtures(tablenames ...string) (err error) {
var testfiles func(loader *testfixtures.Loader) error
dir := filepath.Join(config.ServiceRootpath.GetString(), "pkg", "db", "fixtures")
// If fixture table names are specified, load them
// Otherwise, load all fixtures
if len(tablenames) > 0 {
for i, name := range tablenames {
tablenames[i] = filepath.Join(dir, name+".yml")
}
testfiles = testfixtures.Files(tablenames...)
} else {
testfiles = testfixtures.Directory(dir)
}
loaderOptions := []func(loader *testfixtures.Loader) error{
testfixtures.Database(x.DB().DB),
testfixtures.Dialect(config.DatabaseType.GetString()),
testfixtures.DangerousSkipTestDatabaseCheck(),
testfiles,
}
if config.DatabaseType.GetString() == "postgres" {
loaderOptions = append(loaderOptions, testfixtures.SkipResetSequences())
}
fixtures, err = testfixtures.New(loaderOptions...)
if err != nil {
return err
}
return err
}
// LoadFixtures load fixtures for a test database
func LoadFixtures() error {
err := fixtures.Load()
if err != nil {
return err
}
// Copied from https://github.com/go-gitea/gitea/blob/master/models/test_fixtures.go#L39
// Now if we're running postgres we need to tell it to update the sequences
if x.Dialect().URI().DBType == schemas.POSTGRES {
results, err := x.QueryString(`SELECT 'SELECT SETVAL(' ||
quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) ||
', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' ||
quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';'
FROM pg_class AS S,
pg_depend AS D,
pg_class AS T,
pg_attribute AS C,
pg_tables AS PGT
WHERE S.relkind = 'S'
AND S.oid = D.objid
AND D.refobjid = T.oid
AND D.refobjid = C.attrelid
AND D.refobjsubid = C.attnum
AND T.relname = PGT.tablename
ORDER BY S.relname;`)
if err != nil {
fmt.Printf("Failed to generate sequence update: %v\n", err)
return err
}
for _, r := range results {
for _, value := range r {
_, err = x.Exec(value)
if err != nil {
fmt.Printf("Failed to update sequence: %s Error: %v\n", value, err)
return err
}
}
}
}
return err
}
// LoadAndAssertFixtures loads all fixtures defined before and asserts they are correctly loaded
func LoadAndAssertFixtures(t *testing.T) {
err := LoadFixtures()
assert.NoError(t, err)
}
+49
View File
@@ -0,0 +1,49 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package files
import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/log"
"xorm.io/xorm"
)
var x *xorm.Engine
// SetEngine sets the xorm.Engine
func SetEngine() (err error) {
x, err = db.CreateDBEngine()
if err != nil {
log.Criticalf("Could not connect to db: %v", err.Error())
return
}
// Cache
if config.CacheEnabled.GetBool() && config.CacheType.GetString() == "redis" {
db.RegisterTableStructsForCache(GetTables())
}
return nil
}
// GetTables returns all structs which are also a table.
func GetTables() []interface{} {
return []interface{}{
&File{},
}
}
+52
View File
@@ -0,0 +1,52 @@
// Copyright 2018-2020 Vikunja and contriubtors. All rights reserved.
//
// This file is part of Vikunja.
//
// Vikunja is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vikunja 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
package files
import "fmt"
// ErrFileDoesNotExist defines an error where a file does not exist in the db
type ErrFileDoesNotExist struct {
FileID int64
}
// Error is the error implementation of ErrFileDoesNotExist
func (err ErrFileDoesNotExist) Error() string {
return fmt.Sprintf("file %d does not exist", err.FileID)
}
//IsErrFileDoesNotExist checks if an error is ErrFileDoesNotExist
func IsErrFileDoesNotExist(err error) bool {
_, ok := err.(ErrFileDoesNotExist)
return ok
}
// ErrFileIsTooLarge defines an error where a file is larger than the configured limit
type ErrFileIsTooLarge struct {
Size uint64
}
// Error is the error implementation of ErrFileIsTooLarge
func (err ErrFileIsTooLarge) Error() string {
return fmt.Sprintf("file is too large [Size: %d]", err.Size)
}
//IsErrFileIsTooLarge checks if an error is ErrFileIsTooLarge
func IsErrFileIsTooLarge(err error) bool {
_, ok := err.(ErrFileIsTooLarge)
return ok
}
+84
View File
@@ -0,0 +1,84 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package files
import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/log"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"os"
"testing"
)
// This file handles storing and retrieving a file for different backends
var fs afero.Fs
var afs *afero.Afero
// InitFileHandler creates a new file handler for the file backend we want to use
func InitFileHandler() {
fs = afero.NewOsFs()
afs = &afero.Afero{Fs: fs}
}
// InitTestFileHandler initializes a new memory file system for testing
func InitTestFileHandler() {
fs = afero.NewMemMapFs()
afs = &afero.Afero{Fs: fs}
}
func initFixtures(t *testing.T) {
// DB fixtures
db.LoadAndAssertFixtures(t)
// File fixtures
InitTestFileFixtures(t)
}
//InitTestFileFixtures initializes file fixtures
func InitTestFileFixtures(t *testing.T) {
// Init fixture files
filename := config.FilesBasePath.GetString() + "/1"
err := afero.WriteFile(afs, filename, []byte("testfile1"), 0644)
assert.NoError(t, err)
}
// InitTests handles the actual bootstrapping of the test env
func InitTests() {
var err error
x, err = db.CreateTestEngine()
if err != nil {
log.Fatal(err)
}
err = x.Sync2(GetTables()...)
if err != nil {
log.Fatal(err)
}
err = db.InitTestFixtures("files")
if err != nil {
log.Fatal(err)
}
InitTestFileHandler()
}
// FileStat stats a file. This is an exported function to be able to test this from outide of the package
func FileStat(filename string) (os.FileInfo, error) {
return afs.Stat(filename)
}
+115
View File
@@ -0,0 +1,115 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package files
import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/timeutil"
"code.vikunja.io/web"
"github.com/c2h5oh/datasize"
"github.com/spf13/afero"
"io"
"strconv"
"time"
)
// File holds all information about a file
type File struct {
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"`
Name string `xorm:"text not null" json:"name"`
Mime string `xorm:"text null" json:"mime"`
Size uint64 `xorm:"int(11) not null" json:"size"`
Created time.Time `xorm:"-" json:"created"`
CreatedUnix timeutil.TimeStamp `xorm:"created" json:"-"`
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
File afero.File `xorm:"-" json:"-"`
// This ReadCloser is only used for migration purposes. Use with care!
// There is currentlc no better way of doing this.
FileContent []byte `xorm:"-" json:"-"`
}
// TableName is the table name for the files table
func (File) TableName() string {
return "files"
}
func (f *File) getFileName() string {
return config.FilesBasePath.GetString() + "/" + strconv.FormatInt(f.ID, 10)
}
// LoadFileByID returns a file by its ID
func (f *File) LoadFileByID() (err error) {
f.File, err = afs.Open(f.getFileName())
return
}
// LoadFileMetaByID loads everything about a file without loading the actual file
func (f *File) LoadFileMetaByID() (err error) {
exists, err := x.Where("id = ?", f.ID).Get(f)
if !exists {
return ErrFileDoesNotExist{FileID: f.ID}
}
f.Created = f.CreatedUnix.ToTime()
return
}
// Create creates a new file from an FileHeader
func Create(f io.ReadCloser, realname string, realsize uint64, a web.Auth) (file *File, err error) {
// Get and parse the configured file size
var maxSize datasize.ByteSize
err = maxSize.UnmarshalText([]byte(config.FilesMaxSize.GetString()))
if err != nil {
return nil, err
}
if realsize > maxSize.Bytes() {
return nil, ErrFileIsTooLarge{Size: realsize}
}
// We first insert the file into the db to get it's ID
file = &File{
Name: realname,
Size: realsize,
CreatedByID: a.GetID(),
}
_, err = x.Insert(file)
if err != nil {
return
}
// Save the file to storage with its new ID as path
err = afs.WriteReader(file.getFileName(), f)
return
}
// Delete removes a file from the DB and the file system
func (f *File) Delete() (err error) {
deleted, err := x.Where("id = ?", f.ID).Delete(f)
if err != nil {
return err
}
if deleted == 0 {
return ErrFileDoesNotExist{FileID: f.ID}
}
err = afs.Remove(f.getFileName())
return
}
+131
View File
@@ -0,0 +1,131 @@
// Copyright 2018-2020 Vikunja and contriubtors. All rights reserved.
//
// This file is part of Vikunja.
//
// Vikunja is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vikunja 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
package files
import (
"github.com/stretchr/testify/assert"
"io"
"os"
"testing"
)
type testfile struct {
content []byte
done bool
}
func (t *testfile) Read(p []byte) (n int, err error) {
if t.done {
return 0, io.EOF
}
copy(p, t.content)
t.done = true
return len(p), nil
}
func (t *testfile) Close() error {
return nil
}
type testauth struct {
id int64
}
func (a *testauth) GetID() int64 {
return a.id
}
func TestCreate(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
initFixtures(t)
tf := &testfile{
content: []byte("testfile"),
}
ta := &testauth{id: 1}
createdFile, err := Create(tf, "testfile", 100, ta)
assert.NoError(t, err)
// Check the file was created correctly
file := &File{ID: createdFile.ID}
err = file.LoadFileMetaByID()
assert.NoError(t, err)
assert.Equal(t, int64(1), file.CreatedByID)
assert.Equal(t, "testfile", file.Name)
assert.Equal(t, uint64(100), file.Size)
})
t.Run("Too Large", func(t *testing.T) {
initFixtures(t)
tf := &testfile{
content: []byte("testfile"),
}
ta := &testauth{id: 1}
_, err := Create(tf, "testfile", 99999999999, ta)
assert.Error(t, err)
assert.True(t, IsErrFileIsTooLarge(err))
})
}
func TestFile_Delete(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
initFixtures(t)
f := &File{ID: 1}
err := f.Delete()
assert.NoError(t, err)
})
t.Run("Nonexisting", func(t *testing.T) {
initFixtures(t)
f := &File{ID: 9999}
err := f.Delete()
assert.Error(t, err)
assert.True(t, IsErrFileDoesNotExist(err))
})
}
func TestFile_LoadFileByID(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
initFixtures(t)
f := &File{ID: 1}
err := f.LoadFileByID()
assert.NoError(t, err)
})
t.Run("Nonexisting", func(t *testing.T) {
initFixtures(t)
f := &File{ID: 9999}
err := f.LoadFileByID()
assert.Error(t, err)
assert.True(t, os.IsNotExist(err))
})
}
func TestFile_LoadFileMetaByID(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
initFixtures(t)
f := &File{ID: 1}
err := f.LoadFileMetaByID()
assert.NoError(t, err)
assert.Equal(t, "test", f.Name)
})
t.Run("Nonexisting", func(t *testing.T) {
initFixtures(t)
f := &File{ID: 9999}
err := f.LoadFileMetaByID()
assert.Error(t, err)
assert.True(t, IsErrFileDoesNotExist(err))
})
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2018-2020 Vikunja and contriubtors. All rights reserved.
//
// This file is part of Vikunja.
//
// Vikunja is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vikunja 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
package files
import (
"os"
"testing"
)
// TestMain is the main test function used to bootstrap the test env
func TestMain(m *testing.M) {
InitTests()
os.Exit(m.Run())
}
+350
View File
@@ -0,0 +1,350 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 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 General Public License 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package integrations
import (
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/web/handler"
"github.com/labstack/echo"
"github.com/stretchr/testify/assert"
"net/url"
"testing"
)
func Test${MODEL}(t *testing.T) {
testHandler := webHandlerTest{
user: &testuser1,
strFunc: func() handler.CObject {
return &models.${MODEL}{}
},
t: t,
}
t.Run("ReadAll", func(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
rec, err := testHandler.testReadAll(nil, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
assert.NotContains(t, rec.Body.String(), ``)
})
t.Run("Search", func(t *testing.T) {
rec, err := testHandler.testReadAll(url.Values{"s": []string{""}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
assert.NotContains(t, rec.Body.String(), ``)
})
})
t.Run("ReadOne", func(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
assert.NotContains(t, rec.Body.String(), ``)
})
t.Run("Nonexisting", func(t *testing.T) {
_, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCode)
})
t.Run("Rights check", func(t *testing.T) {
t.Run("Forbidden", func(t *testing.T) {
// Owned by user3
_, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `You don't have the right to see this`)
})
t.Run("Shared Via Team readonly", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via Team write", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via Team admin", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via User readonly", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via User write", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via User admin", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
})
})
t.Run("Update", func(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Nonexisting", func(t *testing.T) {
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCode)
})
t.Run("Rights check", func(t *testing.T) {
t.Run("Forbidden", func(t *testing.T) {
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via Team readonly", func(t *testing.T) {
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via Team write", func(t *testing.T) {
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via Team admin", func(t *testing.T) {
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via User readonly", func(t *testing.T) {
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via User write", func(t *testing.T) {
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via User admin", func(t *testing.T) {
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
})
})
t.Run("Delete", func(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Nonexisting", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCode)
})
t.Run("Rights check", func(t *testing.T) {
t.Run("Forbidden", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via Team readonly", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via Team write", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via Team admin", func(t *testing.T) {
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via User readonly", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via User write", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via User admin", func(t *testing.T) {
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
})
})
t.Run("Create", func(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
rec, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Nonexisting", func(t *testing.T) {
_, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCode)
})
t.Run("Rights check", func(t *testing.T) {
t.Run("Forbidden", func(t *testing.T) {
_, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
_, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
rec, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
rec, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
_, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.Error(t, err)
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
})
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
rec, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
rec, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), ``)
})
})
})
}
+238
View File
@@ -0,0 +1,238 @@
// Copyright 2020 Vikunja and contriubtors. All rights reserved.
//
// This file is part of Vikunja.
//
// Vikunja is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vikunja 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
package integrations
import (
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/web/handler"
"github.com/stretchr/testify/assert"
"net/url"
"testing"
)
// This tests the following behaviour:
// 1. A namespace should not be editable if it is archived.
// 1. With the exception being to un-archive it.
// 2. A list which belongs to an archived namespace cannot be edited.
// 3. An archived list should not be editable.
// 1. Except for un-archiving it.
// 4. It is not possible to un-archive a list individually if its namespace is archived.
// 5. Creating new lists on an archived namespace should not work.
// 6. Creating new tasks on an archived list should not work.
// 7. Creating new tasks on a list who's namespace is archived should not work.
// 8. Editing tasks on an archived list should not work.
// 9. Editing tasks on a list who's namespace is archived should not work.
// 10. Archived namespaces should not appear in the list with all namespaces.
// 11. Archived lists should not appear in the list with all lists.
// 12. Lists who's namespace is archived should not appear in the list with all lists.
//
// All of this is tested through integration tests because it's not yet clear if this will be implemented directly
// or with some kind of middleware.
//
// Maybe the inheritance of lists from namespaces could be solved with some kind of is_archived_inherited flag -
// that way I'd only need to implement the checking on a list level and update the flag for all lists once the
// namespace is archived. The archived flag would then be used to not accedentially unarchive lists which were
// already individually archived when the namespace was archived.
// Should still test it all though.
//
// Namespace 16 is archived
// List 21 belongs to namespace 16
// List 22 is archived individually
func TestArchived(t *testing.T) {
testListHandler := webHandlerTest{
user: &testuser1,
strFunc: func() handler.CObject {
return &models.List{}
},
t: t,
}
testNamespaceHandler := webHandlerTest{
user: &testuser1,
strFunc: func() handler.CObject {
return &models.Namespace{}
},
t: t,
}
testTaskHandler := webHandlerTest{
user: &testuser1,
strFunc: func() handler.CObject {
return &models.Task{}
},
t: t,
}
testLabelHandler := webHandlerTest{
user: &testuser1,
strFunc: func() handler.CObject {
return &models.LabelTask{}
},
t: t,
}
testAssigneeHandler := webHandlerTest{
user: &testuser1,
strFunc: func() handler.CObject {
return &models.TaskAssginee{}
},
t: t,
}
testRelationHandler := webHandlerTest{
user: &testuser1,
strFunc: func() handler.CObject {
return &models.TaskRelation{}
},
t: t,
}
testCommentHandler := webHandlerTest{
user: &testuser1,
strFunc: func() handler.CObject {
return &models.TaskComment{}
},
t: t,
}
t.Run("namespace", func(t *testing.T) {
t.Run("not editable", func(t *testing.T) {
_, err := testNamespaceHandler.testUpdateWithUser(nil, map[string]string{"namespace": "16"}, `{"name":"TestIpsum","is_archived":true}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeNamespaceIsArchived)
})
t.Run("unarchivable", func(t *testing.T) {
rec, err := testNamespaceHandler.testUpdateWithUser(nil, map[string]string{"namespace": "16"}, `{"name":"TestIpsum","is_archived":false}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"is_archived":false`)
})
t.Run("no new lists", func(t *testing.T) {
_, err := testListHandler.testCreateWithUser(nil, map[string]string{"namespace": "16"}, `{"title":"Lorem"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeNamespaceIsArchived)
})
t.Run("should not appear in the list", func(t *testing.T) {
rec, err := testNamespaceHandler.testReadAllWithUser(nil, nil)
assert.NoError(t, err)
assert.NotContains(t, rec.Body.String(), `"name":"Archived testnamespace16"`)
})
t.Run("should appear in the list if explicitly requested", func(t *testing.T) {
rec, err := testNamespaceHandler.testReadAllWithUser(url.Values{"is_archived": []string{"true"}}, nil)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"name":"Archived testnamespace16"`)
})
})
t.Run("list", func(t *testing.T) {
taskTests := func(taskID string, errCode int, t *testing.T) {
t.Run("task", func(t *testing.T) {
t.Run("edit task", func(t *testing.T) {
_, err := testTaskHandler.testUpdateWithUser(nil, map[string]string{"listtask": taskID}, `{"text":"TestIpsum"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
t.Run("delete", func(t *testing.T) {
_, err := testTaskHandler.testDeleteWithUser(nil, map[string]string{"listtask": taskID})
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
t.Run("add new labels", func(t *testing.T) {
_, err := testLabelHandler.testCreateWithUser(nil, map[string]string{"listtask": taskID}, `{"label_id":1}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
t.Run("remove lables", func(t *testing.T) {
_, err := testLabelHandler.testDeleteWithUser(nil, map[string]string{"listtask": taskID, "label": "4"})
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
t.Run("add assignees", func(t *testing.T) {
_, err := testAssigneeHandler.testCreateWithUser(nil, map[string]string{"listtask": taskID}, `{"user_id":3}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
t.Run("remove assignees", func(t *testing.T) {
_, err := testAssigneeHandler.testDeleteWithUser(nil, map[string]string{"listtask": taskID, "user": "2"})
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
t.Run("add relation", func(t *testing.T) {
_, err := testRelationHandler.testCreateWithUser(nil, map[string]string{"task": taskID}, `{"other_task_id":1,"relation_kind":"related"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
t.Run("remove relation", func(t *testing.T) {
_, err := testRelationHandler.testDeleteWithUser(nil, map[string]string{"task": taskID}, `{"other_task_id":2,"relation_kind":"related"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
t.Run("add comment", func(t *testing.T) {
_, err := testCommentHandler.testCreateWithUser(nil, map[string]string{"task": taskID}, `{"comment":"Lorem"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
t.Run("remove comment", func(t *testing.T) {
var commentID = "15"
if taskID == "36" {
commentID = "16"
}
_, err := testCommentHandler.testDeleteWithUser(nil, map[string]string{"task": taskID, "commentid": commentID})
assert.Error(t, err)
assertHandlerErrorCode(t, err, errCode)
})
})
}
// The list belongs to an archived namespace
t.Run("archived namespace", func(t *testing.T) {
t.Run("not editable", func(t *testing.T) {
_, err := testListHandler.testUpdateWithUser(nil, map[string]string{"list": "21"}, `{"title":"TestIpsum","is_archived":true}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeNamespaceIsArchived)
})
t.Run("no new tasks", func(t *testing.T) {
_, err := testTaskHandler.testCreateWithUser(nil, map[string]string{"list": "21"}, `{"text":"Lorem"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeNamespaceIsArchived)
})
t.Run("not unarchivable", func(t *testing.T) {
_, err := testListHandler.testUpdateWithUser(nil, map[string]string{"list": "21"}, `{"title":"LoremIpsum","is_archived":false}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeNamespaceIsArchived)
})
taskTests("35", models.ErrCodeNamespaceIsArchived, t)
})
// The list itself is archived
t.Run("archived individually", func(t *testing.T) {
t.Run("not editable", func(t *testing.T) {
_, err := testListHandler.testUpdateWithUser(nil, map[string]string{"list": "22"}, `{"title":"TestIpsum","is_archived":true}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeListIsArchived)
})
t.Run("no new tasks", func(t *testing.T) {
_, err := testTaskHandler.testCreateWithUser(nil, map[string]string{"list": "22"}, `{"text":"Lorem"}`)
assert.Error(t, err)
assertHandlerErrorCode(t, err, models.ErrCodeListIsArchived)
})
t.Run("unarchivable", func(t *testing.T) {
rec, err := testListHandler.testUpdateWithUser(nil, map[string]string{"list": "22"}, `{"title":"LoremIpsum","is_archived":false}`)
assert.NoError(t, err)
assert.Contains(t, rec.Body.String(), `"is_archived":false`)
})
taskTests("36", models.ErrCodeListIsArchived, t)
})
})
}

Some files were not shown because too many files have changed in this diff Show More