Skip to content

Commit e30a130

Browse files
lunnyGiteaBot
andauthored
Fix edit user email bug in API (#36068)
Follow #36058 for API edit user bug when editing email. - The Admin Edit User API includes a breaking change. Previously, when updating a user with an email from an unallowed domain, the request would succeed but return a warning in the response headers. Now, the request will fail and return an error in the response body instead. - Removed `AdminAddOrSetPrimaryEmailAddress` because it will not be used any where. Fix #36058 (comment) --------- Co-authored-by: Giteabot <[email protected]>
1 parent 97cb440 commit e30a130

File tree

4 files changed

+9
-113
lines changed

4 files changed

+9
-113
lines changed

routers/api/v1/admin/user.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,12 @@ func EditUser(ctx *context.APIContext) {
216216
}
217217

218218
if form.Email != nil {
219-
if err := user_service.AdminAddOrSetPrimaryEmailAddress(ctx, ctx.ContextUser, *form.Email); err != nil {
219+
if err := user_service.ReplacePrimaryEmailAddress(ctx, ctx.ContextUser, *form.Email); err != nil {
220220
switch {
221221
case user_model.IsErrEmailCharIsNotSupported(err), user_model.IsErrEmailInvalid(err):
222+
if !user_model.IsEmailDomainAllowed(*form.Email) {
223+
err = fmt.Errorf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", *form.Email)
224+
}
222225
ctx.APIError(http.StatusBadRequest, err)
223226
case user_model.IsErrEmailAlreadyUsed(err):
224227
ctx.APIError(http.StatusBadRequest, err)
@@ -227,10 +230,6 @@ func EditUser(ctx *context.APIContext) {
227230
}
228231
return
229232
}
230-
231-
if !user_model.IsEmailDomainAllowed(*form.Email) {
232-
ctx.Resp.Header().Add("X-Gitea-Warning", fmt.Sprintf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", *form.Email))
233-
}
234233
}
235234

236235
opts := &user_service.UpdateOptions{

services/user/email.go

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,60 +14,6 @@ import (
1414
"code.gitea.io/gitea/modules/util"
1515
)
1616

17-
// AdminAddOrSetPrimaryEmailAddress is used by admins to add or set a user's primary email address
18-
func AdminAddOrSetPrimaryEmailAddress(ctx context.Context, u *user_model.User, emailStr string) error {
19-
if strings.EqualFold(u.Email, emailStr) {
20-
return nil
21-
}
22-
23-
if err := user_model.ValidateEmailForAdmin(emailStr); err != nil {
24-
return err
25-
}
26-
27-
// Check if address exists already
28-
email, err := user_model.GetEmailAddressByEmail(ctx, emailStr)
29-
if err != nil && !errors.Is(err, util.ErrNotExist) {
30-
return err
31-
}
32-
if email != nil && email.UID != u.ID {
33-
return user_model.ErrEmailAlreadyUsed{Email: emailStr}
34-
}
35-
36-
// Update old primary address
37-
primary, err := user_model.GetPrimaryEmailAddressOfUser(ctx, u.ID)
38-
if err != nil {
39-
return err
40-
}
41-
42-
primary.IsPrimary = false
43-
if err := user_model.UpdateEmailAddress(ctx, primary); err != nil {
44-
return err
45-
}
46-
47-
// Insert new or update existing address
48-
if email != nil {
49-
email.IsPrimary = true
50-
email.IsActivated = true
51-
if err := user_model.UpdateEmailAddress(ctx, email); err != nil {
52-
return err
53-
}
54-
} else {
55-
email = &user_model.EmailAddress{
56-
UID: u.ID,
57-
Email: emailStr,
58-
IsActivated: true,
59-
IsPrimary: true,
60-
}
61-
if _, err := user_model.InsertEmailAddress(ctx, email); err != nil {
62-
return err
63-
}
64-
}
65-
66-
u.Email = emailStr
67-
68-
return user_model.UpdateUserCols(ctx, u, "email")
69-
}
70-
7117
func ReplacePrimaryEmailAddress(ctx context.Context, u *user_model.User, emailStr string) error {
7218
if strings.EqualFold(u.Email, emailStr) {
7319
return nil

services/user/email_test.go

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,61 +9,10 @@ import (
99
organization_model "code.gitea.io/gitea/models/organization"
1010
"code.gitea.io/gitea/models/unittest"
1111
user_model "code.gitea.io/gitea/models/user"
12-
"code.gitea.io/gitea/modules/glob"
13-
"code.gitea.io/gitea/modules/setting"
1412

1513
"github.com/stretchr/testify/assert"
1614
)
1715

18-
func TestAdminAddOrSetPrimaryEmailAddress(t *testing.T) {
19-
assert.NoError(t, unittest.PrepareTestDatabase())
20-
21-
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 27})
22-
23-
emails, err := user_model.GetEmailAddresses(t.Context(), user.ID)
24-
assert.NoError(t, err)
25-
assert.Len(t, emails, 1)
26-
27-
primary, err := user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID)
28-
assert.NoError(t, err)
29-
assert.NotEqual(t, "[email protected]", primary.Email)
30-
assert.Equal(t, user.Email, primary.Email)
31-
32-
assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(t.Context(), user, "[email protected]"))
33-
34-
primary, err = user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID)
35-
assert.NoError(t, err)
36-
assert.Equal(t, "[email protected]", primary.Email)
37-
assert.Equal(t, user.Email, primary.Email)
38-
39-
emails, err = user_model.GetEmailAddresses(t.Context(), user.ID)
40-
assert.NoError(t, err)
41-
assert.Len(t, emails, 2)
42-
43-
setting.Service.EmailDomainAllowList = []glob.Glob{glob.MustCompile("example.org")}
44-
defer func() {
45-
setting.Service.EmailDomainAllowList = []glob.Glob{}
46-
}()
47-
48-
assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(t.Context(), user, "[email protected]"))
49-
50-
primary, err = user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID)
51-
assert.NoError(t, err)
52-
assert.Equal(t, "[email protected]", primary.Email)
53-
assert.Equal(t, user.Email, primary.Email)
54-
55-
assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(t.Context(), user, "[email protected]"))
56-
57-
primary, err = user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID)
58-
assert.NoError(t, err)
59-
assert.Equal(t, "[email protected]", primary.Email)
60-
assert.Equal(t, user.Email, primary.Email)
61-
62-
emails, err = user_model.GetEmailAddresses(t.Context(), user.ID)
63-
assert.NoError(t, err)
64-
assert.Len(t, emails, 3)
65-
}
66-
6716
func TestReplacePrimaryEmailAddress(t *testing.T) {
6817
assert.NoError(t, unittest.PrepareTestDatabase())
6918

tests/integration/api_admin_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,12 @@ func TestAPIEditUser_NotAllowedEmailDomain(t *testing.T) {
382382
SourceID: 0,
383383
Email: &newEmail,
384384
}).AddTokenAuth(token)
385-
resp := MakeRequest(t, req, http.StatusOK)
386-
assert.Equal(t, "the domain of user email [email protected] conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", resp.Header().Get("X-Gitea-Warning"))
385+
resp := MakeRequest(t, req, http.StatusBadRequest)
386+
errMap := make(map[string]string)
387+
assert.NoError(t, json.Unmarshal(resp.Body.Bytes(), &errMap))
388+
assert.Equal(t, "the domain of user email [email protected] conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", errMap["message"])
387389

388-
originalEmail := "user2@example.com"
390+
originalEmail := "user2@example.org"
389391
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{
390392
LoginName: "user2",
391393
SourceID: 0,

0 commit comments

Comments
 (0)