Skip to content

Commit 19aa38d

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Fix incorrect `/tokens` api (go-gitea#32085) Set manual `tabindex`es on login page (go-gitea#31689) Only use Host header from reverse proxy (go-gitea#32060) [skip ci] Updated translations via Crowdin
2 parents 3cd37d1 + 08adbc4 commit 19aa38d

File tree

8 files changed

+32
-39
lines changed

8 files changed

+32
-39
lines changed

.github/workflows/pull-db-tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ jobs:
201201
runs-on: ubuntu-latest
202202
services:
203203
mssql:
204-
image: mcr.microsoft.com/mssql/server:2017-latest
204+
# some images before 2024-04 can't run on new kernels
205+
image: mcr.microsoft.com/mssql/server:2019-latest
205206
env:
206207
ACCEPT_EULA: Y
207208
MSSQL_PID: Standard

modules/httplib/url.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@ func getRequestScheme(req *http.Request) string {
5252
return ""
5353
}
5454

55-
func getForwardedHost(req *http.Request) string {
56-
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
57-
return req.Header.Get("X-Forwarded-Host")
58-
}
59-
6055
// GuessCurrentAppURL tries to guess the current full app URL (with sub-path) by http headers. It always has a '/' suffix, exactly the same as setting.AppURL
6156
func GuessCurrentAppURL(ctx context.Context) string {
6257
return GuessCurrentHostURL(ctx) + setting.AppSubURL + "/"
@@ -81,11 +76,9 @@ func GuessCurrentHostURL(ctx context.Context) string {
8176
if reqScheme == "" {
8277
return strings.TrimSuffix(setting.AppURL, setting.AppSubURL+"/")
8378
}
84-
reqHost := getForwardedHost(req)
85-
if reqHost == "" {
86-
reqHost = req.Host
87-
}
88-
return reqScheme + "://" + reqHost
79+
// X-Forwarded-Host has many problems: non-standard, not well-defined (X-Forwarded-Port or not), conflicts with Host header.
80+
// So do not use X-Forwarded-Host, just use Host header directly.
81+
return reqScheme + "://" + req.Host
8982
}
9083

9184
// MakeAbsoluteURL tries to make a link to an absolute URL:

modules/httplib/url_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func TestMakeAbsoluteURL(t *testing.T) {
7070
"X-Forwarded-Proto": {"https"},
7171
},
7272
})
73-
assert.Equal(t, "https://forwarded-host/foo", MakeAbsoluteURL(ctx, "/foo"))
73+
assert.Equal(t, "https://user-host/foo", MakeAbsoluteURL(ctx, "/foo"))
7474
}
7575

7676
func TestIsCurrentGiteaSiteURL(t *testing.T) {
@@ -119,5 +119,6 @@ func TestIsCurrentGiteaSiteURL(t *testing.T) {
119119
},
120120
})
121121
assert.True(t, IsCurrentGiteaSiteURL(ctx, "http://localhost:3000"))
122-
assert.True(t, IsCurrentGiteaSiteURL(ctx, "https://forwarded-host"))
122+
assert.True(t, IsCurrentGiteaSiteURL(ctx, "https://user-host"))
123+
assert.False(t, IsCurrentGiteaSiteURL(ctx, "https://forwarded-host"))
123124
}

options/locale/locale_pt-PT.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,6 +1731,7 @@ issues.dependency.add_error_dep_not_same_repo=Ambas as questões têm que estar
17311731
issues.review.self.approval=Não pode aprovar o seu próprio pedido de integração.
17321732
issues.review.self.rejection=Não pode solicitar modificações sobre o seu próprio pedido de integração.
17331733
issues.review.approve=aprovou estas modificações %s
1734+
issues.review.comment=reviu %s
17341735
issues.review.dismissed=descartou a revisão de %s %s
17351736
issues.review.dismissed_label=Descartada
17361737
issues.review.left_comment=deixou um comentário

routers/api/v1/user/app.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ func CreateAccessToken(ctx *context.APIContext) {
118118
ctx.Error(http.StatusBadRequest, "AccessTokenScope.Normalize", fmt.Errorf("invalid access token scope provided: %w", err))
119119
return
120120
}
121+
if scope == "" {
122+
ctx.Error(http.StatusBadRequest, "AccessTokenScope", "access token must have a scope")
123+
return
124+
}
121125
t.Scope = scope
122126

123127
if err := auth_model.NewAccessToken(ctx, t); err != nil {
@@ -129,6 +133,7 @@ func CreateAccessToken(ctx *context.APIContext) {
129133
Token: t.Token,
130134
ID: t.ID,
131135
TokenLastEight: t.TokenLastEight,
136+
Scopes: t.Scope.StringSlice(),
132137
})
133138
}
134139

templates/user/auth/signin_inner.tmpl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,30 @@
1414
{{.CsrfTokenHtml}}
1515
<div class="required field {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
1616
<label for="user_name">{{ctx.Locale.Tr "home.uname_holder"}}</label>
17-
<input id="user_name" type="text" name="user_name" value="{{.user_name}}" autofocus required>
17+
<input id="user_name" type="text" name="user_name" value="{{.user_name}}" autofocus required tabindex="1">
1818
</div>
1919
{{if or (not .DisablePassword) .LinkAccountMode}}
2020
<div class="required field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}} form-field-content-aside-label">
2121
<label for="password">{{ctx.Locale.Tr "password"}}</label>
22-
<a href="{{AppSubUrl}}/user/forgot_password">{{ctx.Locale.Tr "auth.forgot_password"}}</a>
23-
<input id="password" name="password" type="password" value="{{.password}}" autocomplete="current-password" required>
22+
<div>
23+
<a href="{{AppSubUrl}}/user/forgot_password" tabindex="4">{{ctx.Locale.Tr "auth.forgot_password"}}</a>
24+
</div>
25+
<input id="password" name="password" type="password" value="{{.password}}" autocomplete="current-password" required tabindex="2">
2426
</div>
2527
{{end}}
2628
{{if not .LinkAccountMode}}
2729
<div class="inline field">
2830
<div class="ui checkbox">
2931
<label>{{ctx.Locale.Tr "auth.remember_me"}}</label>
30-
<input name="remember" type="checkbox">
32+
<input name="remember" type="checkbox" tabindex="5">
3133
</div>
3234
</div>
3335
{{end}}
3436

3537
{{template "user/auth/captcha" .}}
3638

3739
<div class="field">
38-
<button class="ui primary button tw-w-full">
40+
<button class="ui primary button tw-w-full" tabindex="3">
3941
{{if .LinkAccountMode}}
4042
{{ctx.Locale.Tr "auth.oauth_signin_submit"}}
4143
{{else}}

tests/integration/api_token_test.go

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ func TestAPICreateAndDeleteToken(t *testing.T) {
2323
defer tests.PrepareTestEnv(t)()
2424
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
2525

26-
newAccessToken := createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user, nil)
26+
newAccessToken := createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll})
2727
deleteAPIAccessToken(t, newAccessToken, user)
2828

29-
newAccessToken = createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user, nil)
29+
newAccessToken = createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll})
3030
deleteAPIAccessToken(t, newAccessToken, user)
3131
}
3232

@@ -72,19 +72,19 @@ func TestAPIDeleteTokensPermission(t *testing.T) {
7272
user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
7373

7474
// admin can delete tokens for other users
75-
createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user2, nil)
75+
createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user2, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll})
7676
req := NewRequest(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-1").
7777
AddBasicAuth(admin.Name)
7878
MakeRequest(t, req, http.StatusNoContent)
7979

8080
// non-admin can delete tokens for himself
81-
createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user2, nil)
81+
createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user2, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll})
8282
req = NewRequest(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-2").
8383
AddBasicAuth(user2.Name)
8484
MakeRequest(t, req, http.StatusNoContent)
8585

8686
// non-admin can't delete tokens for other users
87-
createAPIAccessTokenWithoutCleanUp(t, "test-key-3", user2, nil)
87+
createAPIAccessTokenWithoutCleanUp(t, "test-key-3", user2, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll})
8888
req = NewRequest(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-3").
8989
AddBasicAuth(user4.Name)
9090
MakeRequest(t, req, http.StatusForbidden)
@@ -520,7 +520,7 @@ func runTestCase(t *testing.T, testCase *requiredScopeTestCase, user *user_model
520520
unauthorizedScopes = append(unauthorizedScopes, cateogoryUnauthorizedScopes...)
521521
}
522522

523-
accessToken := createAPIAccessTokenWithoutCleanUp(t, "test-token", user, &unauthorizedScopes)
523+
accessToken := createAPIAccessTokenWithoutCleanUp(t, "test-token", user, unauthorizedScopes)
524524
defer deleteAPIAccessToken(t, accessToken, user)
525525

526526
// Request the endpoint. Verify that permission is denied.
@@ -532,20 +532,12 @@ func runTestCase(t *testing.T, testCase *requiredScopeTestCase, user *user_model
532532

533533
// createAPIAccessTokenWithoutCleanUp Create an API access token and assert that
534534
// creation succeeded. The caller is responsible for deleting the token.
535-
func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *user_model.User, scopes *[]auth_model.AccessTokenScope) api.AccessToken {
535+
func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *user_model.User, scopes []auth_model.AccessTokenScope) api.AccessToken {
536536
payload := map[string]any{
537-
"name": tokenName,
538-
}
539-
if scopes != nil {
540-
for _, scope := range *scopes {
541-
scopes, scopesExists := payload["scopes"].([]string)
542-
if !scopesExists {
543-
scopes = make([]string, 0)
544-
}
545-
scopes = append(scopes, string(scope))
546-
payload["scopes"] = scopes
547-
}
537+
"name": tokenName,
538+
"scopes": scopes,
548539
}
540+
549541
log.Debug("Requesting creation of token with scopes: %v", scopes)
550542
req := NewRequestWithJSON(t, "POST", "/api/v1/users/"+user.LoginName+"/tokens", payload).
551543
AddBasicAuth(user.Name)
@@ -563,8 +555,7 @@ func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *us
563555
return newAccessToken
564556
}
565557

566-
// createAPIAccessTokenWithoutCleanUp Delete an API access token and assert that
567-
// deletion succeeded.
558+
// deleteAPIAccessToken deletes an API access token and assert that deletion succeeded.
568559
func deleteAPIAccessToken(t *testing.T, accessToken api.AccessToken, user *user_model.User) {
569560
req := NewRequestf(t, "DELETE", "/api/v1/users/"+user.LoginName+"/tokens/%d", accessToken.ID).
570561
AddBasicAuth(user.Name)

web_src/css/form.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,6 @@ textarea:focus,
456456
}
457457
.form-field-content-aside-label > *:nth-child(2) {
458458
text-align: right;
459-
margin-bottom: 4px;
460459
}
461460
.form-field-content-aside-label input {
462461
grid-column: span 2;

0 commit comments

Comments
 (0)