GetUser now returns a pointer (#93)
This commit is contained in:
parent
8fbe721453
commit
be14634e1e
25 changed files with 172 additions and 131 deletions
|
@ -183,7 +183,7 @@ Sorry for some of them being in German, I'll tranlate them at some point.
|
||||||
* [x] Refactor config handling: Custom type "key" or so which holds the viper const and then mixins on that type to get the values from viper
|
* [x] Refactor config handling: Custom type "key" or so which holds the viper const and then mixins on that type to get the values from viper
|
||||||
* [x] Less files, but with some kind of logic
|
* [x] Less files, but with some kind of logic
|
||||||
* [x] Have extra functions for logging to call so it is possible to call `log.Info` instead of `log.Log.Info`
|
* [x] Have extra functions for logging to call so it is possible to call `log.Info` instead of `log.Log.Info`
|
||||||
* [ ] `GetUserByID` and the likes should return pointers
|
* [x] `GetUserByID` and the likes should return pointers
|
||||||
* [ ] `ListTask` should be just `Task`
|
* [ ] `ListTask` should be just `Task`
|
||||||
|
|
||||||
### Linters
|
### Linters
|
||||||
|
|
|
@ -173,7 +173,7 @@ func (l *Label) ReadOne() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
l.CreatedBy = &user
|
l.CreatedBy = user
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,11 @@ func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, err
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Obfuscate all user emails
|
||||||
|
for _, u := range users {
|
||||||
|
u.Email = ""
|
||||||
|
}
|
||||||
|
|
||||||
// Put it all together
|
// Put it all together
|
||||||
for in, l := range labels {
|
for in, l := range labels {
|
||||||
labels[in].CreatedBy = users[l.CreatedByID]
|
labels[in].CreatedBy = users[l.CreatedByID]
|
||||||
|
|
|
@ -33,7 +33,7 @@ type List struct {
|
||||||
NamespaceID int64 `xorm:"int(11) INDEX not null" json:"-" param:"namespace"`
|
NamespaceID int64 `xorm:"int(11) INDEX not null" json:"-" param:"namespace"`
|
||||||
|
|
||||||
// The user who created this list.
|
// The user who created this list.
|
||||||
Owner User `xorm:"-" json:"owner" valid:"-"`
|
Owner *User `xorm:"-" json:"owner" valid:"-"`
|
||||||
// An array of tasks which belong to the list.
|
// An array of tasks which belong to the list.
|
||||||
Tasks []*ListTask `xorm:"-" json:"tasks"`
|
Tasks []*ListTask `xorm:"-" json:"tasks"`
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ func AddListDetails(lists []*List) (err error) {
|
||||||
// Owner
|
// Owner
|
||||||
for _, owner := range owners {
|
for _, owner := range owners {
|
||||||
if list.OwnerID == owner.ID {
|
if list.OwnerID == owner.ID {
|
||||||
lists[in].Owner = *owner
|
lists[in].Owner = owner
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -326,7 +326,7 @@ func (l *List) Create(a web.Auth) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
l.OwnerID = doer.ID
|
l.OwnerID = doer.ID
|
||||||
l.Owner = *doer
|
l.Owner = doer
|
||||||
l.ID = 0 // Otherwise only the first time a new list would be created
|
l.ID = 0 // Otherwise only the first time a new list would be created
|
||||||
|
|
||||||
return CreateOrUpdateList(l)
|
return CreateOrUpdateList(l)
|
||||||
|
|
|
@ -37,16 +37,16 @@ func TestList_Create(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user can create
|
// Check if the user can create
|
||||||
allowed, _ := dummylist.CanCreate(&doer)
|
allowed, _ := dummylist.CanCreate(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
|
|
||||||
// Create it
|
// Create it
|
||||||
err = dummylist.Create(&doer)
|
err = dummylist.Create(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Get the list
|
// Get the list
|
||||||
newdummy := List{ID: dummylist.ID}
|
newdummy := List{ID: dummylist.ID}
|
||||||
canRead, err := newdummy.CanRead(&doer)
|
canRead, err := newdummy.CanRead(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, canRead)
|
assert.True(t, canRead)
|
||||||
err = newdummy.ReadOne()
|
err = newdummy.ReadOne()
|
||||||
|
@ -56,18 +56,18 @@ func TestList_Create(t *testing.T) {
|
||||||
assert.Equal(t, dummylist.OwnerID, doer.ID)
|
assert.Equal(t, dummylist.OwnerID, doer.ID)
|
||||||
|
|
||||||
// Check if the user can see it
|
// Check if the user can see it
|
||||||
allowed, _ = dummylist.CanRead(&doer)
|
allowed, _ = dummylist.CanRead(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
|
|
||||||
// Try updating a list
|
// Try updating a list
|
||||||
allowed, _ = dummylist.CanUpdate(&doer)
|
allowed, _ = dummylist.CanUpdate(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
dummylist.Description = "Lorem Ipsum dolor sit amet."
|
dummylist.Description = "Lorem Ipsum dolor sit amet."
|
||||||
err = dummylist.Update()
|
err = dummylist.Update()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Delete it
|
// Delete it
|
||||||
allowed, _ = dummylist.CanDelete(&doer)
|
allowed, _ = dummylist.CanDelete(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
|
|
||||||
err = dummylist.Delete()
|
err = dummylist.Delete()
|
||||||
|
@ -85,7 +85,7 @@ func TestList_Create(t *testing.T) {
|
||||||
NamespaceID: 876694,
|
NamespaceID: 876694,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = list3.Create(&doer)
|
err = list3.Create(doer)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ func TestList_ReadAll(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
lists2 := List{}
|
lists2 := List{}
|
||||||
lists3, err := lists2.ReadAll("", &u, 1)
|
lists3, err := lists2.ReadAll("", u, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(lists3).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(lists3).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(lists3)
|
s := reflect.ValueOf(lists3)
|
||||||
|
|
|
@ -193,7 +193,7 @@ func (t *ListTask) addNewAssigneeByID(newAssigneeID int64, list *List) (err erro
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
canRead, err := list.CanRead(&newAssignee)
|
canRead, err := list.CanRead(newAssignee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,20 +16,20 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func sortTasksForTesting(by SortBy) (tasks []*ListTask) {
|
func sortTasksForTesting(by SortBy) (tasks []*ListTask) {
|
||||||
user1 := User{
|
user1 := &User{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Username: "user1",
|
Username: "user1",
|
||||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
IsActive: true,
|
IsActive: true,
|
||||||
AvatarURL: "111d68d06e2d317b5a59c2c6c5bad808", // hash for ""
|
AvatarURL: "111d68d06e2d317b5a59c2c6c5bad808", // hash for ""
|
||||||
}
|
}
|
||||||
user2 := User{
|
user2 := &User{
|
||||||
ID: 2,
|
ID: 2,
|
||||||
Username: "user2",
|
Username: "user2",
|
||||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
AvatarURL: "ab53a2911ddf9b4817ac01ddcd3d975f", // hash for ""
|
AvatarURL: "ab53a2911ddf9b4817ac01ddcd3d975f", // hash for ""
|
||||||
}
|
}
|
||||||
user6 := User{
|
user6 := &User{
|
||||||
ID: 6,
|
ID: 6,
|
||||||
Username: "user6",
|
Username: "user6",
|
||||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
@ -50,7 +50,7 @@ func sortTasksForTesting(by SortBy) (tasks []*ListTask) {
|
||||||
ID: 4,
|
ID: 4,
|
||||||
Title: "Label #4 - visible via other task",
|
Title: "Label #4 - visible via other task",
|
||||||
CreatedByID: 2,
|
CreatedByID: 2,
|
||||||
CreatedBy: &user2,
|
CreatedBy: user2,
|
||||||
Updated: 0,
|
Updated: 0,
|
||||||
Created: 0,
|
Created: 0,
|
||||||
},
|
},
|
||||||
|
@ -301,8 +301,8 @@ func sortTasksForTesting(by SortBy) (tasks []*ListTask) {
|
||||||
CreatedBy: user1,
|
CreatedBy: user1,
|
||||||
ListID: 1,
|
ListID: 1,
|
||||||
Assignees: []*User{
|
Assignees: []*User{
|
||||||
&user1,
|
user1,
|
||||||
&user2,
|
user2,
|
||||||
},
|
},
|
||||||
Created: 1543626724,
|
Created: 1543626724,
|
||||||
Updated: 1543626724,
|
Updated: 1543626724,
|
||||||
|
@ -345,7 +345,7 @@ func TestListTask_ReadAll(t *testing.T) {
|
||||||
assert.NoError(t, LoadFixtures())
|
assert.NoError(t, LoadFixtures())
|
||||||
|
|
||||||
// Dummy users
|
// Dummy users
|
||||||
user1 := User{
|
user1 := &User{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Username: "user1",
|
Username: "user1",
|
||||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
@ -371,7 +371,7 @@ func TestListTask_ReadAll(t *testing.T) {
|
||||||
Subtasks []*ListTask
|
Subtasks []*ListTask
|
||||||
Created int64
|
Created int64
|
||||||
Updated int64
|
Updated int64
|
||||||
CreatedBy User
|
CreatedBy *User
|
||||||
CRUDable web.CRUDable
|
CRUDable web.CRUDable
|
||||||
Rights web.Rights
|
Rights web.Rights
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ type ListTask struct {
|
||||||
Updated int64 `xorm:"updated not null" json:"updated"`
|
Updated int64 `xorm:"updated not null" json:"updated"`
|
||||||
|
|
||||||
// The user who initially created the task.
|
// The user who initially created the task.
|
||||||
CreatedBy User `xorm:"-" json:"createdBy" valid:"-"`
|
CreatedBy *User `xorm:"-" json:"createdBy" valid:"-"`
|
||||||
|
|
||||||
web.CRUDable `xorm:"-" json:"-"`
|
web.CRUDable `xorm:"-" json:"-"`
|
||||||
web.Rights `xorm:"-" json:"-"`
|
web.Rights `xorm:"-" json:"-"`
|
||||||
|
@ -372,6 +372,7 @@ func addMoreInfoToTasks(taskMap map[int64]*ListTask) (tasks []*ListTask, err err
|
||||||
// Put the assignees in the task map
|
// Put the assignees in the task map
|
||||||
for _, a := range taskAssignees {
|
for _, a := range taskAssignees {
|
||||||
if a != nil {
|
if a != nil {
|
||||||
|
a.Email = "" // Obfuscate the email
|
||||||
taskMap[a.TaskID].Assignees = append(taskMap[a.TaskID].Assignees, &a.User)
|
taskMap[a.TaskID].Assignees = append(taskMap[a.TaskID].Assignees, &a.User)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -395,6 +396,11 @@ func addMoreInfoToTasks(taskMap map[int64]*ListTask) (tasks []*ListTask, err err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Obfuscate all user emails
|
||||||
|
for _, u := range users {
|
||||||
|
u.Email = ""
|
||||||
|
}
|
||||||
|
|
||||||
// Get all reminders and put them in a map to have it easier later
|
// Get all reminders and put them in a map to have it easier later
|
||||||
reminders := []*TaskReminder{}
|
reminders := []*TaskReminder{}
|
||||||
err = x.Table("task_reminders").In("task_id", taskIDs).Find(&reminders)
|
err = x.Table("task_reminders").In("task_id", taskIDs).Find(&reminders)
|
||||||
|
@ -411,7 +417,7 @@ func addMoreInfoToTasks(taskMap map[int64]*ListTask) (tasks []*ListTask, err err
|
||||||
for _, task := range taskMap {
|
for _, task := range taskMap {
|
||||||
|
|
||||||
// Make created by user objects
|
// Make created by user objects
|
||||||
taskMap[task.ID].CreatedBy = *users[task.CreatedByID]
|
taskMap[task.ID].CreatedBy = users[task.CreatedByID]
|
||||||
|
|
||||||
// Add the reminders
|
// Add the reminders
|
||||||
taskMap[task.ID].RemindersUnix = taskRemindersUnix[task.ID]
|
taskMap[task.ID].RemindersUnix = taskRemindersUnix[task.ID]
|
||||||
|
|
|
@ -35,15 +35,15 @@ func TestListTask_Create(t *testing.T) {
|
||||||
doer, err := GetUserByID(1)
|
doer, err := GetUserByID(1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
allowed, _ := listtask.CanCreate(&doer)
|
allowed, _ := listtask.CanCreate(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
|
|
||||||
err = listtask.Create(&doer)
|
err = listtask.Create(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Update it
|
// Update it
|
||||||
listtask.Text = "Test34"
|
listtask.Text = "Test34"
|
||||||
allowed, _ = listtask.CanUpdate(&doer)
|
allowed, _ = listtask.CanUpdate(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = listtask.Update()
|
err = listtask.Update()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -54,7 +54,7 @@ func TestListTask_Create(t *testing.T) {
|
||||||
assert.Equal(t, li.Text, "Test34")
|
assert.Equal(t, li.Text, "Test34")
|
||||||
|
|
||||||
// Delete the task
|
// Delete the task
|
||||||
allowed, _ = listtask.CanDelete(&doer)
|
allowed, _ = listtask.CanDelete(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = listtask.Delete()
|
err = listtask.Delete()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -67,14 +67,14 @@ func TestListTask_Create(t *testing.T) {
|
||||||
|
|
||||||
// Try adding a list task with an empty text
|
// Try adding a list task with an empty text
|
||||||
listtask.Text = ""
|
listtask.Text = ""
|
||||||
err = listtask.Create(&doer)
|
err = listtask.Create(doer)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrListTaskCannotBeEmpty(err))
|
assert.True(t, IsErrListTaskCannotBeEmpty(err))
|
||||||
|
|
||||||
// Try adding one to a nonexistant list
|
// Try adding one to a nonexistant list
|
||||||
listtask.ListID = 99993939
|
listtask.ListID = 99993939
|
||||||
listtask.Text = "Lorem Ipsum"
|
listtask.Text = "Lorem Ipsum"
|
||||||
err = listtask.Create(&doer)
|
err = listtask.Create(doer)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrListDoesNotExist(err))
|
assert.True(t, IsErrListDoesNotExist(err))
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,11 @@ func (lu *ListUser) ReadAll(search string, a web.Auth, page int) (interface{}, e
|
||||||
Where("users.username LIKE ?", "%"+search+"%").
|
Where("users.username LIKE ?", "%"+search+"%").
|
||||||
Find(&all)
|
Find(&all)
|
||||||
|
|
||||||
|
// Obfuscate all user emails
|
||||||
|
for _, u := range all {
|
||||||
|
u.Email = ""
|
||||||
|
}
|
||||||
|
|
||||||
return all, err
|
return all, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ type Namespace struct {
|
||||||
OwnerID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
OwnerID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
||||||
|
|
||||||
// The user who owns this namespace
|
// The user who owns this namespace
|
||||||
Owner User `xorm:"-" json:"owner" valid:"-"`
|
Owner *User `xorm:"-" json:"owner" valid:"-"`
|
||||||
|
|
||||||
// A unix timestamp when this namespace was created. You cannot change this value.
|
// A unix timestamp when this namespace was created. You cannot change this value.
|
||||||
Created int64 `xorm:"created not null" json:"created"`
|
Created int64 `xorm:"created not null" json:"created"`
|
||||||
|
@ -148,7 +148,7 @@ func (n *Namespace) ReadAll(search string, a web.Auth, page int) (interface{}, e
|
||||||
// Create our pseudo-namespace to hold the shared lists
|
// Create our pseudo-namespace to hold the shared lists
|
||||||
// We want this one at the beginning, which is why we create it here
|
// We want this one at the beginning, which is why we create it here
|
||||||
pseudonamespace := PseudoNamespace
|
pseudonamespace := PseudoNamespace
|
||||||
pseudonamespace.Owner = *doer
|
pseudonamespace.Owner = doer
|
||||||
all = append(all, &NamespaceWithLists{
|
all = append(all, &NamespaceWithLists{
|
||||||
pseudonamespace,
|
pseudonamespace,
|
||||||
[]*List{},
|
[]*List{},
|
||||||
|
@ -238,7 +238,7 @@ func (n *Namespace) ReadAll(search string, a web.Auth, page int) (interface{}, e
|
||||||
// Users
|
// Users
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
if n.OwnerID == u.ID {
|
if n.OwnerID == u.ID {
|
||||||
all[i].Owner = *u
|
all[i].Owner = u
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,13 @@ func TestNamespace_Create(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Try creating it
|
// Try creating it
|
||||||
allowed, _ := dummynamespace.CanCreate(&doer)
|
allowed, _ := dummynamespace.CanCreate(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = dummynamespace.Create(&doer)
|
err = dummynamespace.Create(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// check if it really exists
|
// check if it really exists
|
||||||
allowed, err = dummynamespace.CanRead(&doer)
|
allowed, err = dummynamespace.CanRead(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = dummynamespace.ReadOne()
|
err = dummynamespace.ReadOne()
|
||||||
|
@ -52,7 +52,7 @@ func TestNamespace_Create(t *testing.T) {
|
||||||
|
|
||||||
// Try creating one without a name
|
// Try creating one without a name
|
||||||
n2 := Namespace{}
|
n2 := Namespace{}
|
||||||
err = n2.Create(&doer)
|
err = n2.Create(doer)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNamespaceNameCannotBeEmpty(err))
|
assert.True(t, IsErrNamespaceNameCannotBeEmpty(err))
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func TestNamespace_Create(t *testing.T) {
|
||||||
assert.True(t, IsErrUserDoesNotExist(err))
|
assert.True(t, IsErrUserDoesNotExist(err))
|
||||||
|
|
||||||
// Update it
|
// Update it
|
||||||
allowed, err = dummynamespace.CanUpdate(&doer)
|
allowed, err = dummynamespace.CanUpdate(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
dummynamespace.Description = "Dolor sit amet."
|
dummynamespace.Description = "Dolor sit amet."
|
||||||
|
@ -74,7 +74,7 @@ func TestNamespace_Create(t *testing.T) {
|
||||||
// Check if it was updated
|
// Check if it was updated
|
||||||
assert.Equal(t, "Dolor sit amet.", dummynamespace.Description)
|
assert.Equal(t, "Dolor sit amet.", dummynamespace.Description)
|
||||||
// Get it and check it again
|
// Get it and check it again
|
||||||
allowed, err = dummynamespace.CanRead(&doer)
|
allowed, err = dummynamespace.CanRead(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = dummynamespace.ReadOne()
|
err = dummynamespace.ReadOne()
|
||||||
|
@ -100,7 +100,7 @@ func TestNamespace_Create(t *testing.T) {
|
||||||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||||
|
|
||||||
// Delete it
|
// Delete it
|
||||||
allowed, err = dummynamespace.CanDelete(&doer)
|
allowed, err = dummynamespace.CanDelete(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = dummynamespace.Delete()
|
err = dummynamespace.Delete()
|
||||||
|
@ -112,13 +112,13 @@ func TestNamespace_Create(t *testing.T) {
|
||||||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||||
|
|
||||||
// Check if it was successfully deleted
|
// Check if it was successfully deleted
|
||||||
allowed, err = dummynamespace.CanRead(&doer)
|
allowed, err = dummynamespace.CanRead(doer)
|
||||||
assert.False(t, allowed)
|
assert.False(t, allowed)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||||
|
|
||||||
// Get all namespaces of a user
|
// Get all namespaces of a user
|
||||||
nsps, err := n.ReadAll("", &doer, 1)
|
nsps, err := n.ReadAll("", doer, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(nsps).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(nsps).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(nsps)
|
s := reflect.ValueOf(nsps)
|
||||||
|
|
|
@ -172,6 +172,11 @@ func (nu *NamespaceUser) ReadAll(search string, a web.Auth, page int) (interface
|
||||||
Where("users.username LIKE ?", "%"+search+"%").
|
Where("users.username LIKE ?", "%"+search+"%").
|
||||||
Find(&all)
|
Find(&all)
|
||||||
|
|
||||||
|
// Obfuscate all user emails
|
||||||
|
for _, u := range all {
|
||||||
|
u.Email = ""
|
||||||
|
}
|
||||||
|
|
||||||
return all, err
|
return all, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,64 +37,64 @@ func TestTeamList(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Check normal creation
|
// Check normal creation
|
||||||
allowed, _ := tl.CanCreate(&u)
|
allowed, _ := tl.CanCreate(u)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = tl.Create(&u)
|
err = tl.Create(u)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Check again
|
// Check again
|
||||||
err = tl.Create(&u)
|
err = tl.Create(u)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrTeamAlreadyHasAccess(err))
|
assert.True(t, IsErrTeamAlreadyHasAccess(err))
|
||||||
|
|
||||||
// Check with wrong rights
|
// Check with wrong rights
|
||||||
tl2 := tl
|
tl2 := tl
|
||||||
tl2.Right = RightUnknown
|
tl2.Right = RightUnknown
|
||||||
err = tl2.Create(&u)
|
err = tl2.Create(u)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrInvalidRight(err))
|
assert.True(t, IsErrInvalidRight(err))
|
||||||
|
|
||||||
// Check with inexistant team
|
// Check with inexistant team
|
||||||
tl3 := tl
|
tl3 := tl
|
||||||
tl3.TeamID = 3253
|
tl3.TeamID = 3253
|
||||||
err = tl3.Create(&u)
|
err = tl3.Create(u)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrTeamDoesNotExist(err))
|
assert.True(t, IsErrTeamDoesNotExist(err))
|
||||||
|
|
||||||
// Check with inexistant list
|
// Check with inexistant list
|
||||||
tl4 := tl
|
tl4 := tl
|
||||||
tl4.ListID = 3252
|
tl4.ListID = 3252
|
||||||
err = tl4.Create(&u)
|
err = tl4.Create(u)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrListDoesNotExist(err))
|
assert.True(t, IsErrListDoesNotExist(err))
|
||||||
|
|
||||||
// Test Read all
|
// Test Read all
|
||||||
teams, err := tl.ReadAll("", &u, 1)
|
teams, err := tl.ReadAll("", u, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(teams).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(teams).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(teams)
|
s := reflect.ValueOf(teams)
|
||||||
assert.Equal(t, s.Len(), 1)
|
assert.Equal(t, s.Len(), 1)
|
||||||
|
|
||||||
// Test Read all for nonexistant list
|
// Test Read all for nonexistant list
|
||||||
_, err = tl4.ReadAll("", &u, 1)
|
_, err = tl4.ReadAll("", u, 1)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrListDoesNotExist(err))
|
assert.True(t, IsErrListDoesNotExist(err))
|
||||||
|
|
||||||
// Test Read all for a list where the user is owner of the namespace this list belongs to
|
// Test Read all for a list where the user is owner of the namespace this list belongs to
|
||||||
tl5 := tl
|
tl5 := tl
|
||||||
tl5.ListID = 2
|
tl5.ListID = 2
|
||||||
_, err = tl5.ReadAll("", &u, 1)
|
_, err = tl5.ReadAll("", u, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Test read all for a list where the user not has access
|
// Test read all for a list where the user not has access
|
||||||
tl6 := tl
|
tl6 := tl
|
||||||
tl6.ListID = 5
|
tl6.ListID = 5
|
||||||
_, err = tl6.ReadAll("", &u, 1)
|
_, err = tl6.ReadAll("", u, 1)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNeedToHaveListReadAccess(err))
|
assert.True(t, IsErrNeedToHaveListReadAccess(err))
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
allowed, _ = tl.CanDelete(&u)
|
allowed, _ = tl.CanDelete(u)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = tl.Delete()
|
err = tl.Delete()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
|
@ -34,9 +34,9 @@ func TestTeamMember_Create(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Insert a new team member
|
// Insert a new team member
|
||||||
allowed, _ := dummyteammember.CanCreate(&doer)
|
allowed, _ := dummyteammember.CanCreate(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = dummyteammember.Create(&doer)
|
err = dummyteammember.Create(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Check he's in there
|
// Check he's in there
|
||||||
|
@ -46,12 +46,12 @@ func TestTeamMember_Create(t *testing.T) {
|
||||||
assert.Equal(t, 3, len(team.Members))
|
assert.Equal(t, 3, len(team.Members))
|
||||||
|
|
||||||
// Try inserting a user twice
|
// Try inserting a user twice
|
||||||
err = dummyteammember.Create(&doer)
|
err = dummyteammember.Create(doer)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrUserIsMemberOfTeam(err))
|
assert.True(t, IsErrUserIsMemberOfTeam(err))
|
||||||
|
|
||||||
// Delete it
|
// Delete it
|
||||||
allowed, _ = dummyteammember.CanDelete(&doer)
|
allowed, _ = dummyteammember.CanDelete(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = dummyteammember.Delete()
|
err = dummyteammember.Delete()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -69,13 +69,13 @@ func TestTeamMember_Create(t *testing.T) {
|
||||||
|
|
||||||
// Try inserting a user which does not exist
|
// Try inserting a user which does not exist
|
||||||
dummyteammember.Username = "user9484"
|
dummyteammember.Username = "user9484"
|
||||||
err = dummyteammember.Create(&doer)
|
err = dummyteammember.Create(doer)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrUserDoesNotExist(err))
|
assert.True(t, IsErrUserDoesNotExist(err))
|
||||||
|
|
||||||
// Try adding a user to a team which does not exist
|
// Try adding a user to a team which does not exist
|
||||||
tm = TeamMember{TeamID: 94824, Username: "user1"}
|
tm = TeamMember{TeamID: 94824, Username: "user1"}
|
||||||
err = tm.Create(&doer)
|
err = tm.Create(doer)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrTeamDoesNotExist(err))
|
assert.True(t, IsErrTeamDoesNotExist(err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,46 +36,46 @@ func TestTeamNamespace(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Test normal creation
|
// Test normal creation
|
||||||
allowed, _ := tn.CanCreate(&dummyuser)
|
allowed, _ := tn.CanCreate(dummyuser)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = tn.Create(&dummyuser)
|
err = tn.Create(dummyuser)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Test again (should fail)
|
// Test again (should fail)
|
||||||
err = tn.Create(&dummyuser)
|
err = tn.Create(dummyuser)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrTeamAlreadyHasAccess(err))
|
assert.True(t, IsErrTeamAlreadyHasAccess(err))
|
||||||
|
|
||||||
// Test with invalid team right
|
// Test with invalid team right
|
||||||
tn2 := tn
|
tn2 := tn
|
||||||
tn2.Right = RightUnknown
|
tn2.Right = RightUnknown
|
||||||
err = tn2.Create(&dummyuser)
|
err = tn2.Create(dummyuser)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrInvalidRight(err))
|
assert.True(t, IsErrInvalidRight(err))
|
||||||
|
|
||||||
// Check with inexistant team
|
// Check with inexistant team
|
||||||
tn3 := tn
|
tn3 := tn
|
||||||
tn3.TeamID = 324
|
tn3.TeamID = 324
|
||||||
err = tn3.Create(&dummyuser)
|
err = tn3.Create(dummyuser)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrTeamDoesNotExist(err))
|
assert.True(t, IsErrTeamDoesNotExist(err))
|
||||||
|
|
||||||
// Check with a namespace which does not exist
|
// Check with a namespace which does not exist
|
||||||
tn4 := tn
|
tn4 := tn
|
||||||
tn4.NamespaceID = 423
|
tn4.NamespaceID = 423
|
||||||
err = tn4.Create(&dummyuser)
|
err = tn4.Create(dummyuser)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||||
|
|
||||||
// Check readall
|
// Check readall
|
||||||
teams, err := tn.ReadAll("", &dummyuser, 1)
|
teams, err := tn.ReadAll("", dummyuser, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(teams).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(teams).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(teams)
|
s := reflect.ValueOf(teams)
|
||||||
assert.Equal(t, s.Len(), 1)
|
assert.Equal(t, s.Len(), 1)
|
||||||
|
|
||||||
// Check readall for a nonexistant namespace
|
// Check readall for a nonexistant namespace
|
||||||
_, err = tn4.ReadAll("", &dummyuser, 1)
|
_, err = tn4.ReadAll("", dummyuser, 1)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
assert.True(t, IsErrNamespaceDoesNotExist(err))
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ func TestTeamNamespace(t *testing.T) {
|
||||||
assert.True(t, IsErrNeedToHaveNamespaceReadAccess(err))
|
assert.True(t, IsErrNeedToHaveNamespaceReadAccess(err))
|
||||||
|
|
||||||
// Delete it
|
// Delete it
|
||||||
allowed, _ = tn.CanDelete(&dummyuser)
|
allowed, _ = tn.CanDelete(dummyuser)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = tn.Delete()
|
err = tn.Delete()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
|
@ -32,7 +32,7 @@ type Team struct {
|
||||||
CreatedByID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
CreatedByID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
||||||
|
|
||||||
// The user who created this team.
|
// The user who created this team.
|
||||||
CreatedBy User `xorm:"-" json:"createdBy"`
|
CreatedBy *User `xorm:"-" json:"createdBy"`
|
||||||
// An array of all members in this team.
|
// An array of all members in this team.
|
||||||
Members []*TeamUser `xorm:"-" json:"members"`
|
Members []*TeamUser `xorm:"-" json:"members"`
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ func (t *Team) Create(a web.Auth) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.CreatedByID = doer.ID
|
t.CreatedByID = doer.ID
|
||||||
t.CreatedBy = *doer
|
t.CreatedBy = doer
|
||||||
|
|
||||||
_, err = x.Insert(t)
|
_, err = x.Insert(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -28,7 +28,7 @@ func TestTeam_CanDoSomething(t *testing.T) {
|
||||||
Name string
|
Name string
|
||||||
Description string
|
Description string
|
||||||
CreatedByID int64
|
CreatedByID int64
|
||||||
CreatedBy User
|
CreatedBy *User
|
||||||
Members []*TeamUser
|
Members []*TeamUser
|
||||||
Created int64
|
Created int64
|
||||||
Updated int64
|
Updated int64
|
||||||
|
|
|
@ -34,9 +34,9 @@ func TestTeam_Create(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Insert it
|
// Insert it
|
||||||
allowed, _ := dummyteam.CanCreate(&doer)
|
allowed, _ := dummyteam.CanCreate(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = dummyteam.Create(&doer)
|
err = dummyteam.Create(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Check if it was inserted and we're admin
|
// Check if it was inserted and we're admin
|
||||||
|
@ -46,7 +46,7 @@ func TestTeam_Create(t *testing.T) {
|
||||||
assert.Equal(t, 1, len(tm.Members))
|
assert.Equal(t, 1, len(tm.Members))
|
||||||
assert.Equal(t, doer.ID, tm.Members[0].User.ID)
|
assert.Equal(t, doer.ID, tm.Members[0].User.ID)
|
||||||
assert.True(t, tm.Members[0].Admin)
|
assert.True(t, tm.Members[0].Admin)
|
||||||
allowed, _ = dummyteam.CanRead(&doer)
|
allowed, _ = dummyteam.CanRead(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
|
|
||||||
// Try getting a team with an ID < 0
|
// Try getting a team with an ID < 0
|
||||||
|
@ -55,7 +55,7 @@ func TestTeam_Create(t *testing.T) {
|
||||||
assert.True(t, IsErrTeamDoesNotExist(err))
|
assert.True(t, IsErrTeamDoesNotExist(err))
|
||||||
|
|
||||||
// Get all teams the user is part of
|
// Get all teams the user is part of
|
||||||
ts, err := tm.ReadAll("", &doer, 1)
|
ts, err := tm.ReadAll("", doer, 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, reflect.TypeOf(ts).Kind(), reflect.Slice)
|
assert.Equal(t, reflect.TypeOf(ts).Kind(), reflect.Slice)
|
||||||
s := reflect.ValueOf(ts)
|
s := reflect.ValueOf(ts)
|
||||||
|
@ -63,12 +63,12 @@ func TestTeam_Create(t *testing.T) {
|
||||||
|
|
||||||
// Check inserting it with an empty name
|
// Check inserting it with an empty name
|
||||||
dummyteam.Name = ""
|
dummyteam.Name = ""
|
||||||
err = dummyteam.Create(&doer)
|
err = dummyteam.Create(doer)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrTeamNameCannotBeEmpty(err))
|
assert.True(t, IsErrTeamNameCannotBeEmpty(err))
|
||||||
|
|
||||||
// update it (still no name, should fail)
|
// update it (still no name, should fail)
|
||||||
allowed, _ = dummyteam.CanUpdate(&doer)
|
allowed, _ = dummyteam.CanUpdate(doer)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = dummyteam.Update()
|
err = dummyteam.Update()
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
@ -80,14 +80,14 @@ func TestTeam_Create(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Delete it
|
// Delete it
|
||||||
allowed, err = dummyteam.CanDelete(&doer)
|
allowed, err = dummyteam.CanDelete(doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, allowed)
|
assert.True(t, allowed)
|
||||||
err = dummyteam.Delete()
|
err = dummyteam.Delete()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Try deleting a (now) nonexistant team
|
// Try deleting a (now) nonexistant team
|
||||||
allowed, err = dummyteam.CanDelete(&doer)
|
allowed, err = dummyteam.CanDelete(doer)
|
||||||
assert.False(t, allowed)
|
assert.False(t, allowed)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrTeamDoesNotExist(err))
|
assert.True(t, IsErrTeamDoesNotExist(err))
|
||||||
|
|
|
@ -65,7 +65,6 @@ type User struct {
|
||||||
// AfterLoad is used to delete all emails to not have them leaked to the user
|
// AfterLoad is used to delete all emails to not have them leaked to the user
|
||||||
func (u *User) AfterLoad() {
|
func (u *User) AfterLoad() {
|
||||||
u.AvatarURL = utils.Md5String(u.Email)
|
u.AvatarURL = utils.Md5String(u.Email)
|
||||||
u.Email = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetID implements the Auth interface
|
// GetID implements the Auth interface
|
||||||
|
@ -99,8 +98,8 @@ type APIUserPassword struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIFormat formats an API User into a normal user struct
|
// APIFormat formats an API User into a normal user struct
|
||||||
func (apiUser *APIUserPassword) APIFormat() User {
|
func (apiUser *APIUserPassword) APIFormat() *User {
|
||||||
return User{
|
return &User{
|
||||||
ID: apiUser.ID,
|
ID: apiUser.ID,
|
||||||
Username: apiUser.Username,
|
Username: apiUser.Username,
|
||||||
Password: apiUser.Password,
|
Password: apiUser.Password,
|
||||||
|
@ -109,41 +108,56 @@ func (apiUser *APIUserPassword) APIFormat() User {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserByID gets informations about a user by its ID
|
// GetUserByID gets informations about a user by its ID
|
||||||
func GetUserByID(id int64) (user User, err error) {
|
func GetUserByID(id int64) (user *User, err error) {
|
||||||
// Apparently xorm does otherwise look for all users but return only one, which leads to returing one even if the ID is 0
|
// Apparently xorm does otherwise look for all users but return only one, which leads to returing one even if the ID is 0
|
||||||
if id < 1 {
|
if id < 1 {
|
||||||
return User{}, ErrUserDoesNotExist{}
|
return &User{}, ErrUserDoesNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetUser(User{ID: id})
|
return GetUser(&User{ID: id})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserByUsername gets a user from its user name. This is an extra function to be able to add an extra error check.
|
// GetUserByUsername gets a user from its user name. This is an extra function to be able to add an extra error check.
|
||||||
func GetUserByUsername(username string) (user User, err error) {
|
func GetUserByUsername(username string) (user *User, err error) {
|
||||||
if username == "" {
|
if username == "" {
|
||||||
return User{}, ErrUserDoesNotExist{}
|
return &User{}, ErrUserDoesNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetUser(User{Username: username})
|
return GetUser(&User{Username: username})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUser gets a user object
|
// GetUser gets a user object
|
||||||
func GetUser(user User) (userOut User, err error) {
|
func GetUser(user *User) (userOut *User, err error) {
|
||||||
userOut = user
|
return getUser(user, false)
|
||||||
exists, err := x.Get(&userOut)
|
}
|
||||||
|
|
||||||
|
// GetUserWithEmail returns a user object with email
|
||||||
|
func GetUserWithEmail(user *User) (userOut *User, err error) {
|
||||||
|
return getUser(user, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getUser is a small helper function to avoid having duplicated code for almost the same use case
|
||||||
|
func getUser(user *User, withEmail bool) (userOut *User, err error) {
|
||||||
|
userOut = &User{} // To prevent a panic if user is nil
|
||||||
|
*userOut = *user
|
||||||
|
exists, err := x.Get(userOut)
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
return User{}, ErrUserDoesNotExist{UserID: user.ID}
|
return &User{}, ErrUserDoesNotExist{UserID: user.ID}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !withEmail {
|
||||||
|
userOut.Email = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return userOut, err
|
return userOut, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckUserCredentials checks user credentials
|
// CheckUserCredentials checks user credentials
|
||||||
func CheckUserCredentials(u *UserLogin) (User, error) {
|
func CheckUserCredentials(u *UserLogin) (*User, error) {
|
||||||
// Check if we have any credentials
|
// Check if we have any credentials
|
||||||
if u.Password == "" || u.Username == "" {
|
if u.Password == "" || u.Username == "" {
|
||||||
return User{}, ErrNoUsernamePassword{}
|
return &User{}, ErrNoUsernamePassword{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user exists
|
// Check if the user exists
|
||||||
|
@ -151,21 +165,21 @@ func CheckUserCredentials(u *UserLogin) (User, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// hashing the password takes a long time, so we hash something to not make it clear if the username was wrong
|
// hashing the password takes a long time, so we hash something to not make it clear if the username was wrong
|
||||||
bcrypt.GenerateFromPassword([]byte(u.Username), 14)
|
bcrypt.GenerateFromPassword([]byte(u.Username), 14)
|
||||||
return User{}, ErrWrongUsernameOrPassword{}
|
return &User{}, ErrWrongUsernameOrPassword{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// User is invalid if it needs to verify its email address
|
// User is invalid if it needs to verify its email address
|
||||||
if !user.IsActive {
|
if !user.IsActive {
|
||||||
return User{}, ErrEmailNotConfirmed{UserID: user.ID}
|
return &User{}, ErrEmailNotConfirmed{UserID: user.ID}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the users password
|
// Check the users password
|
||||||
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(u.Password))
|
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(u.Password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||||
return User{}, ErrWrongUsernameOrPassword{}
|
return &User{}, ErrWrongUsernameOrPassword{}
|
||||||
}
|
}
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
|
@ -216,47 +230,47 @@ func UpdateActiveUsersFromContext(c echo.Context) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates a new user and inserts it into the database
|
// CreateUser creates a new user and inserts it into the database
|
||||||
func CreateUser(user User) (newUser User, err error) {
|
func CreateUser(user *User) (newUser *User, err error) {
|
||||||
|
|
||||||
newUser = user
|
newUser = user
|
||||||
|
|
||||||
// Check if we have all needed informations
|
// Check if we have all needed informations
|
||||||
if newUser.Password == "" || newUser.Username == "" || newUser.Email == "" {
|
if newUser.Password == "" || newUser.Username == "" || newUser.Email == "" {
|
||||||
return User{}, ErrNoUsernamePassword{}
|
return &User{}, ErrNoUsernamePassword{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user already existst with that username
|
// Check if the user already existst with that username
|
||||||
exists := true
|
exists := true
|
||||||
existingUser, err := GetUserByUsername(newUser.Username)
|
_, err = GetUserByUsername(newUser.Username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if IsErrUserDoesNotExist(err) {
|
if IsErrUserDoesNotExist(err) {
|
||||||
exists = false
|
exists = false
|
||||||
} else {
|
} else {
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if exists {
|
if exists {
|
||||||
return User{}, ErrUsernameExists{newUser.ID, newUser.Username}
|
return &User{}, ErrUsernameExists{newUser.ID, newUser.Username}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user already existst with that email
|
// Check if the user already existst with that email
|
||||||
exists = true
|
exists = true
|
||||||
existingUser, err = GetUser(User{Email: newUser.Email})
|
_, err = GetUser(&User{Email: newUser.Email})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if IsErrUserDoesNotExist(err) {
|
if IsErrUserDoesNotExist(err) {
|
||||||
exists = false
|
exists = false
|
||||||
} else {
|
} else {
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if exists {
|
if exists {
|
||||||
return User{}, ErrUserEmailExists{existingUser.ID, existingUser.Email}
|
return &User{}, ErrUserEmailExists{newUser.ID, newUser.Email}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash the password
|
// Hash the password
|
||||||
newUser.Password, err = hashPassword(user.Password)
|
newUser.Password, err = hashPassword(user.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
newUser.IsActive = true
|
newUser.IsActive = true
|
||||||
|
@ -270,7 +284,7 @@ func CreateUser(user User) (newUser User, err error) {
|
||||||
// Insert it
|
// Insert it
|
||||||
_, err = x.Insert(newUser)
|
_, err = x.Insert(newUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the metrics
|
// Update the metrics
|
||||||
|
@ -279,14 +293,14 @@ func CreateUser(user User) (newUser User, err error) {
|
||||||
// Get the full new User
|
// Get the full new User
|
||||||
newUserOut, err := GetUser(newUser)
|
newUserOut, err := GetUser(newUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the user's namespace
|
// Create the user's namespace
|
||||||
newN := &Namespace{Name: newUserOut.Username, Description: newUserOut.Username + "'s namespace.", Owner: newUserOut}
|
newN := &Namespace{Name: newUserOut.Username, Description: newUserOut.Username + "'s namespace.", Owner: newUserOut}
|
||||||
err = newN.Create(&newUserOut)
|
err = newN.Create(newUserOut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dont send a mail if we're testing
|
// Dont send a mail if we're testing
|
||||||
|
@ -311,12 +325,12 @@ func hashPassword(password string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUser updates a user
|
// UpdateUser updates a user
|
||||||
func UpdateUser(user User) (updatedUser User, err error) {
|
func UpdateUser(user *User) (updatedUser *User, err error) {
|
||||||
|
|
||||||
// Check if it exists
|
// Check if it exists
|
||||||
theUser, err := GetUserByID(user.ID)
|
theUser, err := GetUserByID(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have at least a username
|
// Check if we have at least a username
|
||||||
|
@ -330,13 +344,13 @@ func UpdateUser(user User) (updatedUser User, err error) {
|
||||||
// Update it
|
// Update it
|
||||||
_, err = x.Id(user.ID).Update(user)
|
_, err = x.Id(user.ID).Update(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the newly updated user
|
// Get the newly updated user
|
||||||
updatedUser, err = GetUserByID(user.ID)
|
updatedUser, err = GetUserByID(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return User{}, err
|
return &User{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return updatedUser, err
|
return updatedUser, err
|
||||||
|
|
|
@ -88,7 +88,7 @@ func RequestUserPasswordResetToken(tr *PasswordTokenRequest) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user exists
|
// Check if the user exists
|
||||||
user, err := GetUser(User{Email: tr.Email})
|
user, err := GetUserWithEmail(&User{Email: tr.Email})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ func RequestUserPasswordResetToken(tr *PasswordTokenRequest) (err error) {
|
||||||
user.PasswordResetToken = utils.MakeRandomString(400)
|
user.PasswordResetToken = utils.MakeRandomString(400)
|
||||||
|
|
||||||
// Save it
|
// Save it
|
||||||
_, err = x.Where("id = ?", user.ID).Update(&user)
|
_, err = x.Where("id = ?", user.ID).Update(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ func TestCreateUser(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Our dummy user for testing
|
// Our dummy user for testing
|
||||||
dummyuser := User{
|
dummyuser := &User{
|
||||||
Username: "testuu",
|
Username: "testuu",
|
||||||
Password: "1234",
|
Password: "1234",
|
||||||
Email: "noone@example.com",
|
Email: "noone@example.com",
|
||||||
|
@ -42,7 +42,7 @@ func TestCreateUser(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Create a second new user
|
// Create a second new user
|
||||||
_, err = CreateUser(User{Username: dummyuser.Username + "2", Email: dummyuser.Email + "m", Password: dummyuser.Password})
|
_, err = CreateUser(&User{Username: dummyuser.Username + "2", Email: dummyuser.Email + "m", Password: dummyuser.Password})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Check if it fails to create the same user again
|
// Check if it fails to create the same user again
|
||||||
|
@ -50,17 +50,17 @@ func TestCreateUser(t *testing.T) {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
// Check if it fails to create a user with just the same username
|
// Check if it fails to create a user with just the same username
|
||||||
_, err = CreateUser(User{Username: dummyuser.Username, Password: "12345", Email: "email@example.com"})
|
_, err = CreateUser(&User{Username: dummyuser.Username, Password: "12345", Email: "email@example.com"})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrUsernameExists(err))
|
assert.True(t, IsErrUsernameExists(err))
|
||||||
|
|
||||||
// Check if it fails to create one with the same email
|
// Check if it fails to create one with the same email
|
||||||
_, err = CreateUser(User{Username: "noone", Password: "1234", Email: dummyuser.Email})
|
_, err = CreateUser(&User{Username: "noone", Password: "1234", Email: dummyuser.Email})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrUserEmailExists(err))
|
assert.True(t, IsErrUserEmailExists(err))
|
||||||
|
|
||||||
// Check if it fails to create a user without password and username
|
// Check if it fails to create a user without password and username
|
||||||
_, err = CreateUser(User{})
|
_, err = CreateUser(&User{})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrNoUsernamePassword(err))
|
assert.True(t, IsErrNoUsernamePassword(err))
|
||||||
|
|
||||||
|
@ -78,14 +78,14 @@ func TestCreateUser(t *testing.T) {
|
||||||
assert.True(t, IsErrUserDoesNotExist(err))
|
assert.True(t, IsErrUserDoesNotExist(err))
|
||||||
|
|
||||||
// Check the user credentials with an unverified email
|
// Check the user credentials with an unverified email
|
||||||
user, err := CheckUserCredentials(&UserLogin{"user5", "1234"})
|
_, err = CheckUserCredentials(&UserLogin{"user5", "1234"})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrEmailNotConfirmed(err))
|
assert.True(t, IsErrEmailNotConfirmed(err))
|
||||||
|
|
||||||
// Update everything and check again
|
// Update everything and check again
|
||||||
_, err = x.Cols("is_active").Where("true").Update(User{IsActive: true})
|
_, err = x.Cols("is_active").Where("true").Update(User{IsActive: true})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
user, err = CheckUserCredentials(&UserLogin{"testuu", "1234"})
|
user, err := CheckUserCredentials(&UserLogin{"testuu", "1234"})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "testuu", user.Username)
|
assert.Equal(t, "testuu", user.Username)
|
||||||
|
|
||||||
|
@ -100,23 +100,23 @@ func TestCreateUser(t *testing.T) {
|
||||||
assert.True(t, IsErrWrongUsernameOrPassword(err))
|
assert.True(t, IsErrWrongUsernameOrPassword(err))
|
||||||
|
|
||||||
// Update the user
|
// Update the user
|
||||||
uuser, err := UpdateUser(User{ID: theuser.ID, Password: "444444"})
|
uuser, err := UpdateUser(&User{ID: theuser.ID, Password: "444444"})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, theuser.Password, uuser.Password) // Password should not change
|
assert.Equal(t, theuser.Password, uuser.Password) // Password should not change
|
||||||
assert.Equal(t, theuser.Username, uuser.Username) // Username should not change either
|
assert.Equal(t, theuser.Username, uuser.Username) // Username should not change either
|
||||||
|
|
||||||
// Try updating one which does not exist
|
// Try updating one which does not exist
|
||||||
_, err = UpdateUser(User{ID: 99999, Username: "dg"})
|
_, err = UpdateUser(&User{ID: 99999, Username: "dg"})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrUserDoesNotExist(err))
|
assert.True(t, IsErrUserDoesNotExist(err))
|
||||||
|
|
||||||
// Update a users password
|
// Update a users password
|
||||||
newpassword := "55555"
|
newpassword := "55555"
|
||||||
err = UpdateUserPassword(&theuser, newpassword)
|
err = UpdateUserPassword(theuser, newpassword)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Check if it was changed
|
// Check if it was changed
|
||||||
user, err = CheckUserCredentials(&UserLogin{theuser.Username, newpassword})
|
_, err = CheckUserCredentials(&UserLogin{theuser.Username, newpassword})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Check if the searchterm works
|
// Check if the searchterm works
|
||||||
|
@ -134,11 +134,11 @@ func TestCreateUser(t *testing.T) {
|
||||||
assert.True(t, IsErrUserDoesNotExist(err))
|
assert.True(t, IsErrUserDoesNotExist(err))
|
||||||
|
|
||||||
// Delete it
|
// Delete it
|
||||||
err = DeleteUserByID(theuser.ID, &doer)
|
err = DeleteUserByID(theuser.ID, doer)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Try deleting one with ID = 0
|
// Try deleting one with ID = 0
|
||||||
err = DeleteUserByID(0, &doer)
|
err = DeleteUserByID(0, doer)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, IsErrIDCannotBeZero(err))
|
assert.True(t, IsErrIDCannotBeZero(err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,5 +119,11 @@ func ListUsersFromList(l *List, search string) (users []*User, err error) {
|
||||||
GroupBy("id").
|
GroupBy("id").
|
||||||
OrderBy("id").
|
OrderBy("id").
|
||||||
Find(&users)
|
Find(&users)
|
||||||
|
|
||||||
|
// Obfuscate all user emails
|
||||||
|
for _, u := range users {
|
||||||
|
u.Email = ""
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ func Login(c echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create token
|
// Create token
|
||||||
t, err := CreateNewJWTTokenForUser(&user)
|
t, err := CreateNewJWTTokenForUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue