Rights performance improvements for lists and namespaces #54
18
docs/docs.go
18
docs/docs.go
|
@ -1,6 +1,6 @@
|
|||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
// This file was generated by swaggo/swag at
|
||||
// 2019-01-14 23:02:47.994258682 +0100 CET m=+0.170768570
|
||||
// 2019-01-18 12:59:51.359642373 +0100 CET m=+0.125821859
|
||||
|
||||
package docs
|
||||
|
||||
|
@ -14,7 +14,7 @@ import (
|
|||
var doc = `{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "\u003c!-- ReDoc-Inject: \u003csecurity-definitions\u003e --\u003e",
|
||||
"description": "This is the documentation for the [Vikunja](http://vikunja.io) API. Vikunja is a cross-plattform Todo-application with a lot of features, such as sharing lists with users or teams. \u003c!-- ReDoc-Inject: \u003csecurity-definitions\u003e --\u003e\n# Authorization\n**JWT-Auth:** Main authorization method, used for most of the requests. Needs ` + "`" + `Authorization: Bearer \u003cjwt-token\u003e` + "`" + `-header to authenticate successfully.\n\n**BasicAuth:** Only used when requesting tasks via caldav.\n\u003c!-- ReDoc-Inject: \u003csecurity-definitions\u003e --\u003e",
|
||||
"title": "Vikunja API",
|
||||
"contact": {
|
||||
"name": "General Vikunja contact",
|
||||
|
@ -391,7 +391,7 @@ var doc = `{
|
|||
"JWTKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Returns a list by its ID.",
|
||||
"description": "Returns a team by its ID.",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
|
@ -399,13 +399,13 @@ var doc = `{
|
|||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"list"
|
||||
"team"
|
||||
],
|
||||
"summary": "Gets one list",
|
||||
"summary": "Gets one team",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "List ID",
|
||||
"description": "Team ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
|
@ -413,14 +413,14 @@ var doc = `{
|
|||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The list",
|
||||
"description": "The team",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/models.List"
|
||||
"$ref": "#/definitions/models.Team"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "The user does not have access to the list",
|
||||
"description": "The user does not have access to the team",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/code.vikunja.io.web.HTTPError"
|
||||
|
|
|
@ -24,14 +24,12 @@ This document describes the different errors Vikunja can return.
|
|||
| 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 list right is invalid. |
|
||||
| 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 | 403 | The namespace right is invalid. |
|
||||
| 6001 | 400 | The team name cannot be emtpy. |
|
||||
| 6002 | 404 | The team does not exist. |
|
||||
| 6003 | 400 | The provided team right is invalid. |
|
||||
|
@ -39,9 +37,9 @@ This document describes the different errors Vikunja can return.
|
|||
| 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. |
|
||||
| 7001 | 400 | The user right is invalid. |
|
||||
| 7002 | 409 | The user already has access to that list. |
|
||||
| 7003 | 403 | The user does not have access to that list. |
|
||||
| 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. |
|
||||
| 8003 | 403 | The user does not have access to this label. |
|
||||
| 9001 | 403 | The right is invalid. |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "\u003c!-- ReDoc-Inject: \u003csecurity-definitions\u003e --\u003e",
|
||||
"description": "This is the documentation for the [Vikunja](http://vikunja.io) API. Vikunja is a cross-plattform Todo-application with a lot of features, such as sharing lists with users or teams. \u003c!-- ReDoc-Inject: \u003csecurity-definitions\u003e --\u003e\n# Authorization\n**JWT-Auth:** Main authorization method, used for most of the requests. Needs ` + \"`\" + `Authorization: Bearer \u003cjwt-token\u003e` + \"`\" + `-header to authenticate successfully.\n\n**BasicAuth:** Only used when requesting tasks via caldav.\n\u003c!-- ReDoc-Inject: \u003csecurity-definitions\u003e --\u003e",
|
||||
"title": "Vikunja API",
|
||||
"contact": {
|
||||
"name": "General Vikunja contact",
|
||||
|
@ -378,7 +378,7 @@
|
|||
"JWTKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Returns a list by its ID.",
|
||||
"description": "Returns a team by its ID.",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
|
@ -386,13 +386,13 @@
|
|||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"list"
|
||||
"team"
|
||||
],
|
||||
"summary": "Gets one list",
|
||||
"summary": "Gets one team",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "List ID",
|
||||
"description": "Team ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
|
@ -400,14 +400,14 @@
|
|||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The list",
|
||||
"description": "The team",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/models.List"
|
||||
"$ref": "#/definitions/models.Team"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "The user does not have access to the list",
|
||||
"description": "The user does not have access to the team",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/code.vikunja.io/web.HTTPError"
|
||||
|
|
|
@ -622,7 +622,13 @@ info:
|
|||
email: hello@vikunja.io
|
||||
name: General Vikunja contact
|
||||
url: http://vikunja.io/en/contact/
|
||||
description: '<!-- ReDoc-Inject: <security-definitions> -->'
|
||||
description: |-
|
||||
This is the documentation for the [Vikunja](http://vikunja.io) API. Vikunja is a cross-plattform Todo-application with a lot of features, such as sharing lists with users or teams. <!-- ReDoc-Inject: <security-definitions> -->
|
||||
# Authorization
|
||||
**JWT-Auth:** Main authorization method, used for most of the requests. Needs ` + "`" + `Authorization: Bearer <jwt-token>` + "`" + `-header to authenticate successfully.
|
||||
|
||||
**BasicAuth:** Only used when requesting tasks via caldav.
|
||||
<!-- ReDoc-Inject: <security-definitions> -->
|
||||
license:
|
||||
name: GPLv3
|
||||
url: http://code.vikunja.io/api/src/branch/master/LICENSE
|
||||
|
@ -906,9 +912,9 @@ paths:
|
|||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Returns a list by its ID.
|
||||
description: Returns a team by its ID.
|
||||
parameters:
|
||||
- description: List ID
|
||||
- description: Team ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
|
@ -917,12 +923,12 @@ paths:
|
|||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: The list
|
||||
description: The team
|
||||
schema:
|
||||
$ref: '#/definitions/models.List'
|
||||
$ref: '#/definitions/models.Team'
|
||||
type: object
|
||||
"403":
|
||||
description: The user does not have access to the list
|
||||
description: The user does not have access to the team
|
||||
schema:
|
||||
$ref: '#/definitions/code.vikunja.io/web.HTTPError'
|
||||
type: object
|
||||
|
@ -933,9 +939,9 @@ paths:
|
|||
type: object
|
||||
security:
|
||||
- JWTKeyAuth: []
|
||||
summary: Gets one list
|
||||
summary: Gets one team
|
||||
tags:
|
||||
- list
|
||||
- team
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
|
|
|
@ -502,29 +502,6 @@ func (err ErrNoRightToSeeTask) HTTPError() web.HTTPError {
|
|||
}
|
||||
}
|
||||
|
||||
// ErrInvalidListRight represents an error where a list right is invalid
|
||||
type ErrInvalidListRight struct {
|
||||
Right ListRight
|
||||
}
|
||||
|
||||
// IsErrInvalidListRight checks if an error is ErrInvalidListRight.
|
||||
func IsErrInvalidListRight(err error) bool {
|
||||
_, ok := err.(ErrInvalidListRight)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrInvalidListRight) Error() string {
|
||||
return fmt.Sprintf("List right is invalid [Right: %d]", err.Right)
|
||||
}
|
||||
|
||||
// ErrCodeInvalidListRight holds the unique world-error code of this error
|
||||
const ErrCodeInvalidListRight = 4006
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrInvalidListRight) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeInvalidListRight, Message: "The list right is invalid."}
|
||||
}
|
||||
|
||||
// =================
|
||||
// Namespace errors
|
||||
// =================
|
||||
|
@ -672,33 +649,6 @@ func (err ErrUserAlreadyHasNamespaceAccess) HTTPError() web.HTTPError {
|
|||
return web.HTTPError{HTTPCode: http.StatusConflict, Code: ErrCodeUserAlreadyHasNamespaceAccess, Message: "This user already has access to this namespace."}
|
||||
}
|
||||
|
||||
// ErrInvalidNamespaceRight represents an error where a namespace right is invalid
|
||||
type ErrInvalidNamespaceRight struct {
|
||||
Right NamespaceRight
|
||||
}
|
||||
|
||||
// IsErrInvalidNamespaceRight checks if an error is ErrInvalidNamespaceRight.
|
||||
func IsErrInvalidNamespaceRight(err error) bool {
|
||||
_, ok := err.(ErrInvalidNamespaceRight)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrInvalidNamespaceRight) Error() string {
|
||||
return fmt.Sprintf("Namespace right is invalid [Right: %d]", err.Right)
|
||||
}
|
||||
|
||||
// ErrCodeInvalidNamespaceRight holds the unique world-error code of this error
|
||||
const ErrCodeInvalidNamespaceRight = 5012
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrInvalidNamespaceRight) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{
|
||||
HTTPCode: http.StatusBadRequest,
|
||||
Code: ErrCodeInvalidNamespaceRight,
|
||||
Message: "The namespace right is invalid.",
|
||||
}
|
||||
}
|
||||
|
||||
// ============
|
||||
// Team errors
|
||||
// ============
|
||||
|
@ -749,29 +699,6 @@ func (err ErrTeamDoesNotExist) HTTPError() web.HTTPError {
|
|||
return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."}
|
||||
}
|
||||
|
||||
// ErrInvalidTeamRight represents an error where a team right is invalid
|
||||
type ErrInvalidTeamRight struct {
|
||||
Right TeamRight
|
||||
}
|
||||
|
||||
// IsErrInvalidTeamRight checks if an error is ErrInvalidTeamRight.
|
||||
func IsErrInvalidTeamRight(err error) bool {
|
||||
_, ok := err.(ErrInvalidTeamRight)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrInvalidTeamRight) Error() string {
|
||||
return fmt.Sprintf("Team right invalid [Right: %d]", err.Right)
|
||||
}
|
||||
|
||||
// ErrCodeInvalidTeamRight holds the unique world-error code of this error
|
||||
const ErrCodeInvalidTeamRight = 6003
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrInvalidTeamRight) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeInvalidTeamRight, Message: "The team right is invalid."}
|
||||
}
|
||||
|
||||
// ErrTeamAlreadyHasAccess represents an error where a team already has access to a list/namespace
|
||||
type ErrTeamAlreadyHasAccess struct {
|
||||
TeamID int64
|
||||
|
@ -872,29 +799,6 @@ func (err ErrTeamDoesNotHaveAccessToList) HTTPError() web.HTTPError {
|
|||
// User <-> List errors
|
||||
// ====================
|
||||
|
||||
// ErrInvalidUserRight represents an error where a user right is invalid
|
||||
type ErrInvalidUserRight struct {
|
||||
Right UserRight
|
||||
}
|
||||
|
||||
// IsErrInvalidUserRight checks if an error is ErrInvalidUserRight.
|
||||
func IsErrInvalidUserRight(err error) bool {
|
||||
_, ok := err.(ErrInvalidUserRight)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrInvalidUserRight) Error() string {
|
||||
return fmt.Sprintf("User right is invalid [Right: %d]", err.Right)
|
||||
}
|
||||
|
||||
// ErrCodeInvalidUserRight holds the unique world-error code of this error
|
||||
const ErrCodeInvalidUserRight = 7001
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrInvalidUserRight) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeInvalidUserRight, Message: "The user right is invalid."}
|
||||
}
|
||||
|
||||
// ErrUserAlreadyHasAccess represents an error where a user already has access to a list/namespace
|
||||
type ErrUserAlreadyHasAccess struct {
|
||||
UserID int64
|
||||
|
@ -1029,3 +933,34 @@ func (err ErrUserHasNoAccessToLabel) HTTPError() web.HTTPError {
|
|||
Message: "You don't have access to this label.",
|
||||
}
|
||||
}
|
||||
|
||||
// ========
|
||||
// Rights
|
||||
// ========
|
||||
|
||||
// ErrInvalidRight represents an error where a right is invalid
|
||||
type ErrInvalidRight struct {
|
||||
Right Right
|
||||
}
|
||||
|
||||
// IsErrInvalidRight checks if an error is ErrInvalidRight.
|
||||
func IsErrInvalidRight(err error) bool {
|
||||
_, ok := err.(ErrInvalidRight)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrInvalidRight) Error() string {
|
||||
return fmt.Sprintf(" right invalid [Right: %d]", err.Right)
|
||||
}
|
||||
|
||||
// ErrCodeInvalidRight holds the unique world-error code of this error
|
||||
const ErrCodeInvalidRight = 9001
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrInvalidRight) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{
|
||||
HTTPCode: http.StatusBadRequest,
|
||||
Code: ErrCodeInvalidRight,
|
||||
Message: "The right is invalid.",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ func (l *List) CanWrite(a web.Auth) bool {
|
|||
|
||||
// Check all the things
|
||||
// Check if the user is either owner or can write to the list
|
||||
return l.isOwner(user) || l.checkRight(user, ListRightWrite, ListRightAdmin)
|
||||
return l.isOwner(user) || l.checkRight(user, RightWrite, RightAdmin)
|
||||
}
|
||||
|
||||
// CanRead checks if a user has read access to a list
|
||||
|
@ -37,7 +37,7 @@ func (l *List) CanRead(a web.Auth) bool {
|
|||
|
||||
// Check all the things
|
||||
// Check if the user is either owner or can read
|
||||
return l.isOwner(user) || l.checkRight(user, ListRightRead, ListRightWrite, ListRightAdmin)
|
||||
return l.isOwner(user) || l.checkRight(user, RightRead, RightWrite, RightAdmin)
|
||||
}
|
||||
|
||||
// CanUpdate checks if the user can update a list
|
||||
|
@ -64,7 +64,7 @@ func (l *List) IsAdmin(a web.Auth) bool {
|
|||
// Check all the things
|
||||
// Check if the user is either owner or can write to the list
|
||||
// Owners are always admins
|
||||
return l.isOwner(user) || l.checkRight(user, ListRightAdmin)
|
||||
return l.isOwner(user) || l.checkRight(user, RightAdmin)
|
||||
}
|
||||
|
||||
// Little helper function to check if a user is list owner
|
||||
|
@ -73,7 +73,7 @@ func (l *List) isOwner(u *User) bool {
|
|||
}
|
||||
|
||||
// Checks n different rights for any given user
|
||||
func (l *List) checkRight(user *User, rights ...ListRight) bool {
|
||||
func (l *List) checkRight(user *User, rights ...Right) bool {
|
||||
|
||||
/*
|
||||
The following loop creates an sql condition like this one:
|
||||
|
@ -139,29 +139,3 @@ func (l *List) checkRight(user *User, rights ...ListRight) bool {
|
|||
|
||||
return exists
|
||||
}
|
||||
|
||||
// ListRight defines the rights users/teams can have for lists
|
||||
type ListRight int
|
||||
|
||||
// define unknown list right
|
||||
const (
|
||||
ListRightUnknown = -1
|
||||
)
|
||||
|
||||
// Enumerate all the list rights
|
||||
const (
|
||||
// Can read lists
|
||||
ListRightRead ListRight = iota
|
||||
// Can write/edit tasks in a list
|
||||
ListRightWrite
|
||||
// Can manage a list, can do everything
|
||||
ListRightAdmin
|
||||
)
|
||||
|
||||
func (r ListRight) isValid() error {
|
||||
if r != ListRightAdmin && r != ListRightRead && r != ListRightWrite {
|
||||
return ErrInvalidListRight{r}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ type ListUser struct {
|
|||
// The list id.
|
||||
ListID int64 `xorm:"int(11) not null INDEX" json:"-" param:"list"`
|
||||
// The right this user has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details.
|
||||
Right UserRight `xorm:"int(11) INDEX" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
Right Right `xorm:"int(11) INDEX" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
|
||||
// A unix timestamp when this relation was created. You cannot change this value.
|
||||
Created int64 `xorm:"created" json:"created"`
|
||||
|
@ -46,5 +46,5 @@ func (ListUser) TableName() string {
|
|||
// UserWithRight represents a user in combination with the right it can have on a list/namespace
|
||||
type UserWithRight struct {
|
||||
User `xorm:"extends"`
|
||||
Right UserRight `json:"right"`
|
||||
Right Right `json:"right"`
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ func TestListUser_CanDoSomething(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
ListID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
|
|
@ -29,7 +29,7 @@ func TestListUser_Create(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
ListID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -69,7 +69,7 @@ func TestListUser_Create(t *testing.T) {
|
|||
Right: 500,
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrInvalidUserRight,
|
||||
errType: IsErrInvalidRight,
|
||||
},
|
||||
{
|
||||
name: "ListUsers Create with inexisting list",
|
||||
|
@ -127,7 +127,7 @@ func TestListUser_ReadAll(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
ListID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -162,7 +162,7 @@ func TestListUser_ReadAll(t *testing.T) {
|
|||
Password: "1234",
|
||||
Email: "user1@example.com",
|
||||
},
|
||||
Right: UserRightRead,
|
||||
Right: RightRead,
|
||||
},
|
||||
{
|
||||
User: User{
|
||||
|
@ -171,7 +171,7 @@ func TestListUser_ReadAll(t *testing.T) {
|
|||
Password: "1234",
|
||||
Email: "user2@example.com",
|
||||
},
|
||||
Right: UserRightRead,
|
||||
Right: RightRead,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -218,7 +218,7 @@ func TestListUser_Update(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
ListID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -235,7 +235,7 @@ func TestListUser_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
ListID: 3,
|
||||
UserID: 1,
|
||||
Right: UserRightAdmin,
|
||||
Right: RightAdmin,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -243,7 +243,7 @@ func TestListUser_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
ListID: 3,
|
||||
UserID: 1,
|
||||
Right: UserRightWrite,
|
||||
Right: RightWrite,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -251,7 +251,7 @@ func TestListUser_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
ListID: 3,
|
||||
UserID: 1,
|
||||
Right: UserRightRead,
|
||||
Right: RightRead,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -262,7 +262,7 @@ func TestListUser_Update(t *testing.T) {
|
|||
Right: 500,
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrInvalidUserRight,
|
||||
errType: IsErrInvalidRight,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
@ -293,7 +293,7 @@ func TestListUser_Delete(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
ListID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
|
|
@ -25,13 +25,13 @@ import (
|
|||
// CanWrite checks if a user has write access to a namespace
|
||||
func (n *Namespace) CanWrite(a web.Auth) bool {
|
||||
u := getUserForRights(a)
|
||||
return n.isOwner(u) || n.checkRight(u, NamespaceRightWrite, NamespaceRightAdmin)
|
||||
return n.isOwner(u) || n.checkRight(u, RightWrite, RightAdmin)
|
||||
}
|
||||
|
||||
// CanRead checks if a user has read access to that namespace
|
||||
func (n *Namespace) CanRead(a web.Auth) bool {
|
||||
u := getUserForRights(a)
|
||||
return n.isOwner(u) || n.checkRight(u, NamespaceRightRead, NamespaceRightWrite, NamespaceRightAdmin)
|
||||
return n.isOwner(u) || n.checkRight(u, RightRead, RightWrite, RightAdmin)
|
||||
}
|
||||
|
||||
// CanUpdate checks if the user can update the namespace
|
||||
|
@ -53,7 +53,7 @@ func (n *Namespace) CanCreate(a web.Auth) bool {
|
|||
// IsAdmin returns true or false if the user is admin on that namespace or not
|
||||
func (n *Namespace) IsAdmin(a web.Auth) bool {
|
||||
u := getUserForRights(a)
|
||||
return n.isOwner(u) || n.checkRight(u, NamespaceRightAdmin)
|
||||
return n.isOwner(u) || n.checkRight(u, RightAdmin)
|
||||
}
|
||||
|
||||
// Small helper function to check if a user owns the namespace
|
||||
|
@ -61,7 +61,7 @@ func (n *Namespace) isOwner(user *User) bool {
|
|||
return n.OwnerID == user.ID
|
||||
}
|
||||
|
||||
func (n *Namespace) checkRight(user *User, rights ...NamespaceRight) bool {
|
||||
func (n *Namespace) checkRight(user *User, rights ...Right) bool {
|
||||
|
||||
/*
|
||||
The following loop creates an sql condition like this one:
|
||||
|
@ -115,29 +115,3 @@ func (n *Namespace) checkRight(user *User, rights ...NamespaceRight) bool {
|
|||
|
||||
return exists
|
||||
}
|
||||
|
||||
// NamespaceRight defines the rights users/teams can have for namespaces
|
||||
type NamespaceRight int
|
||||
|
||||
// define unknown namespace right
|
||||
const (
|
||||
NamespaceRightUnknown = -1
|
||||
)
|
||||
|
||||
// Enumerate all the namespace rights
|
||||
const (
|
||||
// Can read namespaces
|
||||
NamespaceRightRead NamespaceRight = iota
|
||||
// Can write/edit tasks in a namespace
|
||||
NamespaceRightWrite
|
||||
// Can manage a namespace, can do everything
|
||||
NamespaceRightAdmin
|
||||
)
|
||||
|
||||
func (r NamespaceRight) isValid() error {
|
||||
if r != NamespaceRightAdmin && r != NamespaceRightRead && r != NamespaceRightWrite {
|
||||
return ErrInvalidNamespaceRight{r}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ type NamespaceUser struct {
|
|||
// The namespace id
|
||||
NamespaceID int64 `xorm:"int(11) not null INDEX" json:"-" param:"namespace"`
|
||||
// The right this user has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details.
|
||||
Right UserRight `xorm:"int(11) INDEX" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
Right Right `xorm:"int(11) INDEX" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
|
||||
// A unix timestamp when this relation was created. You cannot change this value.
|
||||
Created int64 `xorm:"created" json:"created"`
|
||||
|
|
|
@ -27,7 +27,7 @@ func TestNamespaceUser_CanDoSomething(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
NamespaceID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
|
|
@ -30,7 +30,7 @@ func TestNamespaceUser_Create(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
NamespaceID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -70,7 +70,7 @@ func TestNamespaceUser_Create(t *testing.T) {
|
|||
Right: 500,
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrInvalidUserRight,
|
||||
errType: IsErrInvalidRight,
|
||||
},
|
||||
{
|
||||
name: "NamespaceUsers Create with inexisting list",
|
||||
|
@ -128,7 +128,7 @@ func TestNamespaceUser_ReadAll(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
NamespaceID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -163,7 +163,7 @@ func TestNamespaceUser_ReadAll(t *testing.T) {
|
|||
Password: "1234",
|
||||
Email: "user1@example.com",
|
||||
},
|
||||
Right: UserRightRead,
|
||||
Right: RightRead,
|
||||
},
|
||||
{
|
||||
User: User{
|
||||
|
@ -172,7 +172,7 @@ func TestNamespaceUser_ReadAll(t *testing.T) {
|
|||
Password: "1234",
|
||||
Email: "user2@example.com",
|
||||
},
|
||||
Right: UserRightRead,
|
||||
Right: RightRead,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -220,7 +220,7 @@ func TestNamespaceUser_Update(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
NamespaceID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -237,7 +237,7 @@ func TestNamespaceUser_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
NamespaceID: 3,
|
||||
UserID: 1,
|
||||
Right: UserRightAdmin,
|
||||
Right: RightAdmin,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -245,7 +245,7 @@ func TestNamespaceUser_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
NamespaceID: 3,
|
||||
UserID: 1,
|
||||
Right: UserRightWrite,
|
||||
Right: RightWrite,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -253,7 +253,7 @@ func TestNamespaceUser_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
NamespaceID: 3,
|
||||
UserID: 1,
|
||||
Right: UserRightRead,
|
||||
Right: RightRead,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -264,7 +264,7 @@ func TestNamespaceUser_Update(t *testing.T) {
|
|||
Right: 500,
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrInvalidUserRight,
|
||||
errType: IsErrInvalidRight,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
@ -295,7 +295,7 @@ func TestNamespaceUser_Delete(t *testing.T) {
|
|||
ID int64
|
||||
UserID int64
|
||||
NamespaceID int64
|
||||
Right UserRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2018 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2019 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
|
||||
|
@ -16,27 +16,27 @@
|
|||
|
||||
package models
|
||||
|
||||
// TeamRight defines the rights teams can have for lists/namespaces
|
||||
type TeamRight int
|
||||
// Right defines the rights users/teams can have for lists/namespaces
|
||||
type Right int
|
||||
|
||||
// define unknown team right
|
||||
// define unknown right
|
||||
const (
|
||||
TeamRightUnknown = -1
|
||||
RightUnknown = -1
|
||||
)
|
||||
|
||||
// Enumerate all the team rights
|
||||
const (
|
||||
// Can read lists in a Team
|
||||
TeamRightRead TeamRight = iota
|
||||
// Can write tasks in a Team like lists and todo tasks. Cannot create new lists.
|
||||
TeamRightWrite
|
||||
// Can read lists in a
|
||||
RightRead Right = iota
|
||||
// Can write in a like lists and todo tasks. Cannot create new lists.
|
||||
RightWrite
|
||||
// Can manage a list/namespace, can do everything
|
||||
TeamRightAdmin
|
||||
RightAdmin
|
||||
)
|
||||
|
||||
func (r TeamRight) isValid() error {
|
||||
if r != TeamRightAdmin && r != TeamRightRead && r != TeamRightWrite {
|
||||
return ErrInvalidTeamRight{r}
|
||||
func (r Right) isValid() error {
|
||||
if r != RightAdmin && r != RightRead && r != RightWrite {
|
||||
return ErrInvalidRight{r}
|
||||
}
|
||||
|
||||
return nil
|
|
@ -27,7 +27,7 @@ type TeamList struct {
|
|||
// The list id.
|
||||
ListID int64 `xorm:"int(11) not null INDEX" json:"-" param:"list"`
|
||||
// The right this team has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details.
|
||||
Right TeamRight `xorm:"int(11) INDEX" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
Right Right `xorm:"int(11) INDEX" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
|
||||
// A unix timestamp when this relation was created. You cannot change this value.
|
||||
Created int64 `xorm:"created" json:"created"`
|
||||
|
@ -46,5 +46,5 @@ func (TeamList) TableName() string {
|
|||
// TeamWithRight represents a team, combined with rights.
|
||||
type TeamWithRight struct {
|
||||
Team `xorm:"extends"`
|
||||
Right TeamRight `json:"right"`
|
||||
Right Right `json:"right"`
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ func TestTeamList(t *testing.T) {
|
|||
tl := TeamList{
|
||||
TeamID: 1,
|
||||
ListID: 1,
|
||||
Right: TeamRightAdmin,
|
||||
Right: RightAdmin,
|
||||
}
|
||||
|
||||
// Dummyuser
|
||||
|
@ -48,10 +48,10 @@ func TestTeamList(t *testing.T) {
|
|||
|
||||
// Check with wrong rights
|
||||
tl2 := tl
|
||||
tl2.Right = TeamRightUnknown
|
||||
tl2.Right = RightUnknown
|
||||
err = tl2.Create(&u)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrInvalidTeamRight(err))
|
||||
assert.True(t, IsErrInvalidRight(err))
|
||||
|
||||
// Check with inexistant team
|
||||
tl3 := tl
|
||||
|
@ -113,7 +113,7 @@ func TestTeamList_Update(t *testing.T) {
|
|||
ID int64
|
||||
TeamID int64
|
||||
ListID int64
|
||||
Right TeamRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -130,7 +130,7 @@ func TestTeamList_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
ListID: 3,
|
||||
TeamID: 1,
|
||||
Right: TeamRightAdmin,
|
||||
Right: RightAdmin,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -138,7 +138,7 @@ func TestTeamList_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
ListID: 3,
|
||||
TeamID: 1,
|
||||
Right: TeamRightWrite,
|
||||
Right: RightWrite,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -146,7 +146,7 @@ func TestTeamList_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
ListID: 3,
|
||||
TeamID: 1,
|
||||
Right: TeamRightRead,
|
||||
Right: RightRead,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -157,7 +157,7 @@ func TestTeamList_Update(t *testing.T) {
|
|||
Right: 500,
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrInvalidTeamRight,
|
||||
errType: IsErrInvalidRight,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
|
|
@ -27,7 +27,7 @@ type TeamNamespace struct {
|
|||
// The namespace id.
|
||||
NamespaceID int64 `xorm:"int(11) not null INDEX" json:"-" param:"namespace"`
|
||||
// The right this team has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details.
|
||||
Right TeamRight `xorm:"int(11) INDEX" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
Right Right `xorm:"int(11) INDEX" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
|
||||
// A unix timestamp when this relation was created. You cannot change this value.
|
||||
Created int64 `xorm:"created" json:"created"`
|
||||
|
|
|
@ -27,7 +27,7 @@ func TestTeamNamespace_CanDoSomething(t *testing.T) {
|
|||
ID int64
|
||||
TeamID int64
|
||||
NamespaceID int64
|
||||
Right TeamRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
|
|
@ -29,7 +29,7 @@ func TestTeamNamespace(t *testing.T) {
|
|||
tn := TeamNamespace{
|
||||
TeamID: 1,
|
||||
NamespaceID: 1,
|
||||
Right: TeamRightAdmin,
|
||||
Right: RightAdmin,
|
||||
}
|
||||
|
||||
dummyuser, err := GetUserByID(1)
|
||||
|
@ -47,10 +47,10 @@ func TestTeamNamespace(t *testing.T) {
|
|||
|
||||
// Test with invalid team right
|
||||
tn2 := tn
|
||||
tn2.Right = TeamRightUnknown
|
||||
tn2.Right = RightUnknown
|
||||
err = tn2.Create(&dummyuser)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrInvalidTeamRight(err))
|
||||
assert.True(t, IsErrInvalidRight(err))
|
||||
|
||||
// Check with inexistant team
|
||||
tn3 := tn
|
||||
|
@ -105,7 +105,7 @@ func TestTeamNamespace_Update(t *testing.T) {
|
|||
ID int64
|
||||
TeamID int64
|
||||
NamespaceID int64
|
||||
Right TeamRight
|
||||
Right Right
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -122,7 +122,7 @@ func TestTeamNamespace_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
NamespaceID: 3,
|
||||
TeamID: 1,
|
||||
Right: TeamRightAdmin,
|
||||
Right: RightAdmin,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -130,7 +130,7 @@ func TestTeamNamespace_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
NamespaceID: 3,
|
||||
TeamID: 1,
|
||||
Right: TeamRightWrite,
|
||||
Right: RightWrite,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -138,7 +138,7 @@ func TestTeamNamespace_Update(t *testing.T) {
|
|||
fields: fields{
|
||||
NamespaceID: 3,
|
||||
TeamID: 1,
|
||||
Right: TeamRightRead,
|
||||
Right: RightRead,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -149,7 +149,7 @@ func TestTeamNamespace_Update(t *testing.T) {
|
|||
Right: 500,
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrInvalidTeamRight,
|
||||
errType: IsErrInvalidRight,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
|
|
@ -92,15 +92,15 @@ func TestTeam_Create(t *testing.T) {
|
|||
assert.True(t, IsErrTeamDoesNotExist(err))
|
||||
}
|
||||
|
||||
func TestIsErrInvalidTeamRight(t *testing.T) {
|
||||
assert.NoError(t, TeamRightAdmin.isValid())
|
||||
assert.NoError(t, TeamRightRead.isValid())
|
||||
assert.NoError(t, TeamRightWrite.isValid())
|
||||
func TestIsErrInvalidRight(t *testing.T) {
|
||||
assert.NoError(t, RightAdmin.isValid())
|
||||
assert.NoError(t, RightRead.isValid())
|
||||
assert.NoError(t, RightWrite.isValid())
|
||||
|
||||
// Check invalid
|
||||
var tr TeamRight
|
||||
var tr Right
|
||||
tr = 938
|
||||
err := tr.isValid()
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrInvalidTeamRight(err))
|
||||
assert.True(t, IsErrInvalidRight(err))
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
// Vikunja is a todo-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/>.
|
||||
|
||||
package models
|
||||
|
||||
// UserRight defines the rights users can have for lists/namespaces
|
||||
type UserRight int
|
||||
|
||||
// define unknown user right
|
||||
const (
|
||||
UserRightUnknown = -1
|
||||
)
|
||||
|
||||
// Enumerate all the user rights
|
||||
const (
|
||||
// Can read lists in a User
|
||||
UserRightRead UserRight = iota
|
||||
// Can write tasks in a User like lists and todo tasks. Cannot create new lists.
|
||||
UserRightWrite
|
||||
// Can manage a list/namespace, can do everything
|
||||
UserRightAdmin
|
||||
)
|
||||
|
||||
func (r UserRight) isValid() error {
|
||||
if r != UserRightAdmin && r != UserRightRead && r != UserRightWrite {
|
||||
return ErrInvalidUserRight{r}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue