Skip to content

Commit 1c13962

Browse files
committed
Merge branch 'main' into incr-issue-paging-num
2 parents 14a84ca + 335e918 commit 1c13962

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1507
-286
lines changed

Diff for: custom/conf/app.example.ini

+4
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ USER = root
313313
;DB_TYPE = sqlite3
314314
;PATH= ; defaults to data/gitea.db
315315
;SQLITE_TIMEOUT = ; Query timeout defaults to: 500
316+
;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode
316317
;;
317318
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
318319
;;
@@ -878,6 +879,9 @@ ROUTER = console
878879
;; Allow deletion of unadopted repositories
879880
;ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES = false
880881

882+
;; Don't allow download source archive files from UI
883+
;DISABLE_DOWNLOAD_SOURCE_ARCHIVES = false
884+
881885
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
882886
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
883887
;[repository.editor]

Diff for: docs/content/doc/advanced/config-cheat-sheet.en-us.md

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
7878
- `DEFAULT_BRANCH`: **main**: Default branch name of all repositories.
7979
- `ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to adopt unadopted repositories
8080
- `ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to delete unadopted repositories
81+
- `DISABLE_DOWNLOAD_SOURCE_ARCHIVES`: **false**: Don't allow download source archive files from UI
8182

8283
### Repository - Editor (`repository.editor`)
8384

@@ -382,6 +383,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
382383
- `verify-ca`: Enable TLS with verification of the database server certificate against its root certificate.
383384
- `verify-full`: Enable TLS and verify the database server name matches the given certificate in either the `Common Name` or `Subject Alternative Name` fields.
384385
- `SQLITE_TIMEOUT`: **500**: Query timeout for SQLite3 only.
386+
- `SQLITE_JOURNAL_MODE`: **""**: Change journal mode for SQlite3. Can be used to enable [WAL mode](https://www.sqlite.org/wal.html) when high load causes write congestion. See [SQlite3 docs](https://www.sqlite.org/pragma.html#pragma_journal_mode) for possible values. Defaults to the default for the database file, often DELETE.
385387
- `ITERATE_BUFFER_SIZE`: **50**: Internal buffer size for iterating.
386388
- `CHARSET`: **utf8mb4**: For MySQL only, either "utf8" or "utf8mb4". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
387389
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.

Diff for: docs/content/doc/packages/composer.en-us.md

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ curl --user your_username:your_password_or_token \
6060
https://gitea.example.com/api/packages/testuser/composer?version=1.0.3
6161
```
6262

63+
If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password.
64+
6365
The server responds with the following HTTP Status codes.
6466

6567
| HTTP Status Code | Meaning |

Diff for: docs/content/doc/packages/conan.en-us.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ conan user --remote {remote} --password {password} {username}
3737
| -----------| ----------- |
3838
| `remote` | The remote name. |
3939
| `username` | Your Gitea username. |
40-
| `password` | Your Gitea password or a personal access token. |
40+
| `password` | Your Gitea password. If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. |
4141
| `owner` | The owner of the package. |
4242

4343
For example:

Diff for: docs/content/doc/packages/container.en-us.md

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ To push an image or if the image is in a private registry, you have to authentic
3434
docker login gitea.example.com
3535
```
3636

37+
If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password.
38+
3739
## Image naming convention
3840

3941
Images must follow this naming convention:

Diff for: docs/content/doc/packages/generic.en-us.md

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ curl --user your_username:your_password_or_token \
4848
https://gitea.example.com/api/packages/testuser/generic/test_package/1.0.0/file.bin
4949
```
5050

51+
If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password.
52+
5153
The server reponds with the following HTTP Status codes.
5254

5355
| HTTP Status Code | Meaning |

Diff for: docs/content/doc/packages/helm.en-us.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ helm cm-push ./{chart_file}.tgz {repo}
4242
| Parameter | Description |
4343
| ------------ | ----------- |
4444
| `username` | Your Gitea username. |
45-
| `password` | Your Gitea password or a personal access token. |
45+
| `password` | Your Gitea password. If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. |
4646
| `repo` | The name for the repository. |
4747
| `chart_file` | The Helm Chart archive. |
4848
| `owner` | The owner of the package. |

Diff for: docs/content/doc/packages/nuget.en-us.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ dotnet nuget add source --name {source_name} --username {username} --password {p
3838
| ------------- | ----------- |
3939
| `source_name` | The desired source name. |
4040
| `username` | Your Gitea username. |
41-
| `password` | Your Gitea password or a personal access token. |
41+
| `password` | Your Gitea password. If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. |
4242
| `owner` | The owner of the package. |
4343

4444
For example:

Diff for: docs/content/doc/packages/pypi.en-us.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ password = {password}
4242
| ------------ | ----------- |
4343
| `owner` | The owner of the package. |
4444
| `username` | Your Gitea username. |
45-
| `password` | Your Gitea password or a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}). |
45+
| `password` | Your Gitea password. If you are using 2FA or OAuth use a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}) instead of the password. |
4646

4747
## Publish a package
4848

Diff for: docs/content/doc/packages/rubygems.en-us.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ https://gitea.example.com/api/packages/{owner}/rubygems: Bearer {token}
3636
| Parameter | Description |
3737
| ------------- | ----------- |
3838
| `owner` | The owner of the package. |
39-
| `token` | Your personal access token. |
39+
| `token` | Your [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}). |
4040

4141
For example:
4242

Diff for: integrations/mirror_push_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"testing"
1414

1515
"code.gitea.io/gitea/models"
16+
"code.gitea.io/gitea/models/db"
1617
repo_model "code.gitea.io/gitea/models/repo"
1718
"code.gitea.io/gitea/models/unittest"
1819
user_model "code.gitea.io/gitea/models/user"
@@ -47,7 +48,7 @@ func testMirrorPush(t *testing.T, u *url.URL) {
4748

4849
doCreatePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword)(t)
4950

50-
mirrors, err := repo_model.GetPushMirrorsByRepoID(srcRepo.ID)
51+
mirrors, _, err := repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{})
5152
assert.NoError(t, err)
5253
assert.Len(t, mirrors, 1)
5354

@@ -72,7 +73,7 @@ func testMirrorPush(t *testing.T, u *url.URL) {
7273

7374
// Cleanup
7475
doRemovePushMirror(ctx, fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(ctx.Username), url.PathEscape(mirrorRepo.Name)), user.LowerName, userPassword, int(mirrors[0].ID))(t)
75-
mirrors, err = repo_model.GetPushMirrorsByRepoID(srcRepo.ID)
76+
mirrors, _, err = repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{})
7677
assert.NoError(t, err)
7778
assert.Len(t, mirrors, 0)
7879
}

Diff for: models/auth/webauthn.go

+8-10
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package auth
66

77
import (
88
"context"
9-
"encoding/base32"
109
"fmt"
1110
"strings"
1211

@@ -20,14 +19,14 @@ import (
2019
// ErrWebAuthnCredentialNotExist represents a "ErrWebAuthnCRedentialNotExist" kind of error.
2120
type ErrWebAuthnCredentialNotExist struct {
2221
ID int64
23-
CredentialID string
22+
CredentialID []byte
2423
}
2524

2625
func (err ErrWebAuthnCredentialNotExist) Error() string {
27-
if err.CredentialID == "" {
26+
if len(err.CredentialID) == 0 {
2827
return fmt.Sprintf("WebAuthn credential does not exist [id: %d]", err.ID)
2928
}
30-
return fmt.Sprintf("WebAuthn credential does not exist [credential_id: %s]", err.CredentialID)
29+
return fmt.Sprintf("WebAuthn credential does not exist [credential_id: %x]", err.CredentialID)
3130
}
3231

3332
// IsErrWebAuthnCredentialNotExist checks if an error is a ErrWebAuthnCredentialNotExist.
@@ -43,7 +42,7 @@ type WebAuthnCredential struct {
4342
Name string
4443
LowerName string `xorm:"unique(s)"`
4544
UserID int64 `xorm:"INDEX unique(s)"`
46-
CredentialID string `xorm:"INDEX VARCHAR(410)"`
45+
CredentialID []byte `xorm:"INDEX VARBINARY(1024)"`
4746
PublicKey []byte
4847
AttestationType string
4948
AAGUID []byte
@@ -94,9 +93,8 @@ type WebAuthnCredentialList []*WebAuthnCredential
9493
func (list WebAuthnCredentialList) ToCredentials() []webauthn.Credential {
9594
creds := make([]webauthn.Credential, 0, len(list))
9695
for _, cred := range list {
97-
credID, _ := base32.HexEncoding.DecodeString(cred.CredentialID)
9896
creds = append(creds, webauthn.Credential{
99-
ID: credID,
97+
ID: cred.CredentialID,
10098
PublicKey: cred.PublicKey,
10199
AttestationType: cred.AttestationType,
102100
Authenticator: webauthn.Authenticator{
@@ -164,11 +162,11 @@ func HasWebAuthnRegistrationsByUID(uid int64) (bool, error) {
164162
}
165163

166164
// GetWebAuthnCredentialByCredID returns WebAuthn credential by credential ID
167-
func GetWebAuthnCredentialByCredID(userID int64, credID string) (*WebAuthnCredential, error) {
165+
func GetWebAuthnCredentialByCredID(userID int64, credID []byte) (*WebAuthnCredential, error) {
168166
return getWebAuthnCredentialByCredID(db.DefaultContext, userID, credID)
169167
}
170168

171-
func getWebAuthnCredentialByCredID(ctx context.Context, userID int64, credID string) (*WebAuthnCredential, error) {
169+
func getWebAuthnCredentialByCredID(ctx context.Context, userID int64, credID []byte) (*WebAuthnCredential, error) {
172170
cred := new(WebAuthnCredential)
173171
if found, err := db.GetEngine(ctx).Where("user_id = ? AND credential_id = ?", userID, credID).Get(cred); err != nil {
174172
return nil, err
@@ -187,7 +185,7 @@ func createCredential(ctx context.Context, userID int64, name string, cred *weba
187185
c := &WebAuthnCredential{
188186
UserID: userID,
189187
Name: name,
190-
CredentialID: base32.HexEncoding.EncodeToString(cred.ID),
188+
CredentialID: cred.ID,
191189
PublicKey: cred.PublicKey,
192190
AttestationType: cred.AttestationType,
193191
AAGUID: cred.Authenticator.AAGUID,

Diff for: models/auth/webauthn_test.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package auth
66

77
import (
8-
"encoding/base32"
98
"testing"
109

1110
"code.gitea.io/gitea/models/unittest"
@@ -61,9 +60,7 @@ func TestCreateCredential(t *testing.T) {
6160
res, err := CreateCredential(1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")})
6261
assert.NoError(t, err)
6362
assert.Equal(t, "WebAuthn Created Credential", res.Name)
64-
bs, err := base32.HexEncoding.DecodeString(res.CredentialID)
65-
assert.NoError(t, err)
66-
assert.Equal(t, []byte("Test"), bs)
63+
assert.Equal(t, []byte("Test"), res.CredentialID)
6764

6865
unittest.AssertExistsIf(t, true, &WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1})
6966
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-
2+
id: 1
3+
credential_id: "TVHE44TOH7DF7V48SEAIT3EMMJ7TGBOQ289E5AQB34S98LFCUFJ7U2NAVI8RJG6K2F4TC8AQ8KBNO7AGEOQOL9NE43GR63HTEHJSLOG="
4+
-
5+
id: 2
6+
credential_id: "051CLMMKB62S6M9M2A4H54K7MMCQALFJ36G4TGB2S9A47APLTILU6C6744CEBG4EKCGV357N21BSLH8JD33GQMFAR6DQ70S76P34J6FR="
7+
-
8+
id: 4
9+
credential_id: "APU4B1NDTEVTEM60V4T0FRL7SRJMO9KIE2AKFQ8JDGTQ7VHFI41FDEFTDLBVQEAE4ER49QV2GTGVFDNBO31BPOA3OQN6879OT6MTU3G="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
-
2+
id: 1
3+
lower_name: "u2fkey-correctly-migrated"
4+
name: "u2fkey-correctly-migrated"
5+
user_id: 1
6+
credential_id: "TVHE44TOH7DF7V48SEAIT3EMMJ7TGBOQ289E5AQB34S98LFCUFJ7U2NAVI8RJG6K2F4TC8AQ8KBNO7AGEOQOL9NE43GR63HTEHJSLOG="
7+
public_key: 0x040d0967a2cad045011631187576492a0beb5b377954b4f694c5afc8bdf25270f87f09a9ab6ce9c282f447ba71b2f2bae2105b32b847e0704f310f48644e3eddf2
8+
attestation_type: 'fido-u2f'
9+
sign_count: 1
10+
clone_warning: false
11+
-
12+
id: 2
13+
lower_name: "non-u2f-key"
14+
name: "non-u2f-key"
15+
user_id: 1
16+
credential_id: "051CLMMKB62S6M9M2A4H54K7MMCQALFJ36G4TGB2S9A47APLTILU6C6744CEBG4EKCGV357N21BSLH8JD33GQMFAR6DQ70S76P34J6FR"
17+
public_key: 0x040d0967a2cad045011631187576492a0beb5b377954b4f694c5afc8bdf25270f87f09a9ab6ce9c282f447ba71b2f2bae2105b32b847e0704f310f48644e3eddf2
18+
attestation_type: 'none'
19+
sign_count: 1
20+
clone_warning: false
21+
-
22+
id: 4
23+
lower_name: "packed-key"
24+
name: "packed-key"
25+
user_id: 1
26+
credential_id: "APU4B1NDTEVTEM60V4T0FRL7SRJMO9KIE2AKFQ8JDGTQ7VHFI41FDEFTDLBVQEAE4ER49QV2GTGVFDNBO31BPOA3OQN6879OT6MTU3G="
27+
public_key: 0x040d0967a2cad045011631187576492a0beb5b377954b4f694c5afc8bdf25270f87f09a9ab6ce9c282f447ba71b2f2bae2105b32b847e0704f310f48644e3eddf2
28+
attestation_type: 'fido-u2f'
29+
sign_count: 1
30+
clone_warning: false
31+

Diff for: models/migrations/migrations.go

+6
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,12 @@ var migrations = []Migration{
400400
NewMigration("Add sync_on_commit column to push_mirror table", addSyncOnCommitColForPushMirror),
401401
// v220 -> v221
402402
NewMigration("Add container repository property", addContainerRepositoryProperty),
403+
// v221 -> v222
404+
NewMigration("Store WebAuthentication CredentialID as bytes and increase size to at least 1024", storeWebauthnCredentialIDAsBytes),
405+
// v222 -> v223
406+
NewMigration("Drop old CredentialID column", dropOldCredentialIDColumn),
407+
// v223 -> v224
408+
NewMigration("Rename CredentialIDBytes column to CredentialID", renameCredentialIDBytes),
403409
}
404410

405411
// GetCurrentDBVersion returns the current db version

Diff for: models/migrations/v221.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"encoding/base32"
9+
"fmt"
10+
11+
"code.gitea.io/gitea/modules/timeutil"
12+
13+
"xorm.io/xorm"
14+
)
15+
16+
func storeWebauthnCredentialIDAsBytes(x *xorm.Engine) error {
17+
// Create webauthnCredential table
18+
type webauthnCredential struct {
19+
ID int64 `xorm:"pk autoincr"`
20+
Name string
21+
LowerName string `xorm:"unique(s)"`
22+
UserID int64 `xorm:"INDEX unique(s)"`
23+
CredentialID string `xorm:"INDEX VARCHAR(410)"`
24+
// Note the lack of INDEX here - these will be created once the column is renamed in v223.go
25+
CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
26+
PublicKey []byte
27+
AttestationType string
28+
AAGUID []byte
29+
SignCount uint32 `xorm:"BIGINT"`
30+
CloneWarning bool
31+
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
32+
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
33+
}
34+
if err := x.Sync2(&webauthnCredential{}); err != nil {
35+
return err
36+
}
37+
38+
var start int
39+
creds := make([]*webauthnCredential, 0, 50)
40+
for {
41+
err := x.Select("id, credential_id").OrderBy("id").Limit(50, start).Find(&creds)
42+
if err != nil {
43+
return err
44+
}
45+
46+
err = func() error {
47+
sess := x.NewSession()
48+
defer sess.Close()
49+
if err := sess.Begin(); err != nil {
50+
return fmt.Errorf("unable to allow start session. Error: %w", err)
51+
}
52+
for _, cred := range creds {
53+
cred.CredentialIDBytes, err = base32.HexEncoding.DecodeString(cred.CredentialID)
54+
if err != nil {
55+
return fmt.Errorf("unable to parse credential id %s for credential[%d]: %w", cred.CredentialID, cred.ID, err)
56+
}
57+
count, err := sess.ID(cred.ID).Cols("credential_id_bytes").Update(cred)
58+
if count != 1 || err != nil {
59+
return fmt.Errorf("unable to update credential id bytes for credential[%d]: %d,%w", cred.ID, count, err)
60+
}
61+
}
62+
return sess.Commit()
63+
}()
64+
if err != nil {
65+
return err
66+
}
67+
68+
if len(creds) < 50 {
69+
break
70+
}
71+
start += 50
72+
creds = creds[:0]
73+
}
74+
return nil
75+
}

0 commit comments

Comments
 (0)