Skip to content

Commit 442958d

Browse files
author
Gusted
committed
[gitea] week 2025-14 cherry pick (gitea/main -> forgejo) (go-gitea#7486)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7486 Reviewed-by: Earl Warren <[email protected]> Reviewed-by: Gusted <[email protected]>
2 parents 7861d2f + 2a1759b commit 442958d

File tree

10 files changed

+80
-23
lines changed

10 files changed

+80
-23
lines changed

cmd/admin_user_create.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package cmd
66
import (
77
"errors"
88
"fmt"
9+
"strings"
910

1011
auth_model "forgejo.org/models/auth"
1112
"forgejo.org/models/db"
@@ -61,6 +62,16 @@ var microcmdUserCreate = &cli.Command{
6162
Name: "access-token",
6263
Usage: "Generate access token for the user",
6364
},
65+
&cli.StringFlag{
66+
Name: "access-token-name",
67+
Usage: `Name of the generated access token`,
68+
Value: "gitea-admin",
69+
},
70+
&cli.StringFlag{
71+
Name: "access-token-scopes",
72+
Usage: `Scopes of the generated access token, comma separated. Examples: "all", "public-only,read:issue", "write:repository,write:user"`,
73+
Value: "all",
74+
},
6475
&cli.BoolFlag{
6576
Name: "restricted",
6677
Usage: "Make a restricted user account",
@@ -157,23 +168,40 @@ func runCreateUser(c *cli.Context) error {
157168
IsRestricted: restricted,
158169
}
159170

171+
var accessTokenName string
172+
var accessTokenScope auth_model.AccessTokenScope
173+
if c.IsSet("access-token") {
174+
accessTokenName = strings.TrimSpace(c.String("access-token-name"))
175+
if accessTokenName == "" {
176+
return errors.New("access-token-name cannot be empty")
177+
}
178+
var err error
179+
accessTokenScope, err = auth_model.AccessTokenScope(c.String("access-token-scopes")).Normalize()
180+
if err != nil {
181+
return fmt.Errorf("invalid access token scope provided: %w", err)
182+
}
183+
if !accessTokenScope.HasPermissionScope() {
184+
return errors.New("access token does not have any permission")
185+
}
186+
} else if c.IsSet("access-token-name") || c.IsSet("access-token-scopes") {
187+
return errors.New("access-token-name and access-token-scopes flags are only valid when access-token flag is set")
188+
}
189+
190+
// arguments should be prepared before creating the user & access token, in case there is anything wrong
191+
192+
// create the user
160193
if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
161194
return fmt.Errorf("CreateUser: %w", err)
162195
}
196+
fmt.Printf("New user '%s' has been successfully created!\n", username)
163197

164-
if c.Bool("access-token") {
165-
t := &auth_model.AccessToken{
166-
Name: "gitea-admin",
167-
UID: u.ID,
168-
}
169-
198+
// create the access token
199+
if accessTokenScope != "" {
200+
t := &auth_model.AccessToken{Name: accessTokenName, UID: u.ID, Scope: accessTokenScope}
170201
if err := auth_model.NewAccessToken(ctx, t); err != nil {
171202
return err
172203
}
173-
174204
fmt.Printf("Access token was successfully created... %s\n", t.Token)
175205
}
176-
177-
fmt.Printf("New user '%s' has been successfully created!\n", username)
178206
return nil
179207
}

cmd/admin_user_generate_access_token.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ var microcmdUserGenerateAccessToken = &cli.Command{
3434
},
3535
&cli.StringFlag{
3636
Name: "scopes",
37-
Value: "",
38-
Usage: "Comma separated list of scopes to apply to access token",
37+
Value: "all",
38+
Usage: `Comma separated list of scopes to apply to access token, examples: "all", "public-only,read:issue", "write:repository,write:user"`,
3939
},
4040
},
4141
Action: runGenerateAccessToken,
4242
}
4343

4444
func runGenerateAccessToken(c *cli.Context) error {
4545
if !c.IsSet("username") {
46-
return errors.New("You must provide a username to generate a token for")
46+
return errors.New("you must provide a username to generate a token for")
4747
}
4848

4949
ctx, cancel := installSignals()
@@ -77,6 +77,9 @@ func runGenerateAccessToken(c *cli.Context) error {
7777
if err != nil {
7878
return fmt.Errorf("invalid access token scope provided: %w", err)
7979
}
80+
if !accessTokenScope.HasPermissionScope() {
81+
return errors.New("access token does not have any permission")
82+
}
8083
t.Scope = accessTokenScope
8184

8285
// create the token

docker/root/etc/s6/openssh/setup

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ if [ -e /data/ssh/ssh_host_ecdsa_cert ]; then
3131
SSH_ECDSA_CERT=${SSH_ECDSA_CERT:-"/data/ssh/ssh_host_ecdsa_cert"}
3232
fi
3333

34+
if [ -e /data/ssh/ssh_host_ed25519-cert.pub ]; then
35+
SSH_ED25519_CERT=${SSH_ED25519_CERT:-"/data/ssh/ssh_host_ed25519-cert.pub"}
36+
fi
37+
38+
if [ -e /data/ssh/ssh_host_rsa-cert.pub ]; then
39+
SSH_RSA_CERT=${SSH_RSA_CERT:-"/data/ssh/ssh_host_rsa-cert.pub"}
40+
fi
41+
42+
if [ -e /data/ssh/ssh_host_ecdsa-cert.pub ]; then
43+
SSH_ECDSA_CERT=${SSH_ECDSA_CERT:-"/data/ssh/ssh_host_ecdsa-cert.pub"}
44+
fi
45+
3446
if [ -d /etc/ssh ]; then
3547
SSH_PORT=${SSH_PORT:-"22"} \
3648
SSH_LISTEN_PORT=${SSH_LISTEN_PORT:-"${SSH_PORT}"} \

models/auth/access_token_scope.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ func (s AccessTokenScope) Normalize() (AccessTokenScope, error) {
283283
return bitmap.toScope(), nil
284284
}
285285

286+
func (s AccessTokenScope) HasPermissionScope() bool {
287+
return s != "" && s != AccessTokenScopePublicOnly
288+
}
289+
286290
// PublicOnly checks if this token scope is limited to public resources
287291
func (s AccessTokenScope) PublicOnly() (bool, error) {
288292
bitmap, err := s.parse()

models/user/avatar.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func GenerateRandomAvatar(ctx context.Context, u *User) error {
6262

6363
// AvatarLinkWithSize returns a link to the user's avatar with size. size <= 0 means default size
6464
func (u *User) AvatarLinkWithSize(ctx context.Context, size int) string {
65-
if u.IsGhost() {
65+
if u.IsGhost() || u.ID <= 0 {
6666
return avatars.DefaultAvatarLink()
6767
}
6868

routers/web/user/setting/applications.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ func ApplicationsPost(ctx *context.Context) {
4949
ctx.ServerError("GetScope", err)
5050
return
5151
}
52+
if !scope.HasPermissionScope() {
53+
ctx.Flash.Error(ctx.Tr("settings.at_least_one_permission"), true)
54+
}
5255
t := &auth_model.AccessToken{
5356
UID: ctx.Doer.ID,
5457
Name: form.Name,

services/packages/rpm/repository.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,6 @@ func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs []
410410
files = append(files, f)
411411
}
412412
}
413-
packageVersion := fmt.Sprintf("%s-%s", pd.FileMetadata.Version, pd.FileMetadata.Release)
414413
packages = append(packages, &Package{
415414
Type: "rpm",
416415
Name: pd.Package.Name,
@@ -439,7 +438,7 @@ func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs []
439438
Archive: pd.FileMetadata.ArchiveSize,
440439
},
441440
Location: Location{
442-
Href: fmt.Sprintf("package/%s/%s/%s/%s-%s.%s.rpm", pd.Package.Name, packageVersion, pd.FileMetadata.Architecture, pd.Package.Name, packageVersion, pd.FileMetadata.Architecture),
441+
Href: fmt.Sprintf("package/%s/%s/%s/%s-%s.%s.rpm", pd.Package.Name, pd.Version.Version, pd.FileMetadata.Architecture, pd.Package.Name, pd.Version.Version, pd.FileMetadata.Architecture),
443442
},
444443
Format: Format{
445444
License: pd.VersionMetadata.License,

services/webhook/discord.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"unicode/utf8"
1717

1818
webhook_model "forgejo.org/models/webhook"
19+
"forgejo.org/modules/base"
1920
"forgejo.org/modules/git"
2021
"forgejo.org/modules/json"
2122
"forgejo.org/modules/log"
@@ -151,6 +152,18 @@ var (
151152
redColor = color("ff3232")
152153
)
153154

155+
// https://discord.com/developers/docs/resources/message#embed-object-embed-limits
156+
// Discord has some limits in place for the embeds.
157+
// According to some tests, there is no consistent limit for different character sets.
158+
// For example: 4096 ASCII letters are allowed, but only 2490 emoji characters are allowed.
159+
// To keep it simple, we currently truncate at 2000.
160+
const discordDescriptionCharactersLimit = 2000
161+
162+
type discordConvertor struct {
163+
Username string
164+
AvatarURL string
165+
}
166+
154167
// Create implements PayloadConvertor Create method
155168
func (d discordConvertor) Create(p *api.CreatePayload) (DiscordPayload, error) {
156169
// created tag/branch
@@ -312,11 +325,6 @@ func (d discordConvertor) Package(p *api.PackagePayload) (DiscordPayload, error)
312325
return d.createPayload(p.Sender, text, "", p.Package.HTMLURL, color), nil
313326
}
314327

315-
type discordConvertor struct {
316-
Username string
317-
AvatarURL string
318-
}
319-
320328
var _ shared.PayloadConvertor[DiscordPayload] = discordConvertor{}
321329

322330
func (discordHandler) NewRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
@@ -357,7 +365,7 @@ func (d discordConvertor) createPayload(s *api.User, title, text, url string, co
357365
Embeds: []DiscordEmbed{
358366
{
359367
Title: title,
360-
Description: text,
368+
Description: base.TruncateString(text, discordDescriptionCharactersLimit),
361369
URL: url,
362370
Color: color,
363371
Author: DiscordEmbedAuthor{

services/webhook/discord_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func TestDiscordPayload(t *testing.T) {
175175
require.NoError(t, err)
176176

177177
assert.Len(t, pl.Embeds, 1)
178-
assert.Len(t, pl.Embeds[0].Description, 4096)
178+
assert.Len(t, pl.Embeds[0].Description, 2000)
179179
})
180180

181181
t.Run("IssueComment", func(t *testing.T) {

web_src/css/markup/content.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
overflow: hidden;
33
font-size: 16px;
44
line-height: 1.5 !important;
5-
word-wrap: break-word;
5+
overflow-wrap: anywhere;
66
}
77

88
.markup > *:first-child {

0 commit comments

Comments
 (0)