Skip to content

Commit 5d6d025

Browse files
authored
Add support for searching users by email (#30908)
Fix #30898 we have an option `SearchByEmail`, so enable it, then we can search user by email. Also added a test for it.
1 parent 7e68bc8 commit 5d6d025

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

models/user/search.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,19 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess
6565
builder.Like{"LOWER(full_name)", lowerKeyword},
6666
)
6767
if opts.SearchByEmail {
68-
keywordCond = keywordCond.Or(builder.Like{"LOWER(email)", lowerKeyword})
68+
var emailCond builder.Cond
69+
emailCond = builder.Like{"LOWER(email)", lowerKeyword}
70+
if opts.Actor == nil {
71+
emailCond = emailCond.And(builder.Eq{"keep_email_private": false})
72+
} else if !opts.Actor.IsAdmin {
73+
emailCond = emailCond.And(
74+
builder.Or(
75+
builder.Eq{"keep_email_private": false},
76+
builder.Eq{"id": opts.Actor.ID},
77+
),
78+
)
79+
}
80+
keywordCond = keywordCond.Or(emailCond)
6981
}
7082

7183
cond = cond.And(keywordCond)

routers/api/v1/user/user.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@ func Search(ctx *context.APIContext) {
6868
users = []*user_model.User{user_model.NewActionsUser()}
6969
default:
7070
users, maxResults, err = user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
71-
Actor: ctx.Doer,
72-
Keyword: ctx.FormTrim("q"),
73-
UID: uid,
74-
Type: user_model.UserTypeIndividual,
75-
ListOptions: listOptions,
71+
Actor: ctx.Doer,
72+
Keyword: ctx.FormTrim("q"),
73+
UID: uid,
74+
Type: user_model.UserTypeIndividual,
75+
SearchByEmail: true,
76+
ListOptions: listOptions,
7677
})
7778
if err != nil {
7879
ctx.JSON(http.StatusInternalServerError, map[string]any{

tests/integration/api_user_search_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,39 @@ func TestAPIUserSearchNotLoggedInUserHidden(t *testing.T) {
109109
DecodeJSON(t, resp, &results)
110110
assert.Empty(t, results.Data)
111111
}
112+
113+
func TestAPIUserSearchByEmail(t *testing.T) {
114+
defer tests.PrepareTestEnv(t)()
115+
116+
// admin can search user with private email
117+
adminUsername := "user1"
118+
session := loginUser(t, adminUsername)
119+
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser)
120+
query := "[email protected]"
121+
req := NewRequestf(t, "GET", "/api/v1/users/search?q=%s", query).
122+
AddTokenAuth(token)
123+
resp := MakeRequest(t, req, http.StatusOK)
124+
125+
var results SearchResults
126+
DecodeJSON(t, resp, &results)
127+
assert.Equal(t, 1, len(results.Data))
128+
assert.Equal(t, query, results.Data[0].Email)
129+
130+
// no login user can not search user with private email
131+
req = NewRequestf(t, "GET", "/api/v1/users/search?q=%s", query)
132+
resp = MakeRequest(t, req, http.StatusOK)
133+
DecodeJSON(t, resp, &results)
134+
assert.Empty(t, results.Data)
135+
136+
// user can search self with private email
137+
user2 := "user2"
138+
session = loginUser(t, user2)
139+
token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser)
140+
req = NewRequestf(t, "GET", "/api/v1/users/search?q=%s", query).
141+
AddTokenAuth(token)
142+
resp = MakeRequest(t, req, http.StatusOK)
143+
144+
DecodeJSON(t, resp, &results)
145+
assert.Equal(t, 1, len(results.Data))
146+
assert.Equal(t, query, results.Data[0].Email)
147+
}

0 commit comments

Comments
 (0)