diff --git a/models/user/search.go b/models/user/search.go index 45b051187e..382b6fac2b 100644 --- a/models/user/search.go +++ b/models/user/search.go @@ -65,7 +65,19 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess builder.Like{"LOWER(full_name)", lowerKeyword}, ) if opts.SearchByEmail { - keywordCond = keywordCond.Or(builder.Like{"LOWER(email)", lowerKeyword}) + var emailCond builder.Cond + emailCond = builder.Like{"LOWER(email)", lowerKeyword} + if opts.Actor == nil { + emailCond = emailCond.And(builder.Eq{"keep_email_private": false}) + } else if !opts.Actor.IsAdmin { + emailCond = emailCond.And( + builder.Or( + builder.Eq{"keep_email_private": false}, + builder.Eq{"id": opts.Actor.ID}, + ), + ) + } + keywordCond = keywordCond.Or(emailCond) } cond = cond.And(keywordCond) diff --git a/tests/integration/api_user_search_test.go b/tests/integration/api_user_search_test.go index f34e21b600..ff4671c54e 100644 --- a/tests/integration/api_user_search_test.go +++ b/tests/integration/api_user_search_test.go @@ -112,6 +112,8 @@ func TestAPIUserSearchNotLoggedInUserHidden(t *testing.T) { func TestAPIUserSearchByEmail(t *testing.T) { defer tests.PrepareTestEnv(t)() + + // admin can search user with private email adminUsername := "user1" session := loginUser(t, adminUsername) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) @@ -124,4 +126,22 @@ func TestAPIUserSearchByEmail(t *testing.T) { DecodeJSON(t, resp, &results) assert.Equal(t, 1, len(results.Data)) assert.Equal(t, query, results.Data[0].Email) + + // no login user can not search user with private email + req = NewRequestf(t, "GET", "/api/v1/users/search?q=%s", query) + resp = MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &results) + assert.Empty(t, results.Data) + + // user can search self with private email + user2 := "user2" + session = loginUser(t, user2) + token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) + req = NewRequestf(t, "GET", "/api/v1/users/search?q=%s", query). + AddTokenAuth(token) + resp = MakeRequest(t, req, http.StatusOK) + + DecodeJSON(t, resp, &results) + assert.Equal(t, 1, len(results.Data)) + assert.Equal(t, query, results.Data[0].Email) }