Skip to content

Commit cc942e2

Browse files
authored
Fix GetUsersByEmails (#34643)
1 parent 7fa5a88 commit cc942e2

File tree

4 files changed

+47
-21
lines changed

4 files changed

+47
-21
lines changed

models/fixtures/email_address.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
-
8282
id: 11
8383
uid: 4
84-
email: user4@example.com
84+
email: User4@Example.Com
8585
lower_email: user4@example.com
8686
is_activated: true
8787
is_primary: true

models/user/user.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,8 +1151,8 @@ func ValidateCommitsWithEmails(ctx context.Context, oldCommits []*git.Commit) ([
11511151
}
11521152

11531153
for _, c := range oldCommits {
1154-
user, ok := emailUserMap[c.Author.Email]
1155-
if !ok {
1154+
user := emailUserMap.GetByEmail(c.Author.Email) // FIXME: why ValidateCommitsWithEmails uses "Author", but ParseCommitsWithSignature uses "Committer"?
1155+
if user == nil {
11561156
user = &User{
11571157
Name: c.Author.Name,
11581158
Email: c.Author.Email,
@@ -1166,7 +1166,15 @@ func ValidateCommitsWithEmails(ctx context.Context, oldCommits []*git.Commit) ([
11661166
return newCommits, nil
11671167
}
11681168

1169-
func GetUsersByEmails(ctx context.Context, emails []string) (map[string]*User, error) {
1169+
type EmailUserMap struct {
1170+
m map[string]*User
1171+
}
1172+
1173+
func (eum *EmailUserMap) GetByEmail(email string) *User {
1174+
return eum.m[strings.ToLower(email)]
1175+
}
1176+
1177+
func GetUsersByEmails(ctx context.Context, emails []string) (*EmailUserMap, error) {
11701178
if len(emails) == 0 {
11711179
return nil, nil
11721180
}
@@ -1176,7 +1184,7 @@ func GetUsersByEmails(ctx context.Context, emails []string) (map[string]*User, e
11761184
for _, email := range emails {
11771185
if strings.HasSuffix(email, "@"+setting.Service.NoReplyAddress) {
11781186
username := strings.TrimSuffix(email, "@"+setting.Service.NoReplyAddress)
1179-
needCheckUserNames.Add(username)
1187+
needCheckUserNames.Add(strings.ToLower(username))
11801188
} else {
11811189
needCheckEmails.Add(strings.ToLower(email))
11821190
}
@@ -1203,8 +1211,7 @@ func GetUsersByEmails(ctx context.Context, emails []string) (map[string]*User, e
12031211
for _, email := range emailAddresses {
12041212
user := users[email.UID]
12051213
if user != nil {
1206-
results[user.Email] = user
1207-
results[user.GetPlaceholderEmail()] = user
1214+
results[email.LowerEmail] = user
12081215
}
12091216
}
12101217
}
@@ -1214,10 +1221,9 @@ func GetUsersByEmails(ctx context.Context, emails []string) (map[string]*User, e
12141221
return nil, err
12151222
}
12161223
for _, user := range users {
1217-
results[user.Email] = user
1218-
results[user.GetPlaceholderEmail()] = user
1224+
results[strings.ToLower(user.GetPlaceholderEmail())] = user
12191225
}
1220-
return results, nil
1226+
return &EmailUserMap{results}, nil
12211227
}
12221228

12231229
// GetUserByEmail returns the user object by given e-mail if exists.

models/user/user_test.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,33 @@ func TestUserEmails(t *testing.T) {
5858
assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "org7"}))
5959
})
6060
t.Run("GetUsersByEmails", func(t *testing.T) {
61-
m, err := user_model.GetUsersByEmails(db.DefaultContext, []string{"user1@example.com", "user2@" + setting.Service.NoReplyAddress})
62-
require.NoError(t, err)
63-
require.Len(t, m, 4)
64-
assert.EqualValues(t, 1, m["user1@example.com"].ID)
65-
assert.EqualValues(t, 1, m["user1@"+setting.Service.NoReplyAddress].ID)
66-
assert.EqualValues(t, 2, m["user2@example.com"].ID)
67-
assert.EqualValues(t, 2, m["user2@"+setting.Service.NoReplyAddress].ID)
61+
defer test.MockVariableValue(&setting.Service.NoReplyAddress, "NoReply.gitea.internal")()
62+
testGetUserByEmail := func(t *testing.T, email string, uid int64) {
63+
m, err := user_model.GetUsersByEmails(db.DefaultContext, []string{email})
64+
require.NoError(t, err)
65+
user := m.GetByEmail(email)
66+
if uid == 0 {
67+
require.Nil(t, user)
68+
return
69+
}
70+
require.NotNil(t, user)
71+
assert.Equal(t, uid, user.ID)
72+
}
73+
cases := []struct {
74+
Email string
75+
UID int64
76+
}{
77+
{"UseR1@example.com", 1},
78+
{"user1-2@example.COM", 1},
79+
{"USER2@" + setting.Service.NoReplyAddress, 2},
80+
{"user4@example.com", 4},
81+
{"no-such", 0},
82+
}
83+
for _, c := range cases {
84+
t.Run(c.Email, func(t *testing.T) {
85+
testGetUserByEmail(t, c.Email, c.UID)
86+
})
87+
}
6888
})
6989
}
7090

services/git/commit.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@ func ParseCommitsWithSignature(ctx context.Context, repo *repo_model.Repository,
3434
}
3535

3636
for _, c := range oldCommits {
37-
committer, ok := emailUsers[c.Committer.Email]
38-
if !ok && c.Committer != nil {
39-
committer = &user_model.User{
37+
committerUser := emailUsers.GetByEmail(c.Committer.Email) // FIXME: why ValidateCommitsWithEmails uses "Author", but ParseCommitsWithSignature uses "Committer"?
38+
if committerUser == nil {
39+
committerUser = &user_model.User{
4040
Name: c.Committer.Name,
4141
Email: c.Committer.Email,
4242
}
4343
}
4444

4545
signCommit := &asymkey_model.SignCommit{
4646
UserCommit: c,
47-
Verification: asymkey_service.ParseCommitWithSignatureCommitter(ctx, c.Commit, committer),
47+
Verification: asymkey_service.ParseCommitWithSignatureCommitter(ctx, c.Commit, committerUser),
4848
}
4949

5050
isOwnerMemberCollaborator := func(user *user_model.User) (bool, error) {

0 commit comments

Comments
 (0)