Added http endpoint to list all users on a list (#87)
This commit is contained in:
parent
b63928850a
commit
12eaddc8ee
21 changed files with 722 additions and 56 deletions
|
@ -55,7 +55,7 @@ Sorry for some of them being in German, I'll tranlate them at some point.
|
||||||
* [x] Wir brauchen noch ne gute idee, wie man die listen kriegt, auf die man nur so Zugriff hat (ohne namespace)
|
* [x] Wir brauchen noch ne gute idee, wie man die listen kriegt, auf die man nur so Zugriff hat (ohne namespace)
|
||||||
* Dazu am Besten nen pseudonamespace anlegen (id -1 oder so), der hat das dann alles
|
* Dazu am Besten nen pseudonamespace anlegen (id -1 oder so), der hat das dann alles
|
||||||
* [x] Testing mit locust: https://locust.io/
|
* [x] Testing mit locust: https://locust.io/
|
||||||
* [ ] Endpoint to get all users who have access to a list - regardless of via team, user share or via namespace
|
* [x] Endpoint to get all users who have access to a list - regardless of via team, user share or via namespace
|
||||||
|
|
||||||
#### Userstuff
|
#### Userstuff
|
||||||
|
|
||||||
|
@ -188,8 +188,8 @@ Sorry for some of them being in German, I'll tranlate them at some point.
|
||||||
* [x] Adding users to a team should also use uuid
|
* [x] Adding users to a team should also use uuid
|
||||||
* [x] Check if the team/user really exist before updating them on lists/namespaces
|
* [x] Check if the team/user really exist before updating them on lists/namespaces
|
||||||
* [x] Refactor config handling: Custom type "key" or so which holds the viper const and then mixins on that type to get the values from viper
|
* [x] Refactor config handling: Custom type "key" or so which holds the viper const and then mixins on that type to get the values from viper
|
||||||
|
* [x] Less files, but with some kind of logic
|
||||||
* [ ] Have extra functions for logging to call so it is possible to call `log.Info` instead of `log.Log.Info`
|
* [ ] Have extra functions for logging to call so it is possible to call `log.Info` instead of `log.Log.Info`
|
||||||
* [ ] Less files, but with some kind of logic
|
|
||||||
|
|
||||||
### Linters
|
### Linters
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ POST http://localhost:8080/api/v1/login
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"username": "user6",
|
"username": "user3",
|
||||||
"password": "1234"
|
"password": "1234"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ Authorization: Bearer {{auth_token}}
|
||||||
###
|
###
|
||||||
|
|
||||||
# Get one list
|
# Get one list
|
||||||
GET http://localhost:8080/api/v1/lists/1172
|
GET http://localhost:8080/api/v1/lists/3
|
||||||
Authorization: Bearer {{auth_token}}
|
Authorization: Bearer {{auth_token}}
|
||||||
|
|
||||||
###
|
###
|
||||||
|
@ -82,11 +82,11 @@ Authorization: Bearer {{auth_token}}
|
||||||
###
|
###
|
||||||
|
|
||||||
# Give a user access to that list
|
# Give a user access to that list
|
||||||
PUT http://localhost:8080/api/v1/lists/1172/users
|
PUT http://localhost:8080/api/v1/lists/3/users
|
||||||
Authorization: Bearer {{auth_token}}
|
Authorization: Bearer {{auth_token}}
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{"user_id":1, "right":1}
|
{"userID":"user4", "right":1}
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
@ -169,3 +169,9 @@ Content-Type: application/json
|
||||||
}
|
}
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
# Get all users who have access to a list
|
||||||
|
GET http://localhost:8080/api/v1/lists/3/users
|
||||||
|
Authorization: Bearer {{auth_token}}
|
||||||
|
|
||||||
|
###
|
||||||
|
|
|
@ -134,3 +134,21 @@
|
||||||
namespace_id: 12
|
namespace_id: 12
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 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
|
||||||
|
owner_id: 7
|
||||||
|
namespace_id: 13
|
||||||
|
updated: 0
|
||||||
|
created: 0
|
||||||
|
-
|
||||||
|
id: 19
|
||||||
|
title: Test19
|
||||||
|
description: Lorem Ipsum
|
||||||
|
owner_id: 7
|
||||||
|
namespace_id: 14
|
||||||
|
updated: 0
|
||||||
|
created: 0
|
||||||
|
|
|
@ -58,3 +58,15 @@
|
||||||
owner_id: 6
|
owner_id: 6
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 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
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
right: 0
|
right: 0
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 0
|
created: 0
|
||||||
|
|
||||||
# This team has read only access on list 6
|
# This team has read only access on list 6
|
||||||
- id: 2
|
- id: 2
|
||||||
team_id: 2
|
team_id: 2
|
||||||
|
@ -12,7 +11,6 @@
|
||||||
right: 0
|
right: 0
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 0
|
created: 0
|
||||||
|
|
||||||
# This team has write access on list 7
|
# This team has write access on list 7
|
||||||
- id: 3
|
- id: 3
|
||||||
team_id: 3
|
team_id: 3
|
||||||
|
@ -20,11 +18,31 @@
|
||||||
right: 1
|
right: 1
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 0
|
created: 0
|
||||||
|
|
||||||
# This team has admin access on list 8
|
# This team has admin access on list 8
|
||||||
- id: 4
|
- id: 4
|
||||||
team_id: 4
|
team_id: 4
|
||||||
list_id: 8
|
list_id: 8
|
||||||
right: 2
|
right: 2
|
||||||
updated: 0
|
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
|
created: 0
|
|
@ -31,3 +31,27 @@
|
||||||
team_id: 7
|
team_id: 7
|
||||||
user_id: 1
|
user_id: 1
|
||||||
created: 0
|
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
|
||||||
|
|
|
@ -32,3 +32,21 @@
|
||||||
right: 2
|
right: 2
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 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
|
||||||
|
|
|
@ -19,4 +19,22 @@
|
||||||
created_by_id: 1
|
created_by_id: 1
|
||||||
- id: 7
|
- id: 7
|
||||||
name: testteam4_admin_on_namespace9
|
name: testteam4_admin_on_namespace9
|
||||||
created_by_id: 1
|
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
|
|
@ -46,3 +46,52 @@
|
||||||
is_active: true
|
is_active: true
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 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
|
||||||
|
|
|
@ -4,31 +4,45 @@
|
||||||
right: 0
|
right: 0
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 0
|
created: 0
|
||||||
|
|
||||||
- id: 2
|
- id: 2
|
||||||
user_id: 2
|
user_id: 2
|
||||||
list_id: 3
|
list_id: 3
|
||||||
right: 0
|
right: 0
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 0
|
created: 0
|
||||||
|
|
||||||
- id: 3
|
- id: 3
|
||||||
user_id: 1
|
user_id: 1
|
||||||
list_id: 9
|
list_id: 9
|
||||||
right: 0
|
right: 0
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 0
|
created: 0
|
||||||
|
|
||||||
- id: 4
|
- id: 4
|
||||||
user_id: 1
|
user_id: 1
|
||||||
list_id: 10
|
list_id: 10
|
||||||
right: 1
|
right: 1
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 0
|
created: 0
|
||||||
|
|
||||||
- id: 5
|
- id: 5
|
||||||
user_id: 1
|
user_id: 1
|
||||||
list_id: 11
|
list_id: 11
|
||||||
right: 2
|
right: 2
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 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
|
||||||
|
|
|
@ -32,3 +32,21 @@
|
||||||
right: 2
|
right: 2
|
||||||
updated: 0
|
updated: 0
|
||||||
created: 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
|
||||||
|
|
|
@ -40,7 +40,7 @@ func TestList_ReadAll(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(lists3).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(lists3).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(lists3)
|
s := reflect.ValueOf(lists3)
|
||||||
assert.Equal(t, 15, s.Len())
|
assert.Equal(t, 16, s.Len())
|
||||||
|
|
||||||
// Try getting lists for a nonexistant user
|
// Try getting lists for a nonexistant user
|
||||||
_, err = lists2.ReadAll("", &User{ID: 984234}, 1)
|
_, err = lists2.ReadAll("", &User{ID: 984234}, 1)
|
||||||
|
|
|
@ -59,7 +59,7 @@ func TestTeam_Create(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(ts).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(ts).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(ts)
|
s := reflect.ValueOf(ts)
|
||||||
assert.Equal(t, 8, s.Len())
|
assert.Equal(t, 9, s.Len())
|
||||||
|
|
||||||
// Check inserting it with an empty name
|
// Check inserting it with an empty name
|
||||||
dummyteam.Name = ""
|
dummyteam.Name = ""
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package models
|
package models
|
||||||
|
|
||||||
|
import "github.com/go-xorm/builder"
|
||||||
|
|
||||||
// ListUsers returns a list with all users, filtered by an optional searchstring
|
// ListUsers returns a list with all users, filtered by an optional searchstring
|
||||||
func ListUsers(searchterm string) (users []User, err error) {
|
func ListUsers(searchterm string) (users []User, err error) {
|
||||||
|
|
||||||
|
@ -33,3 +35,89 @@ func ListUsers(searchterm string) (users []User, err error) {
|
||||||
|
|
||||||
return users, nil
|
return users, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListUIDs hold all kinds of user IDs from accounts who have somehow access to a list
|
||||||
|
type ListUIDs struct {
|
||||||
|
ListOwnerID int64 `xorm:"listOwner"`
|
||||||
|
NamespaceUserID int64 `xorm:"unID"`
|
||||||
|
ListUserID int64 `xorm:"ulID"`
|
||||||
|
NamespaceOwnerUserID int64 `xorm:"nOwner"`
|
||||||
|
TeamNamespaceUserID int64 `xorm:"tnUID"`
|
||||||
|
TeamListUserID int64 `xorm:"tlUID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListUsersFromList returns a list with all users who have access to a list, regardless of the method which gave them access
|
||||||
|
func ListUsersFromList(l *List, search string) (users []*User, err error) {
|
||||||
|
|
||||||
|
userids := []*ListUIDs{}
|
||||||
|
|
||||||
|
err = x.
|
||||||
|
Select(`l.owner_id as listOwner,
|
||||||
|
un.user_id as unID,
|
||||||
|
ul.user_id as ulID,
|
||||||
|
n.owner_id as nOwner,
|
||||||
|
tm.user_id as tnUID,
|
||||||
|
tm2.user_id as tlUID`).
|
||||||
|
Table("list").
|
||||||
|
Alias("l").
|
||||||
|
// User stuff
|
||||||
|
Join("LEFT", []string{"users_namespace", "un"}, "un.namespace_id = l.namespace_id").
|
||||||
|
Join("LEFT", []string{"users_list", "ul"}, "ul.list_id = l.id").
|
||||||
|
Join("LEFT", []string{"namespaces", "n"}, "n.id = l.namespace_id").
|
||||||
|
// Team stuff
|
||||||
|
Join("LEFT", []string{"team_namespaces", "tn"}, " l.namespace_id = tn.namespace_id").
|
||||||
|
Join("LEFT", []string{"team_members", "tm"}, "tm.team_id = tn.team_id").
|
||||||
|
Join("LEFT", []string{"team_list", "tl"}, "l.id = tl.list_id").
|
||||||
|
Join("LEFT", []string{"team_members", "tm2"}, "tm2.team_id = tl.team_id").
|
||||||
|
// The actual condition
|
||||||
|
Where(
|
||||||
|
builder.Or(
|
||||||
|
builder.Or(builder.Eq{"ul.right": RightRead}),
|
||||||
|
builder.Or(builder.Eq{"un.right": RightRead}),
|
||||||
|
builder.Or(builder.Eq{"tl.right": RightRead}),
|
||||||
|
builder.Or(builder.Eq{"tn.right": RightRead}),
|
||||||
|
|
||||||
|
builder.Or(builder.Eq{"ul.right": RightWrite}),
|
||||||
|
builder.Or(builder.Eq{"un.right": RightWrite}),
|
||||||
|
builder.Or(builder.Eq{"tl.right": RightWrite}),
|
||||||
|
builder.Or(builder.Eq{"tn.right": RightWrite}),
|
||||||
|
|
||||||
|
builder.Or(builder.Eq{"ul.right": RightAdmin}),
|
||||||
|
builder.Or(builder.Eq{"un.right": RightAdmin}),
|
||||||
|
builder.Or(builder.Eq{"tl.right": RightAdmin}),
|
||||||
|
builder.Or(builder.Eq{"tn.right": RightAdmin}),
|
||||||
|
),
|
||||||
|
builder.Eq{"l.id": l.ID},
|
||||||
|
).
|
||||||
|
Find(&userids)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove duplicates from the list of ids and make it a slice
|
||||||
|
uidmap := make(map[int64]bool)
|
||||||
|
uidmap[l.OwnerID] = true
|
||||||
|
for _, u := range userids {
|
||||||
|
uidmap[u.ListUserID] = true
|
||||||
|
uidmap[u.NamespaceOwnerUserID] = true
|
||||||
|
uidmap[u.NamespaceUserID] = true
|
||||||
|
uidmap[u.TeamListUserID] = true
|
||||||
|
uidmap[u.TeamNamespaceUserID] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
uids := make([]int64, len(uidmap))
|
||||||
|
for id := range uidmap {
|
||||||
|
uids = append(uids, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all users
|
||||||
|
err = x.
|
||||||
|
Table("users").
|
||||||
|
Select("*").
|
||||||
|
In("id", uids).
|
||||||
|
And("username LIKE ?", "%"+search+"%").
|
||||||
|
GroupBy("id").
|
||||||
|
OrderBy("id").
|
||||||
|
Find(&users)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
159
pkg/models/users_list_test.go
Normal file
159
pkg/models/users_list_test.go
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"gopkg.in/d4l3k/messagediff.v1"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestListUsersFromList(t *testing.T) {
|
||||||
|
|
||||||
|
err := LoadFixtures()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
testuser1 := &User{
|
||||||
|
ID: 1,
|
||||||
|
Username: "user1",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "111d68d06e2d317b5a59c2c6c5bad808",
|
||||||
|
}
|
||||||
|
testuser2 := &User{
|
||||||
|
ID: 2,
|
||||||
|
Username: "user2",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
AvatarURL: "ab53a2911ddf9b4817ac01ddcd3d975f",
|
||||||
|
}
|
||||||
|
testuser3 := &User{
|
||||||
|
ID: 3,
|
||||||
|
Username: "user3",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
AvatarURL: "97d6d9441ff85fdc730e02a6068d267b",
|
||||||
|
PasswordResetToken: "passwordresettesttoken",
|
||||||
|
}
|
||||||
|
testuser4 := &User{
|
||||||
|
ID: 4,
|
||||||
|
Username: "user4",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: false,
|
||||||
|
AvatarURL: "7e65550957227bd38fe2d7fbc6fd2f7b",
|
||||||
|
EmailConfirmToken: "tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael",
|
||||||
|
}
|
||||||
|
testuser5 := &User{
|
||||||
|
ID: 5,
|
||||||
|
Username: "user5",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: false,
|
||||||
|
AvatarURL: "cfa35b8cd2ec278026357769582fa563",
|
||||||
|
EmailConfirmToken: "tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael",
|
||||||
|
}
|
||||||
|
testuser6 := &User{
|
||||||
|
ID: 6,
|
||||||
|
Username: "user6",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "3efbe51f864c6666bc27caf4c6ff90ed",
|
||||||
|
}
|
||||||
|
testuser7 := &User{
|
||||||
|
ID: 7,
|
||||||
|
Username: "user7",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "e80a711d4de44c30054806ebbd488464",
|
||||||
|
}
|
||||||
|
testuser8 := &User{
|
||||||
|
ID: 8,
|
||||||
|
Username: "user8",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "2b9b320416cd31020bb6844c3fadefd1",
|
||||||
|
}
|
||||||
|
testuser9 := &User{
|
||||||
|
ID: 9,
|
||||||
|
Username: "user9",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "f784fdb21d26dd2c64f5135f35ec401f",
|
||||||
|
}
|
||||||
|
testuser10 := &User{
|
||||||
|
ID: 10,
|
||||||
|
Username: "user10",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "fce8ff4ff56d75ad587d1bbaa5ef0563",
|
||||||
|
}
|
||||||
|
testuser11 := &User{
|
||||||
|
ID: 11,
|
||||||
|
Username: "user11",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "ad6d67d0c4495e186010732a7d360028",
|
||||||
|
}
|
||||||
|
testuser12 := &User{
|
||||||
|
ID: 12,
|
||||||
|
Username: "user12",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "ef1debc1364806281c42eeedfdeb943b",
|
||||||
|
}
|
||||||
|
testuser13 := &User{
|
||||||
|
ID: 13,
|
||||||
|
Username: "user13",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "b9e3f76032af53c9ff2df52d51ada717",
|
||||||
|
}
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
l *List
|
||||||
|
search string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantUsers []*User
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Check owner only",
|
||||||
|
args: args{l: &List{ID: 18, OwnerID: 7}},
|
||||||
|
wantUsers: []*User{testuser7},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// This list has another different user shared for each possible method
|
||||||
|
name: "Check with owner and other users",
|
||||||
|
args: args{l: &List{ID: 19, OwnerID: 7}},
|
||||||
|
wantUsers: []*User{
|
||||||
|
testuser1, // Shared Via Team readonly
|
||||||
|
testuser2, // Shared Via Team write
|
||||||
|
testuser3, // Shared Via Team admin
|
||||||
|
|
||||||
|
testuser4, // Shared Via User readonly
|
||||||
|
testuser5, // Shared Via User write
|
||||||
|
testuser6, // Shared Via User admin
|
||||||
|
|
||||||
|
testuser7, // Owner
|
||||||
|
|
||||||
|
testuser8, // Shared Via NamespaceTeam readonly
|
||||||
|
testuser9, // Shared Via NamespaceTeam write
|
||||||
|
testuser10, // Shared Via NamespaceTeam admin
|
||||||
|
|
||||||
|
testuser11, // Shared Via NamespaceUser readonly
|
||||||
|
testuser12, // Shared Via NamespaceUser write
|
||||||
|
testuser13, // Shared Via NamespaceUser admin
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
gotUsers, err := ListUsersFromList(tt.args.l, tt.args.search)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("ListUsersFromList() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if diff, equal := messagediff.PrettyDiff(tt.wantUsers, gotUsers); !equal {
|
||||||
|
t.Errorf("Test %s, LabelTask.ReadAll() = %v, want %v, \ndiff: %v", tt.name, gotUsers, tt.wantUsers, diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"code.vikunja.io/web/handler"
|
"code.vikunja.io/web/handler"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UserList gets all information about a user
|
// UserList gets all information about a user
|
||||||
|
@ -49,3 +50,45 @@ func UserList(c echo.Context) error {
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, users)
|
return c.JSON(http.StatusOK, users)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListUsersForList returns a list with all users who have access to a list, regardless of the method the list was shared with them.
|
||||||
|
// @Summary Get users
|
||||||
|
// @Description Lists all users (without emailadresses). Also possible to search for a specific user.
|
||||||
|
// @tags list
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param s query string false "Search for a user by its name."
|
||||||
|
// @Security JWTKeyAuth
|
||||||
|
// @Param id path int true "List ID"
|
||||||
|
// @Success 200 {array} models.User "All (found) users."
|
||||||
|
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Something's invalid."
|
||||||
|
// @Failure 401 {object} code.vikunja.io/web.HTTPError "The user does not have the right to see the list."
|
||||||
|
// @Failure 500 {object} models.Message "Internal server error."
|
||||||
|
// @Router /lists/{id}/listusers [get]
|
||||||
|
func ListUsersForList(c echo.Context) error {
|
||||||
|
listID, err := strconv.ParseInt(c.Param("list"), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return handler.HandleHTTPError(err, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
list := models.List{ID: listID}
|
||||||
|
currentUser, err := models.GetCurrentUser(c)
|
||||||
|
if err != nil {
|
||||||
|
return handler.HandleHTTPError(err, c)
|
||||||
|
}
|
||||||
|
canRead, err := list.CanRead(currentUser)
|
||||||
|
if err != nil {
|
||||||
|
return handler.HandleHTTPError(err, c)
|
||||||
|
}
|
||||||
|
if !canRead {
|
||||||
|
return echo.ErrForbidden
|
||||||
|
}
|
||||||
|
|
||||||
|
s := c.QueryParam("s")
|
||||||
|
users, err := models.ListUsersFromList(&list, s)
|
||||||
|
if err != nil {
|
||||||
|
return handler.HandleHTTPError(err, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, users)
|
||||||
|
}
|
||||||
|
|
|
@ -254,6 +254,7 @@ func registerAPIRoutes(a *echo.Group) {
|
||||||
a.POST("/lists/:list", listHandler.UpdateWeb)
|
a.POST("/lists/:list", listHandler.UpdateWeb)
|
||||||
a.DELETE("/lists/:list", listHandler.DeleteWeb)
|
a.DELETE("/lists/:list", listHandler.DeleteWeb)
|
||||||
a.PUT("/namespaces/:namespace/lists", listHandler.CreateWeb)
|
a.PUT("/namespaces/:namespace/lists", listHandler.CreateWeb)
|
||||||
|
a.GET("/lists/:list/listusers", apiv1.ListUsersForList)
|
||||||
|
|
||||||
taskHandler := &handler.WebHandler{
|
taskHandler := &handler.WebHandler{
|
||||||
EmptyStruct: func() handler.CObject {
|
EmptyStruct: func() handler.CObject {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
// This file was generated by swaggo/swag at
|
// This file was generated by swaggo/swag at
|
||||||
// 2019-07-16 00:32:48.008049583 +0200 CEST m=+0.169009519
|
// 2019-07-18 18:18:32.365544639 +0200 CEST m=+0.166364676
|
||||||
|
|
||||||
package swagger
|
package swagger
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ var doc = `{
|
||||||
"JWTKeyAuth": []
|
"JWTKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Returns an array with all assignees for this task.",
|
"description": "Returns all labels which are either created by the user or associated with a task the user has at least read-access to.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
@ -66,9 +66,9 @@ var doc = `{
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"assignees"
|
"labels"
|
||||||
],
|
],
|
||||||
"summary": "Get all assignees for a task",
|
"summary": "Get all labels a user has access to",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
@ -78,18 +78,18 @@ var doc = `{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Search assignees by their username.",
|
"description": "Search labels by label text.",
|
||||||
"name": "s",
|
"name": "s",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "The assignees",
|
"description": "The labels",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/models.Label"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -412,7 +412,7 @@ var doc = `{
|
||||||
"JWTKeyAuth": []
|
"JWTKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Returns a list by its ID.",
|
"description": "Returns a team by its ID.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
@ -420,13 +420,13 @@ var doc = `{
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"list"
|
"team"
|
||||||
],
|
],
|
||||||
"summary": "Gets one list",
|
"summary": "Gets one team",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "List ID",
|
"description": "Team ID",
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
@ -434,14 +434,14 @@ var doc = `{
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "The list",
|
"description": "The team",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.List"
|
"$ref": "#/definitions/models.Team"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"403": {
|
"403": {
|
||||||
"description": "The user does not have access to the list",
|
"description": "The user does not have access to the team",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/code.vikunja.io.web.HTTPError"
|
"$ref": "#/definitions/code.vikunja.io.web.HTTPError"
|
||||||
|
@ -645,6 +645,73 @@ var doc = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/lists/{id}/listusers": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"JWTKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Lists all users (without emailadresses). Also possible to search for a specific user.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"list"
|
||||||
|
],
|
||||||
|
"summary": "Get users",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Search for a user by its name.",
|
||||||
|
"name": "s",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "List ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "All (found) users.",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/models.User"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Something's invalid.",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/code.vikunja.io.web.HTTPError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "The user does not have the right to see the list.",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/code.vikunja.io.web.HTTPError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal server error.",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/models.Message"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/lists/{id}/teams": {
|
"/lists/{id}/teams": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
"JWTKeyAuth": []
|
"JWTKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Returns an array with all assignees for this task.",
|
"description": "Returns all labels which are either created by the user or associated with a task the user has at least read-access to.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
@ -53,9 +53,9 @@
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"assignees"
|
"labels"
|
||||||
],
|
],
|
||||||
"summary": "Get all assignees for a task",
|
"summary": "Get all labels a user has access to",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
@ -65,18 +65,18 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Search assignees by their username.",
|
"description": "Search labels by label text.",
|
||||||
"name": "s",
|
"name": "s",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "The assignees",
|
"description": "The labels",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/models.Label"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -399,7 +399,7 @@
|
||||||
"JWTKeyAuth": []
|
"JWTKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Returns a list by its ID.",
|
"description": "Returns a team by its ID.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
@ -407,13 +407,13 @@
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"list"
|
"team"
|
||||||
],
|
],
|
||||||
"summary": "Gets one list",
|
"summary": "Gets one team",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "List ID",
|
"description": "Team ID",
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
@ -421,14 +421,14 @@
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "The list",
|
"description": "The team",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.List"
|
"$ref": "#/definitions/models.Team"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"403": {
|
"403": {
|
||||||
"description": "The user does not have access to the list",
|
"description": "The user does not have access to the team",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/code.vikunja.io/web.HTTPError"
|
"$ref": "#/definitions/code.vikunja.io/web.HTTPError"
|
||||||
|
@ -632,6 +632,73 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/lists/{id}/listusers": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"JWTKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Lists all users (without emailadresses). Also possible to search for a specific user.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"list"
|
||||||
|
],
|
||||||
|
"summary": "Get users",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Search for a user by its name.",
|
||||||
|
"name": "s",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "List ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "All (found) users.",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/models.User"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Something's invalid.",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/code.vikunja.io/web.HTTPError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "The user does not have the right to see the list.",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/code.vikunja.io/web.HTTPError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal server error.",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/models.Message"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/lists/{id}/teams": {
|
"/lists/{id}/teams": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
|
|
|
@ -704,14 +704,15 @@ paths:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: Returns an array with all assignees for this task.
|
description: Returns all labels which are either created by the user or associated
|
||||||
|
with a task the user has at least read-access to.
|
||||||
parameters:
|
parameters:
|
||||||
- description: The page number. Used for pagination. If not provided, the first
|
- description: The page number. Used for pagination. If not provided, the first
|
||||||
page of results is returned.
|
page of results is returned.
|
||||||
in: query
|
in: query
|
||||||
name: p
|
name: p
|
||||||
type: integer
|
type: integer
|
||||||
- description: Search assignees by their username.
|
- description: Search labels by label text.
|
||||||
in: query
|
in: query
|
||||||
name: s
|
name: s
|
||||||
type: string
|
type: string
|
||||||
|
@ -719,10 +720,10 @@ paths:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: The assignees
|
description: The labels
|
||||||
schema:
|
schema:
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/models.User'
|
$ref: '#/definitions/models.Label'
|
||||||
type: array
|
type: array
|
||||||
"500":
|
"500":
|
||||||
description: Internal error
|
description: Internal error
|
||||||
|
@ -731,9 +732,9 @@ paths:
|
||||||
type: object
|
type: object
|
||||||
security:
|
security:
|
||||||
- JWTKeyAuth: []
|
- JWTKeyAuth: []
|
||||||
summary: Get all assignees for a task
|
summary: Get all labels a user has access to
|
||||||
tags:
|
tags:
|
||||||
- assignees
|
- labels
|
||||||
put:
|
put:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
|
@ -977,9 +978,9 @@ paths:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: Returns a list by its ID.
|
description: Returns a team by its ID.
|
||||||
parameters:
|
parameters:
|
||||||
- description: List ID
|
- description: Team ID
|
||||||
in: path
|
in: path
|
||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
|
@ -988,12 +989,12 @@ paths:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: The list
|
description: The team
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/models.List'
|
$ref: '#/definitions/models.Team'
|
||||||
type: object
|
type: object
|
||||||
"403":
|
"403":
|
||||||
description: The user does not have access to the list
|
description: The user does not have access to the team
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/code.vikunja.io/web.HTTPError'
|
$ref: '#/definitions/code.vikunja.io/web.HTTPError'
|
||||||
type: object
|
type: object
|
||||||
|
@ -1004,9 +1005,9 @@ paths:
|
||||||
type: object
|
type: object
|
||||||
security:
|
security:
|
||||||
- JWTKeyAuth: []
|
- JWTKeyAuth: []
|
||||||
summary: Gets one list
|
summary: Gets one team
|
||||||
tags:
|
tags:
|
||||||
- list
|
- team
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
|
@ -1097,6 +1098,51 @@ paths:
|
||||||
summary: Create a task
|
summary: Create a task
|
||||||
tags:
|
tags:
|
||||||
- task
|
- task
|
||||||
|
/lists/{id}/listusers:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Lists all users (without emailadresses). Also possible to search
|
||||||
|
for a specific user.
|
||||||
|
parameters:
|
||||||
|
- description: Search for a user by its name.
|
||||||
|
in: query
|
||||||
|
name: s
|
||||||
|
type: string
|
||||||
|
- description: List ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: All (found) users.
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/models.User'
|
||||||
|
type: array
|
||||||
|
"400":
|
||||||
|
description: Something's invalid.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/code.vikunja.io/web.HTTPError'
|
||||||
|
type: object
|
||||||
|
"401":
|
||||||
|
description: The user does not have the right to see the list.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/code.vikunja.io/web.HTTPError'
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal server error.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.Message'
|
||||||
|
type: object
|
||||||
|
security:
|
||||||
|
- JWTKeyAuth: []
|
||||||
|
summary: Get users
|
||||||
|
tags:
|
||||||
|
- list
|
||||||
/lists/{id}/teams:
|
/lists/{id}/teams:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
Loading…
Reference in a new issue