]> source.dussan.org Git - gitea.git/commitdiff
Add support for searching users by email (#30908)
authoryp05327 <576951401@qq.com>
Fri, 4 Oct 2024 17:45:06 +0000 (02:45 +0900)
committerGitHub <noreply@github.com>
Fri, 4 Oct 2024 17:45:06 +0000 (17:45 +0000)
Fix #30898

we have an option `SearchByEmail`, so enable it, then we can search user
by email.
Also added a test for it.

models/user/search.go
routers/api/v1/user/user.go
tests/integration/api_user_search_test.go

index 45b051187ea07fa001ac5d8124c67abdb3421490..382b6fac2b08ea7026f01ec9f64039d3e28e3f3b 100644 (file)
@@ -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)
index fedad87fc4fa5dd2275112490f3e753d602fd34b..2c277a18c739a42f7e1b5f1fd9705bc1f3410709 100644 (file)
@@ -68,11 +68,12 @@ func Search(ctx *context.APIContext) {
                users = []*user_model.User{user_model.NewActionsUser()}
        default:
                users, maxResults, err = user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
-                       Actor:       ctx.Doer,
-                       Keyword:     ctx.FormTrim("q"),
-                       UID:         uid,
-                       Type:        user_model.UserTypeIndividual,
-                       ListOptions: listOptions,
+                       Actor:         ctx.Doer,
+                       Keyword:       ctx.FormTrim("q"),
+                       UID:           uid,
+                       Type:          user_model.UserTypeIndividual,
+                       SearchByEmail: true,
+                       ListOptions:   listOptions,
                })
                if err != nil {
                        ctx.JSON(http.StatusInternalServerError, map[string]any{
index f776b35325768ec16cd7acaa128e4335bbf7e62a..ff4671c54e94a71f496212940e8e360e289ebae0 100644 (file)
@@ -109,3 +109,39 @@ func TestAPIUserSearchNotLoggedInUserHidden(t *testing.T) {
        DecodeJSON(t, resp, &results)
        assert.Empty(t, results.Data)
 }
+
+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)
+       query := "user2@example.com"
+       req := NewRequestf(t, "GET", "/api/v1/users/search?q=%s", query).
+               AddTokenAuth(token)
+       resp := MakeRequest(t, req, http.StatusOK)
+
+       var results SearchResults
+       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)
+}