Skip to content

Commit af32a09

Browse files
committed
Merge branch 'master' into allow-block_list_migrate-mirror_8040
2 parents 840fc85 + b651409 commit af32a09

File tree

27 files changed

+514
-183
lines changed

27 files changed

+514
-183
lines changed

.github/lock.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Configuration for Lock Threads - https://github.com/dessant/lock-threads-app
2+
3+
# Number of days of inactivity before a closed issue or pull request is locked
4+
daysUntilLock: 60
5+
6+
# Skip issues and pull requests created before a given timestamp. Timestamp must
7+
# follow ISO 8601 (`YYYY-MM-DD`). `false` is disabled
8+
skipCreatedBefore: false
9+
10+
# Issues and pull requests with these labels will be ignored.
11+
exemptLabels: []
12+
13+
# Label to add before locking, such as `outdated`. `false` is disabled
14+
lockLabel: false
15+
16+
# Comment to post before locking.
17+
lockComment: >
18+
This thread has been automatically locked since there has not been
19+
any recent activity after it was closed. Please open a new issue for
20+
related bugs and link to relevant comments in this thread.
21+
22+
# Assign `resolved` as the reason for locking. Set to `false` to disable
23+
setLockReason: true

docs/config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ params:
1818
description: Git with a cup of tea
1919
author: The Gitea Authors
2020
website: https://docs.gitea.io
21-
version: 1.12.5
21+
version: 1.12.6
2222
minGoVersion: 1.13
2323
goVersion: 1.15
2424
minNodeVersion: 10.13

docs/content/doc/installation/with-docker.en-us.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ networks:
4242

4343
services:
4444
server:
45-
image: gitea/gitea:latest
45+
image: gitea/gitea:{{< version >}}
4646
container_name: gitea
4747
environment:
4848
- USER_UID=1000
@@ -74,7 +74,7 @@ networks:
7474

7575
services:
7676
server:
77-
image: gitea/gitea:latest
77+
image: gitea/gitea:{{< version >}}
7878
container_name: gitea
7979
environment:
8080
- USER_UID=1000
@@ -107,7 +107,7 @@ networks:
107107

108108
services:
109109
server:
110-
image: gitea/gitea:latest
110+
image: gitea/gitea:{{< version >}}
111111
container_name: gitea
112112
environment:
113113
- USER_UID=1000
@@ -158,7 +158,7 @@ networks:
158158

159159
services:
160160
server:
161-
image: gitea/gitea:latest
161+
image: gitea/gitea:{{< version >}}
162162
container_name: gitea
163163
environment:
164164
- USER_UID=1000
@@ -214,7 +214,7 @@ networks:
214214
+
215215
services:
216216
server:
217-
image: gitea/gitea:latest
217+
image: gitea/gitea:{{< version >}}
218218
container_name: gitea
219219
restart: always
220220
networks:
@@ -315,7 +315,7 @@ version: "3"
315315
316316
services:
317317
server:
318-
image: gitea/gitea:latest
318+
image: gitea/gitea:{{< version >}}
319319
container_name: gitea
320320
environment:
321321
- USER_UID=1000

integrations/api_admin_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package integrations
66

77
import (
8+
"encoding/json"
89
"fmt"
910
"net/http"
1011
"testing"
@@ -163,3 +164,32 @@ func TestAPICreateUserInvalidEmail(t *testing.T) {
163164
})
164165
session.MakeRequest(t, req, http.StatusUnprocessableEntity)
165166
}
167+
168+
func TestAPIEditUser(t *testing.T) {
169+
defer prepareTestEnv(t)()
170+
adminUsername := "user1"
171+
session := loginUser(t, adminUsername)
172+
token := getTokenForLoggedInUser(t, session)
173+
urlStr := fmt.Sprintf("/api/v1/admin/users/%s?token=%s", "user2", token)
174+
175+
req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{
176+
// required
177+
"login_name": "user2",
178+
"source_id": "0",
179+
// to change
180+
"full_name": "Full Name User 2",
181+
})
182+
session.MakeRequest(t, req, http.StatusOK)
183+
184+
empty := ""
185+
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{
186+
LoginName: "user2",
187+
SourceID: 0,
188+
Email: &empty,
189+
})
190+
resp := session.MakeRequest(t, req, http.StatusUnprocessableEntity)
191+
192+
errMap := make(map[string]interface{})
193+
json.Unmarshal(resp.Body.Bytes(), &errMap)
194+
assert.EqualValues(t, "email is not allowed to be empty string", errMap["message"].(string))
195+
}

models/user.go

+16-11
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"errors"
1515
"fmt"
1616
_ "image/jpeg" // Needed for jpeg support
17-
"net/mail"
1817
"os"
1918
"path/filepath"
2019
"regexp"
@@ -809,9 +808,8 @@ func CreateUser(u *User) (err error) {
809808
return ErrEmailAlreadyUsed{u.Email}
810809
}
811810

812-
_, err = mail.ParseAddress(u.Email)
813-
if err != nil {
814-
return ErrEmailInvalid{u.Email}
811+
if err = ValidateEmail(u.Email); err != nil {
812+
return err
815813
}
816814

817815
isExist, err = isEmailUsed(sess, u.Email)
@@ -956,11 +954,10 @@ func checkDupEmail(e Engine, u *User) error {
956954
return nil
957955
}
958956

959-
func updateUser(e Engine, u *User) error {
957+
func updateUser(e Engine, u *User) (err error) {
960958
u.Email = strings.ToLower(u.Email)
961-
_, err := mail.ParseAddress(u.Email)
962-
if err != nil {
963-
return ErrEmailInvalid{u.Email}
959+
if err = ValidateEmail(u.Email); err != nil {
960+
return err
964961
}
965962
_, err = e.ID(u.ID).AllCols().Update(u)
966963
return err
@@ -982,13 +979,21 @@ func updateUserCols(e Engine, u *User, cols ...string) error {
982979
}
983980

984981
// UpdateUserSetting updates user's settings.
985-
func UpdateUserSetting(u *User) error {
982+
func UpdateUserSetting(u *User) (err error) {
983+
sess := x.NewSession()
984+
defer sess.Close()
985+
if err = sess.Begin(); err != nil {
986+
return err
987+
}
986988
if !u.IsOrganization() {
987-
if err := checkDupEmail(x, u); err != nil {
989+
if err = checkDupEmail(sess, u); err != nil {
988990
return err
989991
}
990992
}
991-
return updateUser(x, u)
993+
if err = updateUser(sess, u); err != nil {
994+
return err
995+
}
996+
return sess.Commit()
992997
}
993998

994999
// deleteBeans deletes all given beans, beans should contain delete conditions.

models/user_mail.go

+19-6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@ type EmailAddress struct {
3333
IsPrimary bool `xorm:"-"`
3434
}
3535

36+
// ValidateEmail check if email is a allowed address
37+
func ValidateEmail(email string) error {
38+
if len(email) == 0 {
39+
return nil
40+
}
41+
42+
if _, err := mail.ParseAddress(email); err != nil {
43+
return ErrEmailInvalid{email}
44+
}
45+
46+
// TODO: add an email allow/block list
47+
48+
return nil
49+
}
50+
3651
// GetEmailAddresses returns all email addresses belongs to given user.
3752
func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
3853
emails := make([]*EmailAddress, 0, 5)
@@ -144,9 +159,8 @@ func addEmailAddress(e Engine, email *EmailAddress) error {
144159
return ErrEmailAlreadyUsed{email.Email}
145160
}
146161

147-
_, err = mail.ParseAddress(email.Email)
148-
if err != nil {
149-
return ErrEmailInvalid{email.Email}
162+
if err = ValidateEmail(email.Email); err != nil {
163+
return err
150164
}
151165

152166
_, err = e.Insert(email)
@@ -173,9 +187,8 @@ func AddEmailAddresses(emails []*EmailAddress) error {
173187
} else if used {
174188
return ErrEmailAlreadyUsed{emails[i].Email}
175189
}
176-
_, err = mail.ParseAddress(emails[i].Email)
177-
if err != nil {
178-
return ErrEmailInvalid{emails[i].Email}
190+
if err = ValidateEmail(emails[i].Email); err != nil {
191+
return err
179192
}
180193
}
181194

modules/migrations/gitlab.go

+15-4
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,17 @@ func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, username, passw
9090

9191
// split namespace and subdirectory
9292
pathParts := strings.Split(strings.Trim(repoPath, "/"), "/")
93-
for len(pathParts) > 2 {
94-
if _, _, err = gitlabClient.Version.GetVersion(); err == nil {
93+
var resp *gitlab.Response
94+
u, _ := url.Parse(baseURL)
95+
for len(pathParts) >= 2 {
96+
_, resp, err = gitlabClient.Version.GetVersion()
97+
if err == nil || resp != nil && resp.StatusCode == 401 {
98+
err = nil // if no authentication given, this still should work
9599
break
96100
}
97101

98-
baseURL = path.Join(baseURL, pathParts[0])
102+
u.Path = path.Join(u.Path, pathParts[0])
103+
baseURL = u.String()
99104
pathParts = pathParts[1:]
100105
_ = gitlab.WithBaseURL(baseURL)(gitlabClient)
101106
repoPath = strings.Join(pathParts, "/")
@@ -105,6 +110,8 @@ func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, username, passw
105110
return nil, err
106111
}
107112

113+
log.Trace("gitlab downloader: use BaseURL: '%s' and RepoPath: '%s'", baseURL, repoPath)
114+
108115
// Grab and store project/repo ID here, due to issues using the URL escaped path
109116
gr, _, err := gitlabClient.Projects.GetProject(repoPath, nil, nil, gitlab.WithContext(ctx))
110117
if err != nil {
@@ -602,8 +609,12 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
602609

603610
// GetReviews returns pull requests review
604611
func (g *GitlabDownloader) GetReviews(pullRequestNumber int64) ([]*base.Review, error) {
605-
state, _, err := g.client.MergeRequestApprovals.GetApprovalState(g.repoID, int(pullRequestNumber), gitlab.WithContext(g.ctx))
612+
state, resp, err := g.client.MergeRequestApprovals.GetApprovalState(g.repoID, int(pullRequestNumber), gitlab.WithContext(g.ctx))
606613
if err != nil {
614+
if resp != nil && resp.StatusCode == 404 {
615+
log.Error(fmt.Sprintf("GitlabDownloader: while migrating a error occurred: '%s'", err.Error()))
616+
return []*base.Review{}, nil
617+
}
607618
return nil, err
608619
}
609620

modules/structs/admin_user.go

+16-15
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,22 @@ type CreateUserOption struct {
2323

2424
// EditUserOption edit user options
2525
type EditUserOption struct {
26-
SourceID int64 `json:"source_id"`
27-
LoginName string `json:"login_name"`
28-
FullName string `json:"full_name" binding:"MaxSize(100)"`
2926
// required: true
27+
SourceID int64 `json:"source_id"`
28+
// required: true
29+
LoginName string `json:"login_name" binding:"Required"`
3030
// swagger:strfmt email
31-
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
32-
Password string `json:"password" binding:"MaxSize(255)"`
33-
MustChangePassword *bool `json:"must_change_password"`
34-
Website string `json:"website" binding:"MaxSize(50)"`
35-
Location string `json:"location" binding:"MaxSize(50)"`
36-
Active *bool `json:"active"`
37-
Admin *bool `json:"admin"`
38-
AllowGitHook *bool `json:"allow_git_hook"`
39-
AllowImportLocal *bool `json:"allow_import_local"`
40-
MaxRepoCreation *int `json:"max_repo_creation"`
41-
ProhibitLogin *bool `json:"prohibit_login"`
42-
AllowCreateOrganization *bool `json:"allow_create_organization"`
31+
Email *string `json:"email" binding:"MaxSize(254)"`
32+
FullName *string `json:"full_name" binding:"MaxSize(100)"`
33+
Password string `json:"password" binding:"MaxSize(255)"`
34+
MustChangePassword *bool `json:"must_change_password"`
35+
Website *string `json:"website" binding:"MaxSize(50)"`
36+
Location *string `json:"location" binding:"MaxSize(50)"`
37+
Active *bool `json:"active"`
38+
Admin *bool `json:"admin"`
39+
AllowGitHook *bool `json:"allow_git_hook"`
40+
AllowImportLocal *bool `json:"allow_import_local"`
41+
MaxRepoCreation *int `json:"max_repo_creation"`
42+
ProhibitLogin *bool `json:"prohibit_login"`
43+
AllowCreateOrganization *bool `json:"allow_create_organization"`
4344
}

options/locale/locale_de-DE.ini

+1
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,7 @@ issues.action_milestone_no_select=Kein Meilenstein
10121012
issues.action_assignee=Zuständig
10131013
issues.action_assignee_no_select=Niemand zuständig
10141014
issues.opened_by=%[1]s von <a href="%[2]s">%[3]s</a> geöffnet
1015+
pulls.merged_by_fake=von %[2]s zusammengefügt %[1]s
10151016
issues.closed_by=von <a href="%[2]s">%[3]s</a> %[1]s geschlossen
10161017
issues.closed_by_fake=von %[2]s %[1]s geschlossen
10171018
issues.previous=Vorherige

options/locale/locale_en-US.ini

+2-2
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ register_helper_msg = Already have an account? Sign in now!
245245
social_register_helper_msg = Already have an account? Link it now!
246246
disable_register_prompt = Registration is disabled. Please contact your site administrator.
247247
disable_register_mail = Email confirmation for registration is disabled.
248-
remember_me = Remember Me
248+
remember_me = Remember this Device
249249
forgot_password_title= Forgot Password
250250
forgot_password = Forgot password?
251251
sign_up_now = Need an account? Register now.
@@ -278,7 +278,7 @@ twofa_scratch_token_incorrect = Your scratch code is incorrect.
278278
login_userpass = Sign In
279279
login_openid = OpenID
280280
oauth_signup_tab = Register New Account
281-
oauth_signup_title = Add Email and Password (for Account Recovery)
281+
oauth_signup_title = Complete New Account
282282
oauth_signup_submit = Complete Account
283283
oauth_signin_tab = Link to Existing Account
284284
oauth_signin_title = Sign In to Authorize Linked Account

routers/api/v1/admin/user.go

+18-5
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func EditUser(ctx *context.APIContext, form api.EditUserOption) {
155155
return
156156
}
157157

158-
if len(form.Password) > 0 {
158+
if len(form.Password) != 0 {
159159
if !password.IsComplexEnough(form.Password) {
160160
err := errors.New("PasswordComplexity")
161161
ctx.Error(http.StatusBadRequest, "PasswordComplexity", err)
@@ -182,10 +182,23 @@ func EditUser(ctx *context.APIContext, form api.EditUserOption) {
182182
}
183183

184184
u.LoginName = form.LoginName
185-
u.FullName = form.FullName
186-
u.Email = form.Email
187-
u.Website = form.Website
188-
u.Location = form.Location
185+
186+
if form.FullName != nil {
187+
u.FullName = *form.FullName
188+
}
189+
if form.Email != nil {
190+
u.Email = *form.Email
191+
if len(u.Email) == 0 {
192+
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("email is not allowed to be empty string"))
193+
return
194+
}
195+
}
196+
if form.Website != nil {
197+
u.Website = *form.Website
198+
}
199+
if form.Location != nil {
200+
u.Location = *form.Location
201+
}
189202
if form.Active != nil {
190203
u.IsActive = *form.Active
191204
}

0 commit comments

Comments
 (0)