feat: allow to find users with access to a project more freely
Related to https://kolaente.dev/vikunja/frontend/issues/2196
This commit is contained in:
parent
327bb3bed9
commit
a7231e197e
@ -22,7 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ILIKE returns an ILIKE query on postgres and a LIKE query on all other platforms.
|
// ILIKE returns an ILIKE query on postgres and a LIKE query on all other platforms.
|
||||||
// Postgres' is case sensitive by default.
|
// Postgres' is case-sensitive by default.
|
||||||
// To work around this, we're using ILIKE as opposed to normal LIKE statements.
|
// To work around this, we're using ILIKE as opposed to normal LIKE statements.
|
||||||
// ILIKE is preferred over LOWER(text) LIKE for performance reasons.
|
// ILIKE is preferred over LOWER(text) LIKE for performance reasons.
|
||||||
// See https://stackoverflow.com/q/7005302/10924593
|
// See https://stackoverflow.com/q/7005302/10924593
|
||||||
@ -31,5 +31,9 @@ func ILIKE(column, search string) builder.Cond {
|
|||||||
return builder.Expr(column+" ILIKE ?", "%"+search+"%")
|
return builder.Expr(column+" ILIKE ?", "%"+search+"%")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if Type() == schemas.SQLITE {
|
||||||
|
return builder.Expr("username = ? COLLATE NOCASE", "%"+search+"%")
|
||||||
|
}
|
||||||
|
|
||||||
return &builder.Like{column, "%" + search + "%"}
|
return &builder.Like{column, "%" + search + "%"}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ func ListUsersFromProject(s *xorm.Session, l *Project, search string) (users []*
|
|||||||
users, err = user.ListUsers(s, search, &user.ProjectUserOpts{
|
users, err = user.ListUsers(s, search, &user.ProjectUserOpts{
|
||||||
AdditionalCond: cond,
|
AdditionalCond: cond,
|
||||||
ReturnAllIfNoSearchProvided: true,
|
ReturnAllIfNoSearchProvided: true,
|
||||||
|
MatchFuzzily: true,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"gopkg.in/d4l3k/messagediff.v1"
|
"gopkg.in/d4l3k/messagediff.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestProjectUsersFromProject(t *testing.T) {
|
func TestListUsersFromProject(t *testing.T) {
|
||||||
testuser1 := &user.User{
|
testuser1 := &user.User{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Username: "user1",
|
Username: "user1",
|
||||||
@ -219,6 +219,11 @@ func TestProjectUsersFromProject(t *testing.T) {
|
|||||||
args: args{l: &Project{ID: 19, OwnerID: 7}, search: "user1"},
|
args: args{l: &Project{ID: 19, OwnerID: 7}, search: "user1"},
|
||||||
wantUsers: []*user.User{
|
wantUsers: []*user.User{
|
||||||
testuser1, // Shared Via Team readonly
|
testuser1, // Shared Via Team readonly
|
||||||
|
|
||||||
|
testuser10, // Matches Partially, Shared Via NamespaceTeam admin
|
||||||
|
testuser11, // Matches Partially, Shared Via NamespaceUser readonly
|
||||||
|
testuser12, // Matches Partially, Shared Via NamespaceUser write
|
||||||
|
testuser13, // Matches Partially, Shared Via NamespaceUser admin
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -503,6 +503,17 @@ func TestProjectUsers(t *testing.T) {
|
|||||||
"username": "user7",
|
"username": "user7",
|
||||||
}, false)
|
}, false)
|
||||||
})
|
})
|
||||||
|
t.Run("discoverable by partial username, email and name when matching fuzzily", func(t *testing.T) {
|
||||||
|
db.LoadAndAssertFixtures(t)
|
||||||
|
s := db.NewSession()
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
all, err := ListUsers(s, "user", &ProjectUserOpts{
|
||||||
|
MatchFuzzily: true,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, all, 15)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUserPasswordReset(t *testing.T) {
|
func TestUserPasswordReset(t *testing.T) {
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
type ProjectUserOpts struct {
|
type ProjectUserOpts struct {
|
||||||
AdditionalCond builder.Cond
|
AdditionalCond builder.Cond
|
||||||
ReturnAllIfNoSearchProvided bool
|
ReturnAllIfNoSearchProvided bool
|
||||||
|
MatchFuzzily bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListUsers returns a project with all users, filtered by an optional search string
|
// ListUsers returns a project with all users, filtered by an optional search string
|
||||||
@ -48,6 +49,16 @@ func ListUsers(s *xorm.Session, search string, opts *ProjectUserOpts) (users []*
|
|||||||
|
|
||||||
if search != "" {
|
if search != "" {
|
||||||
for _, queryPart := range strings.Split(search, ",") {
|
for _, queryPart := range strings.Split(search, ",") {
|
||||||
|
|
||||||
|
if opts.MatchFuzzily {
|
||||||
|
conds = append(conds,
|
||||||
|
db.ILIKE("name", queryPart),
|
||||||
|
db.ILIKE("username", queryPart),
|
||||||
|
db.ILIKE("email", queryPart),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var usernameCond builder.Cond = builder.Eq{"username": queryPart}
|
var usernameCond builder.Cond = builder.Eq{"username": queryPart}
|
||||||
if db.Type() == schemas.POSTGRES {
|
if db.Type() == schemas.POSTGRES {
|
||||||
usernameCond = builder.Expr("username ILIKE ?", queryPart)
|
usernameCond = builder.Expr("username ILIKE ?", queryPart)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user