Refactor User and DB handling #123
|
@ -17,7 +17,7 @@
|
|||
package caldav
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/api/pkg/utils"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
@ -49,7 +49,7 @@ type Todo struct {
|
|||
Summary string
|
||||
Description string
|
||||
CompletedUnix int64
|
||||
Organizer *models.User
|
||||
Organizer *user.User
|
||||
Priority int64 // 0-9, 1 is highest
|
||||
RelatedToUID string
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/routes"
|
||||
v1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
|
@ -38,34 +39,34 @@ import (
|
|||
|
||||
// These are the test users, the same way they are in the test database
|
||||
var (
|
||||
testuser1 = models.User{
|
||||
testuser1 = user.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
Email: "user1@example.com",
|
||||
IsActive: true,
|
||||
}
|
||||
testuser2 = models.User{
|
||||
testuser2 = user.User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
Email: "user2@example.com",
|
||||
}
|
||||
testuser3 = models.User{
|
||||
testuser3 = user.User{
|
||||
ID: 3,
|
||||
Username: "user3",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
Email: "user3@example.com",
|
||||
PasswordResetToken: "passwordresettesttoken",
|
||||
}
|
||||
testuser4 = models.User{
|
||||
testuser4 = user.User{
|
||||
ID: 4,
|
||||
Username: "user4",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
Email: "user4@example.com",
|
||||
EmailConfirmToken: "tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael",
|
||||
}
|
||||
testuser5 = models.User{
|
||||
testuser5 = user.User{
|
||||
ID: 4,
|
||||
Username: "user5",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -114,7 +115,7 @@ func newTestRequest(t *testing.T, method string, handler func(ctx echo.Context)
|
|||
return
|
||||
}
|
||||
|
||||
func addUserTokenToContext(t *testing.T, user *models.User, c echo.Context) {
|
||||
func addUserTokenToContext(t *testing.T, user *user.User, c echo.Context) {
|
||||
// Get the token as a string
|
||||
token, err := v1.NewUserJWTAuthtoken(user)
|
||||
assert.NoError(t, err)
|
||||
|
@ -152,7 +153,7 @@ func testRequestSetup(t *testing.T, method string, payload string, queryParams u
|
|||
return
|
||||
}
|
||||
|
||||
func newTestRequestWithUser(t *testing.T, method string, handler echo.HandlerFunc, user *models.User, payload string, queryParams url.Values, urlParams map[string]string) (rec *httptest.ResponseRecorder, err error) {
|
||||
func newTestRequestWithUser(t *testing.T, method string, handler echo.HandlerFunc, user *user.User, payload string, queryParams url.Values, urlParams map[string]string) (rec *httptest.ResponseRecorder, err error) {
|
||||
rec, c := testRequestSetup(t, method, payload, queryParams, urlParams)
|
||||
addUserTokenToContext(t, user, c)
|
||||
err = handler(c)
|
||||
|
@ -185,7 +186,7 @@ func assertHandlerErrorCode(t *testing.T, err error, expectedErrorCode int) {
|
|||
}
|
||||
|
||||
type webHandlerTest struct {
|
||||
user *models.User
|
||||
user *user.User
|
||||
linkShare *models.LinkSharing
|
||||
strFunc func() handler.CObject
|
||||
t *testing.T
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -9,7 +10,7 @@ func TestBulkTask_Update(t *testing.T) {
|
|||
IDs []int64
|
||||
Tasks []*Task
|
||||
Task Task
|
||||
User *User
|
||||
User *user.User
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -24,7 +25,7 @@ func TestBulkTask_Update(t *testing.T) {
|
|||
Task: Task{
|
||||
Text: "bulkupdated",
|
||||
},
|
||||
User: &User{ID: 1},
|
||||
User: &user.User{ID: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -34,7 +35,7 @@ func TestBulkTask_Update(t *testing.T) {
|
|||
Task: Task{
|
||||
Text: "bulkupdated",
|
||||
},
|
||||
User: &User{ID: 1},
|
||||
User: &user.User{ID: 1},
|
||||
},
|
||||
wantForbidden: true,
|
||||
},
|
||||
|
@ -45,7 +46,7 @@ func TestBulkTask_Update(t *testing.T) {
|
|||
Task: Task{
|
||||
Text: "bulkupdated",
|
||||
},
|
||||
User: &User{ID: 1},
|
||||
User: &user.User{ID: 1},
|
||||
},
|
||||
wantForbidden: true,
|
||||
},
|
||||
|
|
|
@ -46,273 +46,6 @@ func (err ErrGenericForbidden) HTTPError() web.HTTPError {
|
|||
return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrorCodeGenericForbidden, Message: "You're not allowed to do this."}
|
||||
}
|
||||
|
||||
// =====================
|
||||
// User Operation Errors
|
||||
// =====================
|
||||
|
||||
// ErrUsernameExists represents a "UsernameAlreadyExists" kind of error.
|
||||
type ErrUsernameExists struct {
|
||||
UserID int64
|
||||
Username string
|
||||
}
|
||||
|
||||
// IsErrUsernameExists checks if an error is a ErrUsernameExists.
|
||||
func IsErrUsernameExists(err error) bool {
|
||||
_, ok := err.(ErrUsernameExists)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUsernameExists) Error() string {
|
||||
return fmt.Sprintf("User with that username already exists [user id: %d, username: %s]", err.UserID, err.Username)
|
||||
}
|
||||
|
||||
// ErrorCodeUsernameExists holds the unique world-error code of this error
|
||||
const ErrorCodeUsernameExists = 1001
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrUsernameExists) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrorCodeUsernameExists, Message: "A user with this username already exists."}
|
||||
}
|
||||
|
||||
// ErrUserEmailExists represents a "UserEmailExists" kind of error.
|
||||
type ErrUserEmailExists struct {
|
||||
UserID int64
|
||||
Email string
|
||||
}
|
||||
|
||||
// IsErrUserEmailExists checks if an error is a ErrUserEmailExists.
|
||||
func IsErrUserEmailExists(err error) bool {
|
||||
_, ok := err.(ErrUserEmailExists)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserEmailExists) Error() string {
|
||||
return fmt.Sprintf("User with that email already exists [user id: %d, email: %s]", err.UserID, err.Email)
|
||||
}
|
||||
|
||||
// ErrorCodeUserEmailExists holds the unique world-error code of this error
|
||||
const ErrorCodeUserEmailExists = 1002
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrUserEmailExists) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrorCodeUserEmailExists, Message: "A user with this email address already exists."}
|
||||
}
|
||||
|
||||
// ErrNoUsernamePassword represents a "NoUsernamePassword" kind of error.
|
||||
type ErrNoUsernamePassword struct{}
|
||||
|
||||
// IsErrNoUsernamePassword checks if an error is a ErrNoUsernamePassword.
|
||||
func IsErrNoUsernamePassword(err error) bool {
|
||||
_, ok := err.(ErrNoUsernamePassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrNoUsernamePassword) Error() string {
|
||||
return fmt.Sprintf("No username and password provided")
|
||||
}
|
||||
|
||||
// ErrCodeNoUsernamePassword holds the unique world-error code of this error
|
||||
const ErrCodeNoUsernamePassword = 1004
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrNoUsernamePassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeNoUsernamePassword, Message: "Please specify a username and a password."}
|
||||
}
|
||||
|
||||
// ErrUserDoesNotExist represents a "UserDoesNotExist" kind of error.
|
||||
type ErrUserDoesNotExist struct {
|
||||
UserID int64
|
||||
}
|
||||
|
||||
// IsErrUserDoesNotExist checks if an error is a ErrUserDoesNotExist.
|
||||
func IsErrUserDoesNotExist(err error) bool {
|
||||
_, ok := err.(ErrUserDoesNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserDoesNotExist) Error() string {
|
||||
return fmt.Sprintf("User does not exist [user id: %d]", err.UserID)
|
||||
}
|
||||
|
||||
// ErrCodeUserDoesNotExist holds the unique world-error code of this error
|
||||
const ErrCodeUserDoesNotExist = 1005
|
||||
|
||||
// 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."}
|
||||
}
|
||||
|
||||
// ErrCouldNotGetUserID represents a "ErrCouldNotGetUserID" kind of error.
|
||||
type ErrCouldNotGetUserID struct{}
|
||||
|
||||
// IsErrCouldNotGetUserID checks if an error is a ErrCouldNotGetUserID.
|
||||
func IsErrCouldNotGetUserID(err error) bool {
|
||||
_, ok := err.(ErrCouldNotGetUserID)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrCouldNotGetUserID) Error() string {
|
||||
return fmt.Sprintf("Could not get user ID")
|
||||
}
|
||||
|
||||
// ErrCodeCouldNotGetUserID holds the unique world-error code of this error
|
||||
const ErrCodeCouldNotGetUserID = 1006
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrCouldNotGetUserID) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeCouldNotGetUserID, Message: "Could not get user id."}
|
||||
}
|
||||
|
||||
// ErrNoPasswordResetToken represents an error where no password reset token exists for that user
|
||||
type ErrNoPasswordResetToken struct {
|
||||
UserID int64
|
||||
}
|
||||
|
||||
func (err ErrNoPasswordResetToken) Error() string {
|
||||
return fmt.Sprintf("No token to reset a password [UserID: %d]", err.UserID)
|
||||
}
|
||||
|
||||
// ErrCodeNoPasswordResetToken holds the unique world-error code of this error
|
||||
const ErrCodeNoPasswordResetToken = 1008
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrNoPasswordResetToken) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeNoPasswordResetToken, Message: "No token to reset a user's password provided."}
|
||||
}
|
||||
|
||||
// ErrInvalidPasswordResetToken is an error where the password reset token is invalid
|
||||
type ErrInvalidPasswordResetToken struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
func (err ErrInvalidPasswordResetToken) Error() string {
|
||||
return fmt.Sprintf("Invalid token to reset a password [Token: %s]", err.Token)
|
||||
}
|
||||
|
||||
// ErrCodeInvalidPasswordResetToken holds the unique world-error code of this error
|
||||
const ErrCodeInvalidPasswordResetToken = 1009
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrInvalidPasswordResetToken) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeInvalidPasswordResetToken, Message: "Invalid token to reset a user's password."}
|
||||
}
|
||||
|
||||
// IsErrInvalidPasswordResetToken checks if an error is a ErrInvalidPasswordResetToken.
|
||||
func IsErrInvalidPasswordResetToken(err error) bool {
|
||||
_, ok := err.(ErrInvalidPasswordResetToken)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrInvalidEmailConfirmToken is an error where the email confirm token is invalid
|
||||
type ErrInvalidEmailConfirmToken struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
func (err ErrInvalidEmailConfirmToken) Error() string {
|
||||
return fmt.Sprintf("Invalid email confirm token [Token: %s]", err.Token)
|
||||
}
|
||||
|
||||
// ErrCodeInvalidEmailConfirmToken holds the unique world-error code of this error
|
||||
const ErrCodeInvalidEmailConfirmToken = 1010
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrInvalidEmailConfirmToken) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeInvalidEmailConfirmToken, Message: "Invalid email confirm token."}
|
||||
}
|
||||
|
||||
// IsErrInvalidEmailConfirmToken checks if an error is a ErrInvalidEmailConfirmToken.
|
||||
func IsErrInvalidEmailConfirmToken(err error) bool {
|
||||
_, ok := err.(ErrInvalidEmailConfirmToken)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrWrongUsernameOrPassword is an error where the email was not confirmed
|
||||
type ErrWrongUsernameOrPassword struct {
|
||||
}
|
||||
|
||||
func (err ErrWrongUsernameOrPassword) Error() string {
|
||||
return fmt.Sprintf("Wrong username or password")
|
||||
}
|
||||
|
||||
// ErrCodeWrongUsernameOrPassword holds the unique world-error code of this error
|
||||
const ErrCodeWrongUsernameOrPassword = 1011
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrWrongUsernameOrPassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeWrongUsernameOrPassword, Message: "Wrong username or password."}
|
||||
}
|
||||
|
||||
// IsErrWrongUsernameOrPassword checks if an error is a IsErrEmailNotConfirmed.
|
||||
func IsErrWrongUsernameOrPassword(err error) bool {
|
||||
_, ok := err.(ErrWrongUsernameOrPassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrEmailNotConfirmed is an error where the email was not confirmed
|
||||
type ErrEmailNotConfirmed struct {
|
||||
UserID int64
|
||||
}
|
||||
|
||||
func (err ErrEmailNotConfirmed) Error() string {
|
||||
return fmt.Sprintf("Email is not confirmed [UserID: %d]", err.UserID)
|
||||
}
|
||||
|
||||
// ErrCodeEmailNotConfirmed holds the unique world-error code of this error
|
||||
const ErrCodeEmailNotConfirmed = 1012
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrEmailNotConfirmed) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeEmailNotConfirmed, Message: "Please confirm your email address."}
|
||||
}
|
||||
|
||||
// IsErrEmailNotConfirmed checks if an error is a IsErrEmailNotConfirmed.
|
||||
func IsErrEmailNotConfirmed(err error) bool {
|
||||
_, ok := err.(ErrEmailNotConfirmed)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrEmptyNewPassword represents a "EmptyNewPassword" kind of error.
|
||||
type ErrEmptyNewPassword struct{}
|
||||
|
||||
// IsErrEmptyNewPassword checks if an error is a ErrEmptyNewPassword.
|
||||
func IsErrEmptyNewPassword(err error) bool {
|
||||
_, ok := err.(ErrEmptyNewPassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrEmptyNewPassword) Error() string {
|
||||
return fmt.Sprintf("New password is empty")
|
||||
}
|
||||
|
||||
// ErrCodeEmptyNewPassword holds the unique world-error code of this error
|
||||
const ErrCodeEmptyNewPassword = 1013
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrEmptyNewPassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeEmptyNewPassword, Message: "Please specify new password."}
|
||||
}
|
||||
|
||||
// ErrEmptyOldPassword represents a "EmptyOldPassword" kind of error.
|
||||
type ErrEmptyOldPassword struct{}
|
||||
|
||||
// IsErrEmptyOldPassword checks if an error is a ErrEmptyOldPassword.
|
||||
func IsErrEmptyOldPassword(err error) bool {
|
||||
_, ok := err.(ErrEmptyOldPassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrEmptyOldPassword) Error() string {
|
||||
return fmt.Sprintf("Old password is empty")
|
||||
}
|
||||
|
||||
// ErrCodeEmptyOldPassword holds the unique world-error code of this error
|
||||
const ErrCodeEmptyOldPassword = 1014
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrEmptyOldPassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeEmptyOldPassword, Message: "Please specify old password."}
|
||||
}
|
||||
|
||||
// ===================
|
||||
// Empty things errors
|
||||
// ===================
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"time"
|
||||
)
|
||||
|
@ -34,7 +35,7 @@ type Label struct {
|
|||
|
||||
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
|
||||
// The user who created this label
|
||||
CreatedBy *User `xorm:"-" json:"created_by"`
|
||||
CreatedBy *user.User `xorm:"-" json:"created_by"`
|
||||
|
||||
// A unix timestamp when this label was created. You cannot change this value.
|
||||
Created int64 `xorm:"created not null" json:"created"`
|
||||
|
@ -63,7 +64,7 @@ func (Label) TableName() string {
|
|||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /labels [put]
|
||||
func (l *Label) Create(a web.Auth) (err error) {
|
||||
u, err := getUserWithError(a)
|
||||
u, err := user.GetFromAuth(a)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -136,7 +137,7 @@ func (l *Label) ReadAll(a web.Auth, search string, page int, perPage int) (ls in
|
|||
return nil, 0, 0, ErrGenericForbidden{}
|
||||
}
|
||||
|
||||
u := &User{ID: a.GetID()}
|
||||
u := &user.User{ID: a.GetID()}
|
||||
|
||||
// Get all tasks
|
||||
taskIDs, err := getUserTaskIDs(u)
|
||||
|
@ -175,7 +176,7 @@ func (l *Label) ReadOne() (err error) {
|
|||
}
|
||||
*l = *label
|
||||
|
||||
user, err := GetUserByID(l.CreatedByID)
|
||||
user, err := user.GetUserByID(l.CreatedByID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -198,7 +199,7 @@ func getLabelByIDSimple(labelID int64) (*Label, error) {
|
|||
}
|
||||
|
||||
// Helper method to get all task ids a user has
|
||||
func getUserTaskIDs(u *User) (taskIDs []int64, err error) {
|
||||
func getUserTaskIDs(u *user.User) (taskIDs []int64, err error) {
|
||||
|
||||
// Get all lists
|
||||
lists, _, _, err := getRawListsForUser("", u, -1, 0)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/go-xorm/builder"
|
||||
)
|
||||
|
@ -65,7 +66,7 @@ func (l *Label) hasAccessToLabel(a web.Auth) (bool, error) {
|
|||
// TODO: add an extra check for link share handling
|
||||
|
||||
// Get all tasks
|
||||
taskIDs, err := getUserTaskIDs(&User{ID: a.GetID()})
|
||||
taskIDs, err := getUserTaskIDs(&user.User{ID: a.GetID()})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/go-xorm/builder"
|
||||
)
|
||||
|
@ -120,7 +121,7 @@ func (lt *LabelTask) ReadAll(a web.Auth, search string, page int, perPage int) (
|
|||
}
|
||||
|
||||
return getLabelsByTaskIDs(&LabelByTaskIDsOptions{
|
||||
User: &User{ID: a.GetID()},
|
||||
User: &user.User{ID: a.GetID()},
|
||||
Search: search,
|
||||
Page: page,
|
||||
TaskIDs: []int64{lt.TaskID},
|
||||
|
@ -135,7 +136,7 @@ type labelWithTaskID struct {
|
|||
|
||||
// LabelByTaskIDsOptions is a struct to not clutter the function with too many optional parameters.
|
||||
type LabelByTaskIDsOptions struct {
|
||||
User *User
|
||||
User *user.User
|
||||
Search string
|
||||
Page int
|
||||
PerPage int
|
||||
|
@ -185,7 +186,7 @@ func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, res
|
|||
for _, l := range labels {
|
||||
userids = append(userids, l.CreatedByID)
|
||||
}
|
||||
users := make(map[int64]*User)
|
||||
users := make(map[int64]*user.User)
|
||||
err = x.In("id", userids).Find(&users)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
|
@ -290,7 +291,7 @@ func (t *Task) updateTaskLabels(creator web.Auth, labels []*Label) (err error) {
|
|||
return err
|
||||
}
|
||||
if !hasAccessToLabel {
|
||||
user, _ := creator.(*User)
|
||||
user, _ := creator.(*user.User)
|
||||
return ErrUserHasNoAccessToLabel{LabelID: l.ID, UserID: user.ID}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"reflect"
|
||||
"runtime"
|
||||
|
@ -37,7 +38,7 @@ func TestLabelTask_ReadAll(t *testing.T) {
|
|||
TaskID: 1,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
wantLabels: []*labelWithTaskID{
|
||||
{
|
||||
|
@ -46,7 +47,7 @@ func TestLabelTask_ReadAll(t *testing.T) {
|
|||
ID: 4,
|
||||
Title: "Label #4 - visible via other task",
|
||||
CreatedByID: 2,
|
||||
CreatedBy: &User{
|
||||
CreatedBy: &user.User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -62,7 +63,7 @@ func TestLabelTask_ReadAll(t *testing.T) {
|
|||
TaskID: 14,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrNoRightToSeeTask,
|
||||
|
@ -73,7 +74,7 @@ func TestLabelTask_ReadAll(t *testing.T) {
|
|||
TaskID: 9999,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrTaskDoesNotExist,
|
||||
|
@ -131,7 +132,7 @@ func TestLabelTask_Create(t *testing.T) {
|
|||
LabelID: 1,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -141,7 +142,7 @@ func TestLabelTask_Create(t *testing.T) {
|
|||
LabelID: 1,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrLabelIsAlreadyOnTask,
|
||||
|
@ -153,7 +154,7 @@ func TestLabelTask_Create(t *testing.T) {
|
|||
LabelID: 9999,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
wantForbidden: true,
|
||||
},
|
||||
|
@ -164,7 +165,7 @@ func TestLabelTask_Create(t *testing.T) {
|
|||
LabelID: 1,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
wantForbidden: true,
|
||||
wantErr: true,
|
||||
|
@ -219,7 +220,7 @@ func TestLabelTask_Delete(t *testing.T) {
|
|||
TaskID: 1,
|
||||
LabelID: 1,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
},
|
||||
{
|
||||
name: "delete nonexistant",
|
||||
|
@ -227,7 +228,7 @@ func TestLabelTask_Delete(t *testing.T) {
|
|||
TaskID: 1,
|
||||
LabelID: 1,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true,
|
||||
},
|
||||
{
|
||||
|
@ -236,7 +237,7 @@ func TestLabelTask_Delete(t *testing.T) {
|
|||
TaskID: 1,
|
||||
LabelID: 9999,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true,
|
||||
},
|
||||
{
|
||||
|
@ -245,7 +246,7 @@ func TestLabelTask_Delete(t *testing.T) {
|
|||
TaskID: 9999,
|
||||
LabelID: 1,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true,
|
||||
},
|
||||
{
|
||||
|
@ -254,7 +255,7 @@ func TestLabelTask_Delete(t *testing.T) {
|
|||
TaskID: 14,
|
||||
LabelID: 1,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"reflect"
|
||||
"runtime"
|
||||
|
@ -32,7 +33,7 @@ func TestLabel_ReadAll(t *testing.T) {
|
|||
Description string
|
||||
HexColor string
|
||||
CreatedByID int64
|
||||
CreatedBy *User
|
||||
CreatedBy *user.User
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -43,7 +44,7 @@ func TestLabel_ReadAll(t *testing.T) {
|
|||
a web.Auth
|
||||
page int
|
||||
}
|
||||
user1 := &User{
|
||||
user1 := &user.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -60,7 +61,7 @@ func TestLabel_ReadAll(t *testing.T) {
|
|||
{
|
||||
name: "normal",
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
wantLs: []*labelWithTaskID{
|
||||
{
|
||||
|
@ -85,7 +86,7 @@ func TestLabel_ReadAll(t *testing.T) {
|
|||
ID: 4,
|
||||
Title: "Label #4 - visible via other task",
|
||||
CreatedByID: 2,
|
||||
CreatedBy: &User{
|
||||
CreatedBy: &user.User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -98,7 +99,7 @@ func TestLabel_ReadAll(t *testing.T) {
|
|||
{
|
||||
name: "invalid user",
|
||||
args: args{
|
||||
a: &User{ID: -1},
|
||||
a: &user.User{ID: -1},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
|
@ -136,13 +137,13 @@ func TestLabel_ReadOne(t *testing.T) {
|
|||
Description string
|
||||
HexColor string
|
||||
CreatedByID int64
|
||||
CreatedBy *User
|
||||
CreatedBy *user.User
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
Rights web.Rights
|
||||
}
|
||||
user1 := &User{
|
||||
user1 := &user.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -169,7 +170,7 @@ func TestLabel_ReadOne(t *testing.T) {
|
|||
CreatedByID: 1,
|
||||
CreatedBy: user1,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
},
|
||||
{
|
||||
name: "Get nonexistant label",
|
||||
|
@ -179,7 +180,7 @@ func TestLabel_ReadOne(t *testing.T) {
|
|||
wantErr: true,
|
||||
errType: IsErrLabelDoesNotExist,
|
||||
wantForbidden: true,
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
},
|
||||
{
|
||||
name: "no rights",
|
||||
|
@ -187,7 +188,7 @@ func TestLabel_ReadOne(t *testing.T) {
|
|||
ID: 3,
|
||||
},
|
||||
wantForbidden: true,
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
},
|
||||
{
|
||||
name: "Get label #4 - other user",
|
||||
|
@ -198,14 +199,14 @@ func TestLabel_ReadOne(t *testing.T) {
|
|||
ID: 4,
|
||||
Title: "Label #4 - visible via other task",
|
||||
CreatedByID: 2,
|
||||
CreatedBy: &User{
|
||||
CreatedBy: &user.User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
AvatarURL: "ab53a2911ddf9b4817ac01ddcd3d975f",
|
||||
},
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
@ -248,7 +249,7 @@ func TestLabel_Create(t *testing.T) {
|
|||
Description string
|
||||
HexColor string
|
||||
CreatedByID int64
|
||||
CreatedBy *User
|
||||
CreatedBy *user.User
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -272,7 +273,7 @@ func TestLabel_Create(t *testing.T) {
|
|||
HexColor: "ffccff",
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -308,7 +309,7 @@ func TestLabel_Update(t *testing.T) {
|
|||
Description string
|
||||
HexColor string
|
||||
CreatedByID int64
|
||||
CreatedBy *User
|
||||
CreatedBy *user.User
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -327,7 +328,7 @@ func TestLabel_Update(t *testing.T) {
|
|||
ID: 1,
|
||||
Title: "new and better",
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
},
|
||||
{
|
||||
name: "nonexisting",
|
||||
|
@ -335,7 +336,7 @@ func TestLabel_Update(t *testing.T) {
|
|||
ID: 99999,
|
||||
Title: "new and better",
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true,
|
||||
wantErr: true,
|
||||
},
|
||||
|
@ -345,7 +346,7 @@ func TestLabel_Update(t *testing.T) {
|
|||
ID: 3,
|
||||
Title: "new and better",
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true,
|
||||
},
|
||||
{
|
||||
|
@ -354,7 +355,7 @@ func TestLabel_Update(t *testing.T) {
|
|||
ID: 4,
|
||||
Title: "new and better",
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true,
|
||||
},
|
||||
}
|
||||
|
@ -390,7 +391,7 @@ func TestLabel_Delete(t *testing.T) {
|
|||
Description string
|
||||
HexColor string
|
||||
CreatedByID int64
|
||||
CreatedBy *User
|
||||
CreatedBy *user.User
|
||||
Created int64
|
||||
Updated int64
|
||||
CRUDable web.CRUDable
|
||||
|
@ -409,14 +410,14 @@ func TestLabel_Delete(t *testing.T) {
|
|||
fields: fields{
|
||||
ID: 1,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
},
|
||||
{
|
||||
name: "nonexisting",
|
||||
fields: fields{
|
||||
ID: 99999,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true, // When the label does not exist, it is forbidden. We should fix this, but for everything.
|
||||
},
|
||||
{
|
||||
|
@ -424,7 +425,7 @@ func TestLabel_Delete(t *testing.T) {
|
|||
fields: fields{
|
||||
ID: 3,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true,
|
||||
},
|
||||
{
|
||||
|
@ -432,7 +433,7 @@ func TestLabel_Delete(t *testing.T) {
|
|||
fields: fields{
|
||||
ID: 4,
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
auth: &user.User{ID: 1},
|
||||
wantForbidden: true,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/api/pkg/utils"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
|
@ -48,8 +49,8 @@ type LinkSharing struct {
|
|||
SharingType SharingType `xorm:"int(11) INDEX not null default 0" json:"sharing_type" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
|
||||
// The user who shared this list
|
||||
SharedBy *User `xorm:"-" json:"shared_by"`
|
||||
SharedByID int64 `xorm:"int(11) INDEX not null" json:"-"`
|
||||
SharedBy *user.User `xorm:"-" json:"shared_by"`
|
||||
SharedByID int64 `xorm:"int(11) INDEX not null" json:"-"`
|
||||
|
||||
// A unix timestamp when this list was shared. You cannot change this value.
|
||||
Created int64 `xorm:"created not null" json:"created"`
|
||||
|
@ -100,7 +101,7 @@ func (share *LinkSharing) Create(a web.Auth) (err error) {
|
|||
share.SharedByID = a.GetID()
|
||||
share.Hash = utils.MakeRandomString(40)
|
||||
_, err = x.Insert(share)
|
||||
share.SharedBy, _ = a.(*User)
|
||||
share.SharedBy, _ = a.(*user.User)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -168,7 +169,7 @@ func (share *LinkSharing) ReadAll(a web.Auth, search string, page int, perPage i
|
|||
userIDs = append(userIDs, s.SharedByID)
|
||||
}
|
||||
|
||||
users := make(map[int64]*User)
|
||||
users := make(map[int64]*user.User)
|
||||
err = x.In("id", userIDs).Find(&users)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
|
|
|
@ -18,6 +18,7 @@ package models
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/metrics"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
)
|
||||
|
||||
|
@ -36,7 +37,7 @@ type List struct {
|
|||
NamespaceID int64 `xorm:"int(11) INDEX not null" json:"-" param:"namespace"`
|
||||
|
||||
// The user who created this list.
|
||||
Owner *User `xorm:"-" json:"owner" valid:"-"`
|
||||
Owner *user.User `xorm:"-" json:"owner" valid:"-"`
|
||||
// An array of tasks which belong to the list.
|
||||
// Deprecated: you should use the dedicated task list endpoint because it has support for pagination and filtering
|
||||
Tasks []*Task `xorm:"-" json:"-"`
|
||||
|
@ -51,7 +52,7 @@ type List struct {
|
|||
}
|
||||
|
||||
// GetListsByNamespaceID gets all lists in a namespace
|
||||
func GetListsByNamespaceID(nID int64, doer *User) (lists []*List, err error) {
|
||||
func GetListsByNamespaceID(nID int64, doer *user.User) (lists []*List, err error) {
|
||||
if nID == -1 {
|
||||
err = x.Select("l.*").
|
||||
Table("list").
|
||||
|
@ -103,7 +104,7 @@ func (l *List) ReadAll(a web.Auth, search string, page int, perPage int) (result
|
|||
return lists, 0, 0, err
|
||||
}
|
||||
|
||||
lists, resultCount, totalItems, err := getRawListsForUser(search, &User{ID: a.GetID()}, page, perPage)
|
||||
lists, resultCount, totalItems, err := getRawListsForUser(search, &user.User{ID: a.GetID()}, page, perPage)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
@ -127,7 +128,7 @@ func (l *List) ReadAll(a web.Auth, search string, page int, perPage int) (result
|
|||
// @Router /lists/{id} [get]
|
||||
func (l *List) ReadOne() (err error) {
|
||||
// Get list owner
|
||||
l.Owner, err = GetUserByID(l.OwnerID)
|
||||
l.Owner, err = user.GetUserByID(l.OwnerID)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -176,8 +177,8 @@ func GetListSimplByTaskID(taskID int64) (l *List, err error) {
|
|||
}
|
||||
|
||||
// Gets the lists only, without any tasks or so
|
||||
func getRawListsForUser(search string, u *User, page int, perPage int) (lists []*List, resultCount int, totalItems int64, err error) {
|
||||
fullUser, err := GetUserByID(u.ID)
|
||||
func getRawListsForUser(search string, u *user.User, page int, perPage int) (lists []*List, resultCount int, totalItems int64, err error) {
|
||||
fullUser, err := user.GetUserByID(u.ID)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
@ -237,7 +238,7 @@ func AddListDetails(lists []*List) (err error) {
|
|||
}
|
||||
|
||||
// Get all list owners
|
||||
owners := []*User{}
|
||||
owners := []*user.User{}
|
||||
err = x.In("id", ownerIDs).Find(&owners)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -348,7 +349,7 @@ func updateListByTaskID(taskID int64) (err error) {
|
|||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /namespaces/{namespaceID}/lists [put]
|
||||
func (l *List) Create(a web.Auth) (err error) {
|
||||
doer, err := getUserWithError(a)
|
||||
doer, err := user.GetFromAuth(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/go-xorm/builder"
|
||||
)
|
||||
|
@ -39,7 +40,7 @@ func (l *List) CanWrite(a web.Auth) (bool, error) {
|
|||
}
|
||||
|
||||
// Check if the user is either owner or can write to the list
|
||||
if originalList.isOwner(&User{ID: a.GetID()}) {
|
||||
if originalList.isOwner(&user.User{ID: a.GetID()}) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
@ -60,7 +61,7 @@ func (l *List) CanRead(a web.Auth) (bool, error) {
|
|||
(shareAuth.Right == RightRead || shareAuth.Right == RightWrite || shareAuth.Right == RightAdmin), nil
|
||||
}
|
||||
|
||||
if l.isOwner(&User{ID: a.GetID()}) {
|
||||
if l.isOwner(&user.User{ID: a.GetID()}) {
|
||||
return true, nil
|
||||
}
|
||||
return l.checkRight(a, RightRead, RightWrite, RightAdmin)
|
||||
|
@ -100,14 +101,14 @@ func (l *List) IsAdmin(a web.Auth) (bool, error) {
|
|||
// Check all the things
|
||||
// Check if the user is either owner or can write to the list
|
||||
// Owners are always admins
|
||||
if originalList.isOwner(&User{ID: a.GetID()}) {
|
||||
if originalList.isOwner(&user.User{ID: a.GetID()}) {
|
||||
return true, nil
|
||||
}
|
||||
return originalList.checkRight(a, RightAdmin)
|
||||
}
|
||||
|
||||
// Little helper function to check if a user is list owner
|
||||
func (l *List) isOwner(u *User) bool {
|
||||
func (l *List) isOwner(u *user.User) bool {
|
||||
return l.OwnerID == u.ID
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
|
@ -33,7 +34,7 @@ func TestTeamList(t *testing.T) {
|
|||
}
|
||||
|
||||
// Dummyuser
|
||||
u, err := GetUserByID(1)
|
||||
u, err := user.GetUserByID(1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check normal creation
|
||||
|
|
|
@ -17,13 +17,14 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
user2 "code.vikunja.io/api/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestList_CreateOrUpdate(t *testing.T) {
|
||||
user := &User{
|
||||
user := &user2.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Email: "user1@example.com",
|
||||
|
@ -54,7 +55,7 @@ func TestList_CreateOrUpdate(t *testing.T) {
|
|||
})
|
||||
t.Run("nonexistant owner", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
user := &User{ID: 9482385}
|
||||
user := &user2.User{ID: 9482385}
|
||||
list := List{
|
||||
Title: "test",
|
||||
Description: "Lorem Ipsum",
|
||||
|
@ -133,12 +134,12 @@ func TestList_ReadAll(t *testing.T) {
|
|||
t.Run("all in namespace", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
// Get all lists for our namespace
|
||||
lists, err := GetListsByNamespaceID(1, &User{})
|
||||
lists, err := GetListsByNamespaceID(1, &user2.User{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(lists), 2)
|
||||
})
|
||||
t.Run("all lists for user", func(t *testing.T) {
|
||||
u := &User{ID: 1}
|
||||
u := &user2.User{ID: 1}
|
||||
list := List{}
|
||||
lists3, _, _, err := list.ReadAll(u, "", 1, 50)
|
||||
|
||||
|
@ -148,7 +149,7 @@ func TestList_ReadAll(t *testing.T) {
|
|||
assert.Equal(t, 16, s.Len())
|
||||
})
|
||||
t.Run("lists for nonexistant user", func(t *testing.T) {
|
||||
user := &User{ID: 999999}
|
||||
user := &user2.User{ID: 999999}
|
||||
list := List{}
|
||||
_, _, _, err := list.ReadAll(user, "", 1, 50)
|
||||
assert.Error(t, err)
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
|
||||
package models
|
||||
|
||||
import "code.vikunja.io/web"
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
)
|
||||
|
||||
// ListUser represents a list <-> user relation
|
||||
type ListUser struct {
|
||||
|
@ -47,8 +50,8 @@ 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 Right `json:"right"`
|
||||
user.User `xorm:"extends"`
|
||||
Right Right `json:"right"`
|
||||
}
|
||||
|
||||
// Create creates a new list <-> user relation
|
||||
|
@ -80,7 +83,7 @@ func (lu *ListUser) Create(a web.Auth) (err error) {
|
|||
}
|
||||
|
||||
// Check if the user exists
|
||||
user, err := GetUserByUsername(lu.Username)
|
||||
user, err := user.GetUserByUsername(lu.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -126,7 +129,7 @@ func (lu *ListUser) Create(a web.Auth) (err error) {
|
|||
func (lu *ListUser) Delete() (err error) {
|
||||
|
||||
// Check if the user exists
|
||||
user, err := GetUserByUsername(lu.Username)
|
||||
user, err := user.GetUserByUsername(lu.Username)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -227,7 +230,7 @@ func (lu *ListUser) Update() (err error) {
|
|||
}
|
||||
|
||||
// Check if the user exists
|
||||
user, err := GetUserByUsername(lu.Username)
|
||||
user, err := user.GetUserByUsername(lu.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"testing"
|
||||
|
||||
"code.vikunja.io/web"
|
||||
|
@ -48,7 +49,7 @@ func TestListUser_CanDoSomething(t *testing.T) {
|
|||
ListID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 3},
|
||||
a: &user.User{ID: 3},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": true, "CanDelete": true, "CanUpdate": true},
|
||||
},
|
||||
|
@ -58,7 +59,7 @@ func TestListUser_CanDoSomething(t *testing.T) {
|
|||
ListID: 300,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 3},
|
||||
a: &user.User{ID: 3},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": false, "CanDelete": false, "CanUpdate": false},
|
||||
},
|
||||
|
@ -68,7 +69,7 @@ func TestListUser_CanDoSomething(t *testing.T) {
|
|||
ListID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 4},
|
||||
a: &user.User{ID: 4},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": false, "CanDelete": false, "CanUpdate": false},
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"reflect"
|
||||
"runtime"
|
||||
|
@ -155,11 +156,11 @@ func TestListUser_ReadAll(t *testing.T) {
|
|||
ListID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 3},
|
||||
a: &user.User{ID: 3},
|
||||
},
|
||||
want: []*UserWithRight{
|
||||
{
|
||||
User: User{
|
||||
User: user.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -169,7 +170,7 @@ func TestListUser_ReadAll(t *testing.T) {
|
|||
Right: RightRead,
|
||||
},
|
||||
{
|
||||
User: User{
|
||||
User: user.User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -185,7 +186,7 @@ func TestListUser_ReadAll(t *testing.T) {
|
|||
ListID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 4},
|
||||
a: &user.User{ID: 4},
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrNeedToHaveListReadAccess,
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
_ "github.com/go-sql-driver/mysql" // Because.
|
||||
"github.com/go-xorm/xorm"
|
||||
|
||||
|
@ -33,7 +34,7 @@ var (
|
|||
// GetTables returns all structs which are also a table.
|
||||
func GetTables() []interface{} {
|
||||
return []interface{}{
|
||||
&User{},
|
||||
&user.User{},
|
||||
&List{},
|
||||
&Task{},
|
||||
&Team{},
|
||||
|
|
|
@ -18,6 +18,7 @@ package models
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/metrics"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/imdario/mergo"
|
||||
"time"
|
||||
|
@ -34,7 +35,7 @@ type Namespace struct {
|
|||
OwnerID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
||||
|
||||
// The user who owns this namespace
|
||||
Owner *User `xorm:"-" json:"owner" valid:"-"`
|
||||
Owner *user.User `xorm:"-" json:"owner" valid:"-"`
|
||||
|
||||
// A unix timestamp when this namespace was created. You cannot change this value.
|
||||
Created int64 `xorm:"created not null" json:"created"`
|
||||
|
@ -97,7 +98,7 @@ func GetNamespaceByID(id int64) (namespace Namespace, err error) {
|
|||
}
|
||||
|
||||
// Get the namespace Owner
|
||||
namespace.Owner, err = GetUserByID(namespace.OwnerID)
|
||||
namespace.Owner, err = user.GetUserByID(namespace.OwnerID)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -115,7 +116,7 @@ func GetNamespaceByID(id int64) (namespace Namespace, err error) {
|
|||
// @Router /namespaces/{id} [get]
|
||||
func (n *Namespace) ReadOne() (err error) {
|
||||
// Get the namespace Owner
|
||||
n.Owner, err = GetUserByID(n.OwnerID)
|
||||
n.Owner, err = user.GetUserByID(n.OwnerID)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -143,7 +144,7 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
|||
return nil, 0, 0, ErrGenericForbidden{}
|
||||
}
|
||||
|
||||
doer, err := getUserWithError(a)
|
||||
doer, err := user.GetFromAuth(a)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
@ -176,7 +177,7 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
|||
}
|
||||
|
||||
// Get all users
|
||||
users := []*User{}
|
||||
users := []*user.User{}
|
||||
err = x.Select("users.*").
|
||||
Table("namespaces").
|
||||
Join("LEFT", "team_namespaces", "namespaces.id = team_namespaces.namespace_id").
|
||||
|
@ -301,7 +302,7 @@ func (n *Namespace) Create(a web.Auth) (err error) {
|
|||
n.ID = 0 // This would otherwise prevent the creation of new lists after one was created
|
||||
|
||||
// Check if the User exists
|
||||
n.Owner, err = GetUserByID(a.GetID())
|
||||
n.Owner, err = user.GetUserByID(a.GetID())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -343,7 +344,7 @@ func (n *Namespace) Delete() (err error) {
|
|||
}
|
||||
|
||||
// Delete all lists with their tasks
|
||||
lists, err := GetListsByNamespaceID(n.ID, &User{})
|
||||
lists, err := GetListsByNamespaceID(n.ID, &user.User{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -401,7 +402,7 @@ func (n *Namespace) Update() (err error) {
|
|||
// Check if the (new) owner exists
|
||||
n.OwnerID = n.Owner.ID
|
||||
if currentNamespace.OwnerID != n.OwnerID {
|
||||
n.Owner, err = GetUserByID(n.OwnerID)
|
||||
n.Owner, err = user.GetUserByID(n.OwnerID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"testing"
|
||||
|
||||
"code.vikunja.io/web"
|
||||
|
@ -48,7 +49,7 @@ func TestTeamNamespace_CanDoSomething(t *testing.T) {
|
|||
NamespaceID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 3},
|
||||
a: &user.User{ID: 3},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": true, "CanDelete": true, "CanUpdate": true},
|
||||
},
|
||||
|
@ -58,7 +59,7 @@ func TestTeamNamespace_CanDoSomething(t *testing.T) {
|
|||
NamespaceID: 300,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 3},
|
||||
a: &user.User{ID: 3},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": false, "CanDelete": false, "CanUpdate": false},
|
||||
},
|
||||
|
@ -68,7 +69,7 @@ func TestTeamNamespace_CanDoSomething(t *testing.T) {
|
|||
NamespaceID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 4},
|
||||
a: &user.User{ID: 4},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": false, "CanDelete": false, "CanUpdate": false},
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
|
@ -32,7 +33,7 @@ func TestTeamNamespace(t *testing.T) {
|
|||
Right: RightAdmin,
|
||||
}
|
||||
|
||||
dummyuser, err := GetUserByID(1)
|
||||
dummyuser, err := user.GetUserByID(1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Test normal creation
|
||||
|
@ -80,7 +81,7 @@ func TestTeamNamespace(t *testing.T) {
|
|||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||
|
||||
// Check with no right to read the namespace
|
||||
nouser := &User{ID: 393}
|
||||
nouser := &user.User{ID: 393}
|
||||
_, _, _, err = tn.ReadAll(nouser, "", 1, 50)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrNeedToHaveNamespaceReadAccess(err))
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
@ -33,7 +34,7 @@ func TestNamespace_Create(t *testing.T) {
|
|||
}
|
||||
|
||||
// Doer
|
||||
doer, err := GetUserByID(1)
|
||||
doer, err := user.GetUserByID(1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Try creating it
|
||||
|
@ -57,7 +58,7 @@ func TestNamespace_Create(t *testing.T) {
|
|||
assert.True(t, IsErrNamespaceNameCannotBeEmpty(err))
|
||||
|
||||
// Try inserting one with a nonexistant user
|
||||
nUser := &User{ID: 9482385}
|
||||
nUser := &user.User{ID: 9482385}
|
||||
dnsp2 := dummynamespace
|
||||
err = dnsp2.Create(nUser)
|
||||
assert.Error(t, err)
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
|
||||
package models
|
||||
|
||||
import "code.vikunja.io/web"
|
||||
import (
|
||||
user2 "code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
)
|
||||
|
||||
// NamespaceUser represents a namespace <-> user relation
|
||||
type NamespaceUser struct {
|
||||
|
@ -75,7 +78,7 @@ func (nu *NamespaceUser) Create(a web.Auth) (err error) {
|
|||
}
|
||||
|
||||
// Check if the user exists
|
||||
user, err := GetUserByUsername(nu.Username)
|
||||
user, err := user2.GetUserByUsername(nu.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -117,7 +120,7 @@ func (nu *NamespaceUser) Create(a web.Auth) (err error) {
|
|||
func (nu *NamespaceUser) Delete() (err error) {
|
||||
|
||||
// Check if the user exists
|
||||
user, err := GetUserByUsername(nu.Username)
|
||||
user, err := user2.GetUserByUsername(nu.Username)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -213,7 +216,7 @@ func (nu *NamespaceUser) Update() (err error) {
|
|||
}
|
||||
|
||||
// Check if the user exists
|
||||
user, err := GetUserByUsername(nu.Username)
|
||||
user, err := user2.GetUserByUsername(nu.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"testing"
|
||||
|
||||
"code.vikunja.io/web"
|
||||
|
@ -48,7 +49,7 @@ func TestNamespaceUser_CanDoSomething(t *testing.T) {
|
|||
NamespaceID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 3},
|
||||
a: &user.User{ID: 3},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": true, "CanDelete": true, "CanUpdate": true},
|
||||
},
|
||||
|
@ -58,7 +59,7 @@ func TestNamespaceUser_CanDoSomething(t *testing.T) {
|
|||
NamespaceID: 300,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 3},
|
||||
a: &user.User{ID: 3},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": false, "CanDelete": false, "CanUpdate": false},
|
||||
},
|
||||
|
@ -68,7 +69,7 @@ func TestNamespaceUser_CanDoSomething(t *testing.T) {
|
|||
NamespaceID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 4},
|
||||
a: &user.User{ID: 4},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": false, "CanDelete": false, "CanUpdate": false},
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"reflect"
|
||||
|
@ -152,11 +153,11 @@ func TestNamespaceUser_ReadAll(t *testing.T) {
|
|||
NamespaceID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 3},
|
||||
a: &user.User{ID: 3},
|
||||
},
|
||||
want: []*UserWithRight{
|
||||
{
|
||||
User: User{
|
||||
User: user.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -166,7 +167,7 @@ func TestNamespaceUser_ReadAll(t *testing.T) {
|
|||
Right: RightRead,
|
||||
},
|
||||
{
|
||||
User: User{
|
||||
User: user.User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -182,7 +183,7 @@ func TestNamespaceUser_ReadAll(t *testing.T) {
|
|||
NamespaceID: 3,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 4},
|
||||
a: &user.User{ID: 4},
|
||||
},
|
||||
wantErr: true,
|
||||
errType: IsErrNeedToHaveNamespaceReadAccess,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
)
|
||||
|
||||
|
@ -38,8 +39,8 @@ func (TaskAssginee) TableName() string {
|
|||
|
||||
// TaskAssigneeWithUser is a helper type to deal with user joins
|
||||
type TaskAssigneeWithUser struct {
|
||||
TaskID int64
|
||||
User `xorm:"extends"`
|
||||
TaskID int64
|
||||
user.User `xorm:"extends"`
|
||||
}
|
||||
|
||||
func getRawTaskAssigneesForTasks(taskIDs []int64) (taskAssignees []*TaskAssigneeWithUser, err error) {
|
||||
|
@ -53,7 +54,7 @@ func getRawTaskAssigneesForTasks(taskIDs []int64) (taskAssignees []*TaskAssignee
|
|||
}
|
||||
|
||||
// Create or update a bunch of task assignees
|
||||
func (t *Task) updateTaskAssignees(assignees []*User) (err error) {
|
||||
func (t *Task) updateTaskAssignees(assignees []*user.User) (err error) {
|
||||
|
||||
// Load the current assignees
|
||||
currentAssignees, err := getRawTaskAssigneesForTasks([]int64{t.ID})
|
||||
|
@ -61,7 +62,7 @@ func (t *Task) updateTaskAssignees(assignees []*User) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
t.Assignees = make([]*User, 0, len(currentAssignees))
|
||||
t.Assignees = make([]*user.User, 0, len(currentAssignees))
|
||||
for _, assignee := range currentAssignees {
|
||||
t.Assignees = append(t.Assignees, &assignee.User)
|
||||
}
|
||||
|
@ -80,7 +81,7 @@ func (t *Task) updateTaskAssignees(assignees []*User) (err error) {
|
|||
}
|
||||
|
||||
// Make a hashmap of the new assignees for easier comparison
|
||||
newAssignees := make(map[int64]*User, len(assignees))
|
||||
newAssignees := make(map[int64]*user.User, len(assignees))
|
||||
for _, newAssignee := range assignees {
|
||||
newAssignees[newAssignee.ID] = newAssignee
|
||||
}
|
||||
|
@ -88,7 +89,7 @@ func (t *Task) updateTaskAssignees(assignees []*User) (err error) {
|
|||
// Get old assignees to delete
|
||||
var found bool
|
||||
var assigneesToDelete []int64
|
||||
oldAssignees := make(map[int64]*User, len(t.Assignees))
|
||||
oldAssignees := make(map[int64]*user.User, len(t.Assignees))
|
||||
for _, oldAssignee := range t.Assignees {
|
||||
found = false
|
||||
if newAssignees[oldAssignee.ID] != nil {
|
||||
|
@ -142,7 +143,7 @@ func (t *Task) updateTaskAssignees(assignees []*User) (err error) {
|
|||
}
|
||||
|
||||
// Small helper functions to set the new assignees in various places
|
||||
func (t *Task) setTaskAssignees(assignees []*User) {
|
||||
func (t *Task) setTaskAssignees(assignees []*user.User) {
|
||||
if len(assignees) == 0 {
|
||||
t.Assignees = nil
|
||||
return
|
||||
|
@ -200,7 +201,7 @@ func (la *TaskAssginee) Create(a web.Auth) (err error) {
|
|||
|
||||
func (t *Task) addNewAssigneeByID(newAssigneeID int64, list *List) (err error) {
|
||||
// Check if the user exists and has access to the list
|
||||
newAssignee, err := GetUserByID(newAssigneeID)
|
||||
newAssignee, err := user.GetUserByID(newAssigneeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -252,7 +253,7 @@ func (la *TaskAssginee) ReadAll(a web.Auth, search string, page int, perPage int
|
|||
return nil, 0, 0, ErrGenericForbidden{}
|
||||
}
|
||||
|
||||
var taskAssignees []*User
|
||||
var taskAssignees []*user.User
|
||||
err = x.Table("task_assignees").
|
||||
Select("users.*").
|
||||
Join("INNER", "users", "task_assignees.user_id = users.id").
|
||||
|
@ -267,15 +268,15 @@ func (la *TaskAssginee) ReadAll(a web.Auth, search string, page int, perPage int
|
|||
Select("users.*").
|
||||
Join("INNER", "users", "task_assignees.user_id = users.id").
|
||||
Where("task_id = ? AND users.username LIKE ?", la.TaskID, "%"+search+"%").
|
||||
Count(&User{})
|
||||
Count(&user.User{})
|
||||
return taskAssignees, len(taskAssignees), numberOfTotalItems, err
|
||||
}
|
||||
|
||||
// BulkAssignees is a helper struct used to update multiple assignees at once.
|
||||
type BulkAssignees struct {
|
||||
// A list with all assignees
|
||||
Assignees []*User `json:"assignees"`
|
||||
TaskID int64 `json:"-" param:"listtask"`
|
||||
Assignees []*user.User `json:"assignees"`
|
||||
TaskID int64 `json:"-" param:"listtask"`
|
||||
|
||||
web.CRUDable `json:"-"`
|
||||
web.Rights `json:"-"`
|
||||
|
|
|
@ -18,6 +18,7 @@ package models
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"io"
|
||||
"time"
|
||||
|
@ -29,8 +30,8 @@ type TaskAttachment struct {
|
|||
TaskID int64 `xorm:"int(11) not null" json:"task_id" param:"task"`
|
||||
FileID int64 `xorm:"int(11) not null" json:"-"`
|
||||
|
||||
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
|
||||
CreatedBy *User `xorm:"-" json:"created_by"`
|
||||
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
|
||||
CreatedBy *user.User `xorm:"-" json:"created_by"`
|
||||
|
||||
File *files.File `xorm:"-" json:"file"`
|
||||
|
||||
|
@ -132,7 +133,7 @@ func (ta *TaskAttachment) ReadAll(a web.Auth, search string, page int, perPage i
|
|||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
us := make(map[int64]*User)
|
||||
us := make(map[int64]*user.User)
|
||||
err = x.In("id", userIDs).Find(&us)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
|
|
|
@ -20,6 +20,7 @@ package models
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io"
|
||||
"os"
|
||||
|
@ -95,7 +96,7 @@ func TestTaskAttachment_NewAttachment(t *testing.T) {
|
|||
tf := &testfile{
|
||||
content: []byte("testingstuff"),
|
||||
}
|
||||
testuser := &User{ID: 1}
|
||||
testuser := &user.User{ID: 1}
|
||||
|
||||
err := ta.NewAttachment(tf, "testfile", 100, testuser)
|
||||
assert.NoError(t, err)
|
||||
|
@ -119,7 +120,7 @@ func TestTaskAttachment_NewAttachment(t *testing.T) {
|
|||
func TestTaskAttachment_ReadAll(t *testing.T) {
|
||||
files.InitTestFileFixtures(t)
|
||||
ta := &TaskAttachment{TaskID: 1}
|
||||
as, _, _, err := ta.ReadAll(&User{ID: 1}, "", 0, 50)
|
||||
as, _, _, err := ta.ReadAll(&user.User{ID: 1}, "", 0, 50)
|
||||
attachments, _ := as.([]*TaskAttachment)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, attachments, 3)
|
||||
|
@ -152,7 +153,7 @@ func TestTaskAttachment_Delete(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTaskAttachment_Rights(t *testing.T) {
|
||||
u := &User{ID: 1}
|
||||
u := &user.User{ID: 1}
|
||||
t.Run("Can Read", func(t *testing.T) {
|
||||
t.Run("Allowed", func(t *testing.T) {
|
||||
ta := &TaskAttachment{TaskID: 1}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"time"
|
||||
)
|
||||
|
@ -108,7 +109,7 @@ func (tf *TaskCollection) ReadAll(a web.Auth, search string, page int, perPage i
|
|||
// If the list ID is not set, we get all tasks for the user.
|
||||
// This allows to use this function in Task.ReadAll with a possibility to deprecate the latter at some point.
|
||||
if tf.ListID == 0 {
|
||||
tf.Lists, _, _, err = getRawListsForUser("", &User{ID: a.GetID()}, -1, 0)
|
||||
tf.Lists, _, _, err = getRawListsForUser("", &user.User{ID: a.GetID()}, -1, 0)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package models
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
|
@ -29,20 +30,20 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
assert.NoError(t, db.LoadFixtures())
|
||||
|
||||
// Dummy users
|
||||
user1 := &User{
|
||||
user1 := &user.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
AvatarURL: "111d68d06e2d317b5a59c2c6c5bad808", // hash for ""
|
||||
}
|
||||
user2 := &User{
|
||||
user2 := &user.User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
AvatarURL: "ab53a2911ddf9b4817ac01ddcd3d975f", // hash for ""
|
||||
}
|
||||
user6 := &User{
|
||||
user6 := &user.User{
|
||||
ID: 6,
|
||||
Username: "user6",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -463,7 +464,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
CreatedByID: 1,
|
||||
CreatedBy: user1,
|
||||
ListID: 1,
|
||||
Assignees: []*User{
|
||||
Assignees: []*user.User{
|
||||
user1,
|
||||
user2,
|
||||
},
|
||||
|
@ -538,7 +539,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
fields: fields{},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*Task{
|
||||
|
@ -585,7 +586,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*Task{
|
||||
|
@ -631,7 +632,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*Task{
|
||||
|
@ -648,7 +649,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*Task{
|
||||
|
@ -664,7 +665,7 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*Task{
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
)
|
||||
|
||||
|
@ -83,7 +84,7 @@ type TaskRelation struct {
|
|||
|
||||
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
|
||||
// The user who created this relation
|
||||
CreatedBy *User `xorm:"-" json:"created_by"`
|
||||
CreatedBy *user.User `xorm:"-" json:"created_by"`
|
||||
|
||||
// A unix timestamp when this label was created. You cannot change this value.
|
||||
Created int64 `xorm:"created not null" json:"created"`
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
@ -29,7 +30,7 @@ func TestTaskRelation_Create(t *testing.T) {
|
|||
OtherTaskID: 2,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
err := rel.Create(&User{ID: 1})
|
||||
err := rel.Create(&user.User{ID: 1})
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("Two Tasks In Different Lists", func(t *testing.T) {
|
||||
|
@ -38,7 +39,7 @@ func TestTaskRelation_Create(t *testing.T) {
|
|||
OtherTaskID: 13,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
err := rel.Create(&User{ID: 1})
|
||||
err := rel.Create(&user.User{ID: 1})
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("Already Existing", func(t *testing.T) {
|
||||
|
@ -47,7 +48,7 @@ func TestTaskRelation_Create(t *testing.T) {
|
|||
OtherTaskID: 29,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
err := rel.Create(&User{ID: 1})
|
||||
err := rel.Create(&user.User{ID: 1})
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrRelationAlreadyExists(err))
|
||||
})
|
||||
|
@ -56,7 +57,7 @@ func TestTaskRelation_Create(t *testing.T) {
|
|||
TaskID: 1,
|
||||
OtherTaskID: 1,
|
||||
}
|
||||
err := rel.Create(&User{ID: 1})
|
||||
err := rel.Create(&user.User{ID: 1})
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrRelationTasksCannotBeTheSame(err))
|
||||
})
|
||||
|
@ -91,7 +92,7 @@ func TestTaskRelation_CanCreate(t *testing.T) {
|
|||
OtherTaskID: 2,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
can, err := rel.CanCreate(&User{ID: 1})
|
||||
can, err := rel.CanCreate(&user.User{ID: 1})
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, can)
|
||||
})
|
||||
|
@ -101,7 +102,7 @@ func TestTaskRelation_CanCreate(t *testing.T) {
|
|||
OtherTaskID: 13,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
can, err := rel.CanCreate(&User{ID: 1})
|
||||
can, err := rel.CanCreate(&user.User{ID: 1})
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, can)
|
||||
})
|
||||
|
@ -111,7 +112,7 @@ func TestTaskRelation_CanCreate(t *testing.T) {
|
|||
OtherTaskID: 1,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
can, err := rel.CanCreate(&User{ID: 1})
|
||||
can, err := rel.CanCreate(&user.User{ID: 1})
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, can)
|
||||
})
|
||||
|
@ -121,7 +122,7 @@ func TestTaskRelation_CanCreate(t *testing.T) {
|
|||
OtherTaskID: 1,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
can, err := rel.CanCreate(&User{ID: 1})
|
||||
can, err := rel.CanCreate(&user.User{ID: 1})
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, can)
|
||||
})
|
||||
|
@ -131,7 +132,7 @@ func TestTaskRelation_CanCreate(t *testing.T) {
|
|||
OtherTaskID: 14,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
can, err := rel.CanCreate(&User{ID: 1})
|
||||
can, err := rel.CanCreate(&user.User{ID: 1})
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, can)
|
||||
})
|
||||
|
@ -141,7 +142,7 @@ func TestTaskRelation_CanCreate(t *testing.T) {
|
|||
OtherTaskID: 1,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
can, err := rel.CanCreate(&User{ID: 1})
|
||||
can, err := rel.CanCreate(&user.User{ID: 1})
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrTaskDoesNotExist(err))
|
||||
assert.False(t, can)
|
||||
|
@ -152,7 +153,7 @@ func TestTaskRelation_CanCreate(t *testing.T) {
|
|||
OtherTaskID: 999999,
|
||||
RelationKind: RelationKindSubtask,
|
||||
}
|
||||
can, err := rel.CanCreate(&User{ID: 1})
|
||||
can, err := rel.CanCreate(&user.User{ID: 1})
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrTaskDoesNotExist(err))
|
||||
assert.False(t, can)
|
||||
|
|
|
@ -19,6 +19,7 @@ package models
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/api/pkg/metrics"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/api/pkg/utils"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/imdario/mergo"
|
||||
|
@ -55,7 +56,7 @@ type Task struct {
|
|||
// When this task ends.
|
||||
EndDateUnix int64 `xorm:"int(11) INDEX null" json:"endDate" query:"-"`
|
||||
// An array of users who are assigned to this task
|
||||
Assignees []*User `xorm:"-" json:"assignees"`
|
||||
Assignees []*user.User `xorm:"-" json:"assignees"`
|
||||
// An array of labels which are associated with this task.
|
||||
Labels []*Label `xorm:"-" json:"labels"`
|
||||
// The task color in hex
|
||||
|
@ -87,7 +88,7 @@ type Task struct {
|
|||
Updated int64 `xorm:"updated not null" json:"updated"`
|
||||
|
||||
// The user who initially created the task.
|
||||
CreatedBy *User `xorm:"-" json:"createdBy" valid:"-"`
|
||||
CreatedBy *user.User `xorm:"-" json:"createdBy" valid:"-"`
|
||||
|
||||
web.CRUDable `xorm:"-" json:"-"`
|
||||
web.Rights `xorm:"-" json:"-"`
|
||||
|
@ -365,7 +366,7 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (tasks []*Task, err error) {
|
|||
|
||||
// Get all users of a task
|
||||
// aka the ones who created a task
|
||||
users := make(map[int64]*User)
|
||||
users := make(map[int64]*user.User)
|
||||
err = x.In("id", userIDs).Find(&users)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -487,7 +488,7 @@ func (t *Task) Create(a web.Auth) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
u, err := GetUserByID(a.GetID())
|
||||
u, err := user.GetUserByID(a.GetID())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,12 +17,13 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
user2 "code.vikunja.io/api/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTask_Create(t *testing.T) {
|
||||
user := &User{
|
||||
user := &user2.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Email: "user1@example.com",
|
||||
|
@ -70,7 +71,7 @@ func TestTask_Create(t *testing.T) {
|
|||
})
|
||||
t.Run("noneixtant user", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
nUser := &User{ID: 99999999}
|
||||
nUser := &user2.User{ID: 99999999}
|
||||
task := &Task{
|
||||
Text: "Test",
|
||||
Description: "Lorem Ipsum Dolor",
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
|
||||
package models
|
||||
|
||||
import "code.vikunja.io/web"
|
||||
import (
|
||||
user2 "code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
)
|
||||
|
||||
// Create implements the create method to assign a user to a team
|
||||
// @Summary Add a user to a team
|
||||
|
@ -41,7 +44,7 @@ func (tm *TeamMember) Create(a web.Auth) (err error) {
|
|||
}
|
||||
|
||||
// Check if the user exists
|
||||
user, err := GetUserByUsername(tm.Username)
|
||||
user, err := user2.GetUserByUsername(tm.Username)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -84,7 +87,7 @@ func (tm *TeamMember) Delete() (err error) {
|
|||
}
|
||||
|
||||
// Find the numeric user id
|
||||
user, err := GetUserByUsername(tm.Username)
|
||||
user, err := user2.GetUserByUsername(tm.Username)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
@ -30,7 +31,7 @@ func TestTeamMember_Create(t *testing.T) {
|
|||
}
|
||||
|
||||
// Doer
|
||||
doer, err := GetUserByID(1)
|
||||
doer, err := user.GetUserByID(1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Insert a new team member
|
||||
|
|
|
@ -18,6 +18,7 @@ package models
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/metrics"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
)
|
||||
|
||||
|
@ -32,7 +33,7 @@ type Team struct {
|
|||
CreatedByID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
||||
|
||||
// The user who created this team.
|
||||
CreatedBy *User `xorm:"-" json:"createdBy"`
|
||||
CreatedBy *user.User `xorm:"-" json:"createdBy"`
|
||||
// An array of all members in this team.
|
||||
Members []*TeamUser `xorm:"-" json:"members"`
|
||||
|
||||
|
@ -53,7 +54,7 @@ func (Team) TableName() string {
|
|||
// AfterLoad gets the created by user object
|
||||
func (t *Team) AfterLoad() {
|
||||
// Get the owner
|
||||
t.CreatedBy, _ = GetUserByID(t.CreatedByID)
|
||||
t.CreatedBy, _ = user.GetUserByID(t.CreatedByID)
|
||||
|
||||
// Get all members
|
||||
x.Select("*").
|
||||
|
@ -90,7 +91,7 @@ func (TeamMember) TableName() string {
|
|||
|
||||
// TeamUser is the team member type
|
||||
type TeamUser struct {
|
||||
User `xorm:"extends"`
|
||||
user.User `xorm:"extends"`
|
||||
// Whether or not the member is an admin of the team. See the docs for more about what a team admin can do
|
||||
Admin bool `json:"admin"`
|
||||
}
|
||||
|
@ -181,7 +182,7 @@ func (t *Team) ReadAll(a web.Auth, search string, page int, perPage int) (result
|
|||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /teams [put]
|
||||
func (t *Team) Create(a web.Auth) (err error) {
|
||||
doer, err := getUserWithError(a)
|
||||
doer, err := user.GetFromAuth(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"testing"
|
||||
|
||||
"code.vikunja.io/web"
|
||||
|
@ -28,7 +29,7 @@ func TestTeam_CanDoSomething(t *testing.T) {
|
|||
Name string
|
||||
Description string
|
||||
CreatedByID int64
|
||||
CreatedBy *User
|
||||
CreatedBy *user.User
|
||||
Members []*TeamUser
|
||||
Created int64
|
||||
Updated int64
|
||||
|
@ -50,7 +51,7 @@ func TestTeam_CanDoSomething(t *testing.T) {
|
|||
ID: 1,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": true, "IsAdmin": true, "CanRead": true, "CanDelete": true, "CanUpdate": true},
|
||||
},
|
||||
|
@ -60,7 +61,7 @@ func TestTeam_CanDoSomething(t *testing.T) {
|
|||
ID: 300,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 1},
|
||||
a: &user.User{ID: 1},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": true, "IsAdmin": false, "CanRead": false, "CanDelete": false, "CanUpdate": false},
|
||||
},
|
||||
|
@ -70,7 +71,7 @@ func TestTeam_CanDoSomething(t *testing.T) {
|
|||
ID: 1,
|
||||
},
|
||||
args: args{
|
||||
a: &User{ID: 4},
|
||||
a: &user.User{ID: 4},
|
||||
},
|
||||
want: map[string]bool{"CanCreate": true, "IsAdmin": false, "CanRead": false, "CanDelete": false, "CanUpdate": false},
|
||||
},
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
@ -30,7 +31,7 @@ func TestTeam_Create(t *testing.T) {
|
|||
}
|
||||
|
||||
// Doer
|
||||
doer, err := GetUserByID(1)
|
||||
doer, err := user.GetUserByID(1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Insert it
|
||||
|
|
|
@ -1,40 +1,26 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2020 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// 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.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
|
||||
import "github.com/go-xorm/builder"
|
||||
|
||||
// ListUsers returns a list with all users, filtered by an optional searchstring
|
||||
func ListUsers(searchterm string) (users []User, err error) {
|
||||
|
||||
if searchterm == "" {
|
||||
err = x.Find(&users)
|
||||
} else {
|
||||
err = x.
|
||||
Where("username LIKE ?", "%"+searchterm+"%").
|
||||
Find(&users)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return []User{}, err
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"github.com/go-xorm/builder"
|
||||
)
|
||||
|
||||
// ListUIDs hold all kinds of user IDs from accounts who have somehow access to a list
|
||||
type ListUIDs struct {
|
||||
|
@ -47,7 +33,7 @@ type ListUIDs struct {
|
|||
}
|
||||
|
||||
// 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) {
|
||||
func ListUsersFromList(l *List, search string) (users []*user.User, err error) {
|
||||
|
||||
userids := []*ListUIDs{}
|
||||
|
|
@ -1,7 +1,25 @@
|
|||
// 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 models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"testing"
|
||||
|
@ -12,27 +30,27 @@ func TestListUsersFromList(t *testing.T) {
|
|||
err := db.LoadFixtures()
|
||||
assert.NoError(t, err)
|
||||
|
||||
testuser1 := &User{
|
||||
testuser1 := &user.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
AvatarURL: "111d68d06e2d317b5a59c2c6c5bad808",
|
||||
}
|
||||
testuser2 := &User{
|
||||
testuser2 := &user.User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
AvatarURL: "ab53a2911ddf9b4817ac01ddcd3d975f",
|
||||
}
|
||||
testuser3 := &User{
|
||||
testuser3 := &user.User{
|
||||
ID: 3,
|
||||
Username: "user3",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
AvatarURL: "97d6d9441ff85fdc730e02a6068d267b",
|
||||
PasswordResetToken: "passwordresettesttoken",
|
||||
}
|
||||
testuser4 := &User{
|
||||
testuser4 := &user.User{
|
||||
ID: 4,
|
||||
Username: "user4",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -40,7 +58,7 @@ func TestListUsersFromList(t *testing.T) {
|
|||
AvatarURL: "7e65550957227bd38fe2d7fbc6fd2f7b",
|
||||
EmailConfirmToken: "tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael",
|
||||
}
|
||||
testuser5 := &User{
|
||||
testuser5 := &user.User{
|
||||
ID: 5,
|
||||
Username: "user5",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -48,56 +66,56 @@ func TestListUsersFromList(t *testing.T) {
|
|||
AvatarURL: "cfa35b8cd2ec278026357769582fa563",
|
||||
EmailConfirmToken: "tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael",
|
||||
}
|
||||
testuser6 := &User{
|
||||
testuser6 := &user.User{
|
||||
ID: 6,
|
||||
Username: "user6",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
AvatarURL: "3efbe51f864c6666bc27caf4c6ff90ed",
|
||||
}
|
||||
testuser7 := &User{
|
||||
testuser7 := &user.User{
|
||||
ID: 7,
|
||||
Username: "user7",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
AvatarURL: "e80a711d4de44c30054806ebbd488464",
|
||||
}
|
||||
testuser8 := &User{
|
||||
testuser8 := &user.User{
|
||||
ID: 8,
|
||||
Username: "user8",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
AvatarURL: "2b9b320416cd31020bb6844c3fadefd1",
|
||||
}
|
||||
testuser9 := &User{
|
||||
testuser9 := &user.User{
|
||||
ID: 9,
|
||||
Username: "user9",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
AvatarURL: "f784fdb21d26dd2c64f5135f35ec401f",
|
||||
}
|
||||
testuser10 := &User{
|
||||
testuser10 := &user.User{
|
||||
ID: 10,
|
||||
Username: "user10",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
AvatarURL: "fce8ff4ff56d75ad587d1bbaa5ef0563",
|
||||
}
|
||||
testuser11 := &User{
|
||||
testuser11 := &user.User{
|
||||
ID: 11,
|
||||
Username: "user11",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
AvatarURL: "ad6d67d0c4495e186010732a7d360028",
|
||||
}
|
||||
testuser12 := &User{
|
||||
testuser12 := &user.User{
|
||||
ID: 12,
|
||||
Username: "user12",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
AvatarURL: "ef1debc1364806281c42eeedfdeb943b",
|
||||
}
|
||||
testuser13 := &User{
|
||||
testuser13 := &user.User{
|
||||
ID: 13,
|
||||
Username: "user13",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
|
@ -112,19 +130,19 @@ func TestListUsersFromList(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantUsers []*User
|
||||
wantUsers []*user.User
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Check owner only",
|
||||
args: args{l: &List{ID: 18, OwnerID: 7}},
|
||||
wantUsers: []*User{testuser7},
|
||||
wantUsers: []*user.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{
|
||||
wantUsers: []*user.User{
|
||||
testuser1, // Shared Via Team readonly
|
||||
testuser2, // Shared Via Team write
|
||||
testuser3, // Shared Via Team admin
|
||||
|
|
|
@ -19,12 +19,13 @@ package migration
|
|||
import (
|
||||
"bytes"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// InsertFromStructure takes a fully nested Vikunja data structure and a user and then creates everything for this user
|
||||
// (Namespaces, tasks, etc. Even attachments and relations.)
|
||||
func InsertFromStructure(str []*models.NamespaceWithLists, user *models.User) (err error) {
|
||||
func InsertFromStructure(str []*models.NamespaceWithLists, user *user.User) (err error) {
|
||||
|
||||
// Create all namespaces
|
||||
for _, n := range str {
|
||||
|
|
|
@ -19,6 +19,7 @@ package handler
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/modules/migration"
|
||||
user2 "code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
|
@ -53,7 +54,7 @@ func (mw *MigrationWeb) Migrate(c echo.Context) error {
|
|||
ms := mw.MigrationStruct()
|
||||
|
||||
// Get the user from context
|
||||
user, err := models.GetCurrentUser(c)
|
||||
user, err := user2.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
@ -82,7 +83,7 @@ func (mw *MigrationWeb) Migrate(c echo.Context) error {
|
|||
func (mw *MigrationWeb) Status(c echo.Context) error {
|
||||
ms := mw.MigrationStruct()
|
||||
|
||||
user, err := models.GetCurrentUser(c)
|
||||
user, err := user2.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
package migration
|
||||
|
||||
import "code.vikunja.io/api/pkg/models"
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
)
|
||||
|
||||
// Status represents this migration status
|
||||
type Status struct {
|
||||
|
@ -32,7 +34,7 @@ func (s *Status) TableName() string {
|
|||
}
|
||||
|
||||
// SetMigrationStatus sets the migration status for a user
|
||||
func SetMigrationStatus(m Migrator, u *models.User) (err error) {
|
||||
func SetMigrationStatus(m Migrator, u *user.User) (err error) {
|
||||
status := &Status{
|
||||
UserID: u.ID,
|
||||
MigratorName: m.Name(),
|
||||
|
@ -42,7 +44,7 @@ func SetMigrationStatus(m Migrator, u *models.User) (err error) {
|
|||
}
|
||||
|
||||
// GetMigrationStatus returns the migration status for a migration and a user
|
||||
func GetMigrationStatus(m Migrator, u *models.User) (status *Status, err error) {
|
||||
func GetMigrationStatus(m Migrator, u *user.User) (status *Status, err error) {
|
||||
status = &Status{}
|
||||
_, err = x.Where("user_id = ? and migrator_name = ?", u.ID, m.Name()).Desc("id").Get(status)
|
||||
return
|
||||
|
|
|
@ -17,13 +17,15 @@
|
|||
|
||||
package migration
|
||||
|
||||
import "code.vikunja.io/api/pkg/models"
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
)
|
||||
|
||||
// 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
|
||||
Migrate(user *user.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.
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/modules/migration"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/api/pkg/utils"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -341,7 +342,7 @@ func makeAuthGetRequest(token *wunderlistAuthToken, urlPart string, v interface{
|
|||
// @Success 200 {object} models.Message "A message telling you everything was migrated successfully."
|
||||
// @Failure 500 {object} models.Message "Internal server error"
|
||||
// @Router /migration/wunderlist/migrate [post]
|
||||
func (w *Migration) Migrate(user *models.User) (err error) {
|
||||
func (w *Migration) Migrate(user *user.User) (err error) {
|
||||
|
||||
log.Debugf("[Wunderlist migration] Starting wunderlist migration for user %d", user.ID)
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package v1
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
@ -34,7 +35,7 @@ const (
|
|||
)
|
||||
|
||||
// NewUserJWTAuthtoken generates and signes a new jwt token for a user. This is a global function to be able to call it from integration tests.
|
||||
func NewUserJWTAuthtoken(user *models.User) (token string, err error) {
|
||||
func NewUserJWTAuthtoken(user *user.User) (token string, err error) {
|
||||
t := jwt.New(jwt.SigningMethodHS256)
|
||||
|
||||
// Set claims
|
||||
|
@ -78,7 +79,7 @@ func GetAuthFromClaims(c echo.Context) (a web.Auth, err error) {
|
|||
return models.GetLinkShareFromClaims(claims)
|
||||
}
|
||||
if typ == AuthTypeUser {
|
||||
return models.GetUserFromClaims(claims)
|
||||
return user.GetUserFromClaims(claims)
|
||||
}
|
||||
return nil, echo.NewHTTPError(http.StatusBadRequest, models.Message{Message: "Invalid JWT token."})
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package v1
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
|
@ -46,7 +47,7 @@ func GetListsByNamespaceID(c echo.Context) error {
|
|||
}
|
||||
|
||||
// Get the lists
|
||||
doer, err := models.GetCurrentUser(c)
|
||||
doer, err := user.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
@ -73,7 +74,7 @@ func getNamespace(c echo.Context) (namespace *models.Namespace, err error) {
|
|||
}
|
||||
|
||||
// Check if the user has acces to that namespace
|
||||
user, err := models.GetCurrentUser(c)
|
||||
user, err := user.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package v1
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
user2 "code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
@ -41,13 +42,13 @@ type Token struct {
|
|||
// @Failure 403 {object} models.Message "Invalid username or password."
|
||||
// @Router /login [post]
|
||||
func Login(c echo.Context) error {
|
||||
u := models.UserLogin{}
|
||||
u := user2.UserLogin{}
|
||||
if err := c.Bind(&u); err != nil {
|
||||
return c.JSON(http.StatusBadRequest, models.Message{"Please provide a username and password."})
|
||||
}
|
||||
|
||||
// Check user
|
||||
user, err := models.CheckUserCredentials(&u)
|
||||
user, err := user2.CheckUserCredentials(&u)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
@ -80,7 +81,7 @@ func RenewToken(c echo.Context) error {
|
|||
return echo.ErrBadRequest
|
||||
}
|
||||
|
||||
user, err := models.GetUserFromClaims(claims)
|
||||
user, err := user2.GetUserFromClaims(claims)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package v1
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
user2 "code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
|
@ -45,7 +46,7 @@ func UploadTaskAttachment(c echo.Context) error {
|
|||
}
|
||||
|
||||
// Rights check
|
||||
user, err := models.GetCurrentUser(c)
|
||||
user, err := user2.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
@ -114,7 +115,7 @@ func GetTaskAttachment(c echo.Context) error {
|
|||
}
|
||||
|
||||
// Rights check
|
||||
user, err := models.GetCurrentUser(c)
|
||||
user, err := user2.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package v1
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
|
@ -40,13 +41,20 @@ func RegisterUser(c echo.Context) error {
|
|||
return echo.ErrNotFound
|
||||
}
|
||||
// Check for Request Content
|
||||
var datUser *models.APIUserPassword
|
||||
var datUser *user.APIUserPassword
|
||||
if err := c.Bind(&datUser); err != nil {
|
||||
return c.JSON(http.StatusBadRequest, models.Message{"No or invalid user model provided."})
|
||||
}
|
||||
|
||||
// Insert the user
|
||||
newUser, err := models.CreateUser(datUser.APIFormat())
|
||||
newUser, err := user.CreateUser(datUser.APIFormat())
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
// Add its namespace
|
||||
newN := &models.Namespace{Name: newUser.Username, Description: newUser.Username + "'s namespace.", Owner: newUser}
|
||||
err = newN.Create(newUser)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package v1
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
|
@ -36,12 +37,12 @@ import (
|
|||
// @Router /user/confirm [post]
|
||||
func UserConfirmEmail(c echo.Context) error {
|
||||
// Check for Request Content
|
||||
var emailConfirm models.EmailConfirm
|
||||
var emailConfirm user.EmailConfirm
|
||||
if err := c.Bind(&emailConfirm); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "No token provided.")
|
||||
}
|
||||
|
||||
err := models.UserEmailConfirm(&emailConfirm)
|
||||
err := user.UserEmailConfirm(&emailConfirm)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
// Vikunja is a todo-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 v1
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// UserDelete is the handler to delete a user
|
||||
func UserDelete(c echo.Context) error {
|
||||
|
||||
// TODO: only allow users to allow itself
|
||||
|
||||
id := c.Param("id")
|
||||
|
||||
// Make int
|
||||
userID, err := strconv.ParseInt(id, 10, 64)
|
||||
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusBadRequest, models.Message{"User ID is invalid."})
|
||||
}
|
||||
|
||||
// Check if the user exists
|
||||
_, err = models.GetUserByID(userID)
|
||||
|
||||
if err != nil {
|
||||
if models.IsErrUserDoesNotExist(err) {
|
||||
return c.JSON(http.StatusNotFound, models.Message{"The user does not exist."})
|
||||
}
|
||||
return c.JSON(http.StatusInternalServerError, models.Message{"Could not get user."})
|
||||
}
|
||||
|
||||
// Get the doer options
|
||||
doer, err := models.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete it
|
||||
err = models.DeleteUserByID(userID, doer)
|
||||
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, models.Message{"success"})
|
||||
}
|
|
@ -18,6 +18,7 @@ package v1
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
|
@ -38,7 +39,7 @@ import (
|
|||
// @Router /users [get]
|
||||
func UserList(c echo.Context) error {
|
||||
s := c.QueryParam("s")
|
||||
users, err := models.ListUsers(s)
|
||||
users, err := user.ListUsers(s)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
@ -72,7 +73,7 @@ func ListUsersForList(c echo.Context) error {
|
|||
}
|
||||
|
||||
list := models.List{ID: listID}
|
||||
currentUser, err := models.GetCurrentUser(c)
|
||||
currentUser, err := user.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package v1
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
|
@ -36,12 +37,12 @@ import (
|
|||
// @Router /user/password/reset [post]
|
||||
func UserResetPassword(c echo.Context) error {
|
||||
// Check for Request Content
|
||||
var pwReset models.PasswordReset
|
||||
var pwReset user.PasswordReset
|
||||
if err := c.Bind(&pwReset); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "No password provided.")
|
||||
}
|
||||
|
||||
err := models.UserPasswordReset(&pwReset)
|
||||
err := user.UserPasswordReset(&pwReset)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ func UserResetPassword(c echo.Context) error {
|
|||
// @Router /user/password/token [post]
|
||||
func UserRequestResetPasswordToken(c echo.Context) error {
|
||||
// Check for Request Content
|
||||
var pwTokenReset models.PasswordTokenRequest
|
||||
var pwTokenReset user.PasswordTokenRequest
|
||||
if err := c.Bind(&pwTokenReset); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "No username provided.")
|
||||
}
|
||||
|
@ -71,7 +72,7 @@ func UserRequestResetPasswordToken(c echo.Context) error {
|
|||
return echo.NewHTTPError(http.StatusBadRequest, err)
|
||||
}
|
||||
|
||||
err := models.RequestUserPasswordResetToken(&pwTokenReset)
|
||||
err := user.RequestUserPasswordResetToken(&pwTokenReset)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
user2 "code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
|
@ -35,12 +35,12 @@ import (
|
|||
// @Failure 500 {object} models.Message "Internal server error."
|
||||
// @Router /user [get]
|
||||
func UserShow(c echo.Context) error {
|
||||
userInfos, err := models.GetCurrentUser(c)
|
||||
userInfos, err := user2.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Error getting current user.")
|
||||
}
|
||||
|
||||
user, err := models.GetUserByID(userInfos.ID)
|
||||
user, err := user2.GetUserByID(userInfos.ID)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package v1
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
|
@ -44,7 +45,7 @@ type UserPassword struct {
|
|||
// @Router /user/password [post]
|
||||
func UserChangePassword(c echo.Context) error {
|
||||
// Check if the user is itself
|
||||
doer, err := models.GetCurrentUser(c)
|
||||
doer, err := user.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Error getting current user.")
|
||||
}
|
||||
|
@ -56,16 +57,16 @@ func UserChangePassword(c echo.Context) error {
|
|||
}
|
||||
|
||||
if newPW.OldPassword == "" {
|
||||
return handler.HandleHTTPError(models.ErrEmptyOldPassword{}, c)
|
||||
return handler.HandleHTTPError(user.ErrEmptyOldPassword{}, c)
|
||||
}
|
||||
|
||||
// Check the current password
|
||||
if _, err = models.CheckUserCredentials(&models.UserLogin{Username: doer.Username, Password: newPW.OldPassword}); err != nil {
|
||||
if _, err = user.CheckUserCredentials(&user.UserLogin{Username: doer.Username, Password: newPW.OldPassword}); err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
// Update the password
|
||||
if err = models.UpdateUserPassword(doer, newPW.NewPassword); err != nil {
|
||||
if err = user.UpdateUserPassword(doer, newPW.NewPassword); err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"bytes"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"fmt"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
@ -31,10 +32,10 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func getBasicAuthUserFromContext(c echo.Context) (user models.User, err error) {
|
||||
u, is := c.Get("userBasicAuth").(models.User)
|
||||
func getBasicAuthUserFromContext(c echo.Context) (user.User, error) {
|
||||
u, is := c.Get("userBasicAuth").(user.User)
|
||||
if !is {
|
||||
return models.User{}, fmt.Errorf("user is not user element, is %s", reflect.TypeOf(c.Get("userBasicAuth")))
|
||||
return user.User{}, fmt.Errorf("user is not user element, is %s", reflect.TypeOf(c.Get("userBasicAuth")))
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package caldav
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
user2 "code.vikunja.io/api/pkg/user"
|
||||
"github.com/samedi/caldav-go/data"
|
||||
"github.com/samedi/caldav-go/errs"
|
||||
"strconv"
|
||||
|
@ -39,7 +40,7 @@ type VikunjaCaldavListStorage struct {
|
|||
// Used when handling a single task, like updating
|
||||
task *models.Task
|
||||
// The current user
|
||||
user *models.User
|
||||
user *user2.User
|
||||
isPrincipal bool
|
||||
isEntry bool // Entry level handling should only return a link to the principal url
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"code.vikunja.io/api/pkg/metrics"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
v1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"time"
|
||||
|
@ -51,7 +52,7 @@ func setupMetrics(a *echo.Group) {
|
|||
},
|
||||
{
|
||||
metrics.UserCountKey,
|
||||
models.User{},
|
||||
user.User{},
|
||||
},
|
||||
{
|
||||
metrics.NamespaceCountKey,
|
||||
|
|
|
@ -53,6 +53,7 @@ import (
|
|||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"code.vikunja.io/api/pkg/routes/caldav"
|
||||
_ "code.vikunja.io/api/pkg/swagger" // To generate swagger docs
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/asaskevich/govalidator"
|
||||
|
@ -407,11 +408,11 @@ func registerCalDavRoutes(c *echo.Group) {
|
|||
}
|
||||
|
||||
func caldavBasicAuth(username, password string, c echo.Context) (bool, error) {
|
||||
creds := &models.UserLogin{
|
||||
creds := &user.UserLogin{
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
u, err := models.CheckUserCredentials(creds)
|
||||
u, err := user.CheckUserCredentials(creds)
|
||||
if err != nil {
|
||||
log.Errorf("Error during basic auth for caldav: %v", err)
|
||||
return false, nil
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// 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 user
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
var x *xorm.Engine
|
||||
|
||||
// InitDB sets up the database connection to use in this module
|
||||
func InitDB() (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{}{
|
||||
&User{},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,291 @@
|
|||
// 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 user
|
||||
|
||||
import (
|
||||
"code.vikunja.io/web"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// =====================
|
||||
// User Operation Errors
|
||||
// =====================
|
||||
|
||||
// ErrUsernameExists represents a "UsernameAlreadyExists" kind of error.
|
||||
type ErrUsernameExists struct {
|
||||
UserID int64
|
||||
Username string
|
||||
}
|
||||
|
||||
// IsErrUsernameExists checks if an error is a ErrUsernameExists.
|
||||
func IsErrUsernameExists(err error) bool {
|
||||
_, ok := err.(ErrUsernameExists)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUsernameExists) Error() string {
|
||||
return fmt.Sprintf("User with that username already exists [user id: %d, username: %s]", err.UserID, err.Username)
|
||||
}
|
||||
|
||||
// ErrorCodeUsernameExists holds the unique world-error code of this error
|
||||
const ErrorCodeUsernameExists = 1001
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrUsernameExists) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrorCodeUsernameExists, Message: "A user with this username already exists."}
|
||||
}
|
||||
|
||||
// ErrUserEmailExists represents a "UserEmailExists" kind of error.
|
||||
type ErrUserEmailExists struct {
|
||||
UserID int64
|
||||
Email string
|
||||
}
|
||||
|
||||
// IsErrUserEmailExists checks if an error is a ErrUserEmailExists.
|
||||
func IsErrUserEmailExists(err error) bool {
|
||||
_, ok := err.(ErrUserEmailExists)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserEmailExists) Error() string {
|
||||
return fmt.Sprintf("User with that email already exists [user id: %d, email: %s]", err.UserID, err.Email)
|
||||
}
|
||||
|
||||
// ErrorCodeUserEmailExists holds the unique world-error code of this error
|
||||
const ErrorCodeUserEmailExists = 1002
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrUserEmailExists) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrorCodeUserEmailExists, Message: "A user with this email address already exists."}
|
||||
}
|
||||
|
||||
// ErrNoUsernamePassword represents a "NoUsernamePassword" kind of error.
|
||||
type ErrNoUsernamePassword struct{}
|
||||
|
||||
// IsErrNoUsernamePassword checks if an error is a ErrNoUsernamePassword.
|
||||
func IsErrNoUsernamePassword(err error) bool {
|
||||
_, ok := err.(ErrNoUsernamePassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrNoUsernamePassword) Error() string {
|
||||
return fmt.Sprintf("No username and password provided")
|
||||
}
|
||||
|
||||
// ErrCodeNoUsernamePassword holds the unique world-error code of this error
|
||||
const ErrCodeNoUsernamePassword = 1004
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrNoUsernamePassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeNoUsernamePassword, Message: "Please specify a username and a password."}
|
||||
}
|
||||
|
||||
// ErrUserDoesNotExist represents a "UserDoesNotExist" kind of error.
|
||||
type ErrUserDoesNotExist struct {
|
||||
UserID int64
|
||||
}
|
||||
|
||||
// IsErrUserDoesNotExist checks if an error is a ErrUserDoesNotExist.
|
||||
func IsErrUserDoesNotExist(err error) bool {
|
||||
_, ok := err.(ErrUserDoesNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserDoesNotExist) Error() string {
|
||||
return fmt.Sprintf("User does not exist [user id: %d]", err.UserID)
|
||||
}
|
||||
|
||||
// ErrCodeUserDoesNotExist holds the unique world-error code of this error
|
||||
const ErrCodeUserDoesNotExist = 1005
|
||||
|
||||
// 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."}
|
||||
}
|
||||
|
||||
// ErrCouldNotGetUserID represents a "ErrCouldNotGetUserID" kind of error.
|
||||
type ErrCouldNotGetUserID struct{}
|
||||
|
||||
// IsErrCouldNotGetUserID checks if an error is a ErrCouldNotGetUserID.
|
||||
func IsErrCouldNotGetUserID(err error) bool {
|
||||
_, ok := err.(ErrCouldNotGetUserID)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrCouldNotGetUserID) Error() string {
|
||||
return fmt.Sprintf("Could not get user ID")
|
||||
}
|
||||
|
||||
// ErrCodeCouldNotGetUserID holds the unique world-error code of this error
|
||||
const ErrCodeCouldNotGetUserID = 1006
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrCouldNotGetUserID) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeCouldNotGetUserID, Message: "Could not get user id."}
|
||||
}
|
||||
|
||||
// ErrNoPasswordResetToken represents an error where no password reset token exists for that user
|
||||
type ErrNoPasswordResetToken struct {
|
||||
UserID int64
|
||||
}
|
||||
|
||||
func (err ErrNoPasswordResetToken) Error() string {
|
||||
return fmt.Sprintf("No token to reset a password [UserID: %d]", err.UserID)
|
||||
}
|
||||
|
||||
// ErrCodeNoPasswordResetToken holds the unique world-error code of this error
|
||||
const ErrCodeNoPasswordResetToken = 1008
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrNoPasswordResetToken) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeNoPasswordResetToken, Message: "No token to reset a user's password provided."}
|
||||
}
|
||||
|
||||
// ErrInvalidPasswordResetToken is an error where the password reset token is invalid
|
||||
type ErrInvalidPasswordResetToken struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
func (err ErrInvalidPasswordResetToken) Error() string {
|
||||
return fmt.Sprintf("Invalid token to reset a password [Token: %s]", err.Token)
|
||||
}
|
||||
|
||||
// ErrCodeInvalidPasswordResetToken holds the unique world-error code of this error
|
||||
const ErrCodeInvalidPasswordResetToken = 1009
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrInvalidPasswordResetToken) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeInvalidPasswordResetToken, Message: "Invalid token to reset a user's password."}
|
||||
}
|
||||
|
||||
// IsErrInvalidPasswordResetToken checks if an error is a ErrInvalidPasswordResetToken.
|
||||
func IsErrInvalidPasswordResetToken(err error) bool {
|
||||
_, ok := err.(ErrInvalidPasswordResetToken)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrInvalidEmailConfirmToken is an error where the email confirm token is invalid
|
||||
type ErrInvalidEmailConfirmToken struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
func (err ErrInvalidEmailConfirmToken) Error() string {
|
||||
return fmt.Sprintf("Invalid email confirm token [Token: %s]", err.Token)
|
||||
}
|
||||
|
||||
// ErrCodeInvalidEmailConfirmToken holds the unique world-error code of this error
|
||||
const ErrCodeInvalidEmailConfirmToken = 1010
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrInvalidEmailConfirmToken) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeInvalidEmailConfirmToken, Message: "Invalid email confirm token."}
|
||||
}
|
||||
|
||||
// IsErrInvalidEmailConfirmToken checks if an error is a ErrInvalidEmailConfirmToken.
|
||||
func IsErrInvalidEmailConfirmToken(err error) bool {
|
||||
_, ok := err.(ErrInvalidEmailConfirmToken)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrWrongUsernameOrPassword is an error where the email was not confirmed
|
||||
type ErrWrongUsernameOrPassword struct {
|
||||
}
|
||||
|
||||
func (err ErrWrongUsernameOrPassword) Error() string {
|
||||
return fmt.Sprintf("Wrong username or password")
|
||||
}
|
||||
|
||||
// ErrCodeWrongUsernameOrPassword holds the unique world-error code of this error
|
||||
const ErrCodeWrongUsernameOrPassword = 1011
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrWrongUsernameOrPassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeWrongUsernameOrPassword, Message: "Wrong username or password."}
|
||||
}
|
||||
|
||||
// IsErrWrongUsernameOrPassword checks if an error is a IsErrEmailNotConfirmed.
|
||||
func IsErrWrongUsernameOrPassword(err error) bool {
|
||||
_, ok := err.(ErrWrongUsernameOrPassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrEmailNotConfirmed is an error where the email was not confirmed
|
||||
type ErrEmailNotConfirmed struct {
|
||||
UserID int64
|
||||
}
|
||||
|
||||
func (err ErrEmailNotConfirmed) Error() string {
|
||||
return fmt.Sprintf("Email is not confirmed [UserID: %d]", err.UserID)
|
||||
}
|
||||
|
||||
// ErrCodeEmailNotConfirmed holds the unique world-error code of this error
|
||||
const ErrCodeEmailNotConfirmed = 1012
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrEmailNotConfirmed) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeEmailNotConfirmed, Message: "Please confirm your email address."}
|
||||
}
|
||||
|
||||
// IsErrEmailNotConfirmed checks if an error is a IsErrEmailNotConfirmed.
|
||||
func IsErrEmailNotConfirmed(err error) bool {
|
||||
_, ok := err.(ErrEmailNotConfirmed)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrEmptyNewPassword represents a "EmptyNewPassword" kind of error.
|
||||
type ErrEmptyNewPassword struct{}
|
||||
|
||||
// IsErrEmptyNewPassword checks if an error is a ErrEmptyNewPassword.
|
||||
func IsErrEmptyNewPassword(err error) bool {
|
||||
_, ok := err.(ErrEmptyNewPassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrEmptyNewPassword) Error() string {
|
||||
return fmt.Sprintf("New password is empty")
|
||||
}
|
||||
|
||||
// ErrCodeEmptyNewPassword holds the unique world-error code of this error
|
||||
const ErrCodeEmptyNewPassword = 1013
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrEmptyNewPassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeEmptyNewPassword, Message: "Please specify new password."}
|
||||
}
|
||||
|
||||
// ErrEmptyOldPassword represents a "EmptyOldPassword" kind of error.
|
||||
type ErrEmptyOldPassword struct{}
|
||||
|
||||
// IsErrEmptyOldPassword checks if an error is a ErrEmptyOldPassword.
|
||||
func IsErrEmptyOldPassword(err error) bool {
|
||||
_, ok := err.(ErrEmptyOldPassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrEmptyOldPassword) Error() string {
|
||||
return fmt.Sprintf("Old password is empty")
|
||||
}
|
||||
|
||||
// ErrCodeEmptyOldPassword holds the unique world-error code of this error
|
||||
const ErrCodeEmptyOldPassword = 1014
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrEmptyOldPassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeEmptyOldPassword, Message: "Please specify old password."}
|
||||
}
|
|
@ -1,20 +1,21 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2020 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// 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.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
package user
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
|
@ -76,7 +77,7 @@ func (User) TableName() string {
|
|||
return "users"
|
||||
}
|
||||
|
||||
func getUserWithError(a web.Auth) (*User, error) {
|
||||
func GetFromAuth(a web.Auth) (*User, error) {
|
||||
u, is := a.(*User)
|
||||
if !is {
|
||||
return &User{}, fmt.Errorf("user is not user element, is %s", reflect.TypeOf(a))
|
||||
|
@ -273,13 +274,6 @@ func CreateUser(user *User) (newUser *User, err error) {
|
|||
return &User{}, err
|
||||
}
|
||||
|
||||
// Create the user's namespace
|
||||
newN := &Namespace{Name: newUserOut.Username, Description: newUserOut.Username + "'s namespace.", Owner: newUserOut}
|
||||
err = newN.Create(newUserOut)
|
||||
if err != nil {
|
||||
return &User{}, err
|
||||
}
|
||||
|
||||
// Dont send a mail if we're testing
|
||||
if !config.MailerEnabled.GetBool() {
|
||||
return newUserOut, err
|
||||
|
@ -361,23 +355,3 @@ func UpdateUserPassword(user *User, newPassword string) (err error) {
|
|||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteUserByID deletes a user by its ID
|
||||
func DeleteUserByID(id int64, doer *User) error {
|
||||
// Check if the id is 0
|
||||
if id == 0 {
|
||||
return ErrIDCannotBeZero{}
|
||||
}
|
||||
|
||||
// Delete the user
|
||||
_, err := x.Id(id).Delete(&User{})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update the metrics
|
||||
metrics.UpdateCount(-1, metrics.ActiveUsersKey)
|
||||
|
||||
return err
|
||||
}
|
|
@ -1,20 +1,21 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2020 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// 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.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
package user
|
||||
|
||||
// EmailConfirm holds the token to confirm a mail address
|
||||
type EmailConfirm struct {
|
|
@ -1,22 +1,25 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2020 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// 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.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
package user
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUserEmailConfirm(t *testing.T) {
|
||||
type args struct {
|
|
@ -1,20 +1,21 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2020 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// 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.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
package user
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
|
@ -1,20 +1,21 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2020 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// 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.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
package user
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/utils"
|
||||
|
@ -132,15 +133,6 @@ func TestCreateUser(t *testing.T) {
|
|||
err = UpdateUserPassword(&User{ID: 9999}, newpassword)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrUserDoesNotExist(err))
|
||||
|
||||
// Delete it
|
||||
err = DeleteUserByID(theuser.ID, doer)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Try deleting one with ID = 0
|
||||
err = DeleteUserByID(0, doer)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrIDCannotBeZero(err))
|
||||
}
|
||||
|
||||
func TestUserPasswordReset(t *testing.T) {
|
|
@ -0,0 +1,36 @@
|
|||
// 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 user
|
||||
|
||||
// ListUsers returns a list with all users, filtered by an optional searchstring
|
||||
func ListUsers(searchterm string) (users []User, err error) {
|
||||
|
||||
if searchterm == "" {
|
||||
err = x.Find(&users)
|
||||
} else {
|
||||
err = x.
|
||||
Where("username LIKE ?", "%"+searchterm+"%").
|
||||
Find(&users)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return []User{}, err
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
Loading…
Reference in New Issue