Skip to content

Commit

Permalink
Merge remote-tracking branch 'giteaofficial/main'
Browse files Browse the repository at this point in the history
* giteaofficial/main:
  Fix git empty check and HEAD request (go-gitea#33690)
  Fix some user name usages (go-gitea#33689)
  Try to fix ACME path when renew (go-gitea#33668)
  [skip ci] Updated translations via Crowdin
  Improve Open-with URL encoding (go-gitea#33666)
  Fix for Maven Package Naming Convention Handling (go-gitea#33678)
  Improve swagger generation (go-gitea#33664)
  Deleting repository should unlink all related packages (go-gitea#33653)
  • Loading branch information
zjjhot committed Feb 24, 2025
2 parents 681ec25 + 56a0a9c commit debdd78
Show file tree
Hide file tree
Showing 25 changed files with 272 additions and 157 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ insert_final_newline = false

[templates/swagger/v1_json.tmpl]
indent_style = space
insert_final_newline = false

[templates/user/auth/oidc_wellknown.tmpl]
indent_style = space
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/files-changed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ jobs:
swagger:
- "templates/swagger/v1_json.tmpl"
- "templates/swagger/v1_input.json"
- "Makefile"
- "package.json"
- "package-lock.json"
Expand Down
17 changes: 8 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,8 @@ ifdef DEPS_PLAYWRIGHT
endif

SWAGGER_SPEC := templates/swagger/v1_json.tmpl
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape}}/api/v1"|g
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape}}/api/v1"|"basePath": "/api/v1"|g
SWAGGER_SPEC_INPUT := templates/swagger/v1_input.json
SWAGGER_EXCLUDE := code.gitea.io/sdk
SWAGGER_NEWLINE_COMMAND := -e '$$a\'

TEST_MYSQL_HOST ?= mysql:3306
TEST_MYSQL_DBNAME ?= testgitea
Expand Down Expand Up @@ -271,10 +269,8 @@ endif
.PHONY: generate-swagger
generate-swagger: $(SWAGGER_SPEC) ## generate the swagger spec from code comments

$(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA)
$(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
$(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)'
$(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA) $(SWAGGER_SPEC_INPUT)
$(GO) run $(SWAGGER_PACKAGE) generate spec --exclude "$(SWAGGER_EXCLUDE)" --input "$(SWAGGER_SPEC_INPUT)" --output './$(SWAGGER_SPEC)'

.PHONY: swagger-check
swagger-check: generate-swagger
Expand All @@ -287,9 +283,11 @@ swagger-check: generate-swagger

.PHONY: swagger-validate
swagger-validate: ## check if the swagger spec is valid
$(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)'
@# swagger "validate" requires that the "basePath" must start with a slash, but we are using Golang template "{{...}}"
@$(SED_INPLACE) -E -e 's|"basePath":( *)"(.*)"|"basePath":\1"/\2"|g' './$(SWAGGER_SPEC)' # add a prefix slash to basePath
@# FIXME: there are some warnings
$(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
@$(SED_INPLACE) -E -e 's|"basePath":( *)"/(.*)"|"basePath":\1"\2"|g' './$(SWAGGER_SPEC)' # remove the prefix slash from basePath

.PHONY: checks
checks: checks-frontend checks-backend ## run various consistency checks
Expand Down Expand Up @@ -380,6 +378,7 @@ lint-go-gopls: ## lint go files with gopls

.PHONY: lint-editorconfig
lint-editorconfig:
@echo "Running editorconfig check..."
@$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) $(EDITORCONFIG_FILES)

.PHONY: lint-actions
Expand Down
16 changes: 10 additions & 6 deletions cmd/web_acme.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ func runACME(listenAddr string, m http.Handler) error {
altTLSALPNPort = p
}

// FIXME: this path is not right, it uses "AppWorkPath" incorrectly, and writes the data into "AppWorkPath/https"
// Ideally it should migrate to AppDataPath write to "AppDataPath/https"
certmagic.Default.Storage = &certmagic.FileStorage{Path: setting.AcmeLiveDirectory}
magic := certmagic.NewDefault()
// Try to use private CA root if provided, otherwise defaults to system's trust
var certPool *x509.CertPool
if setting.AcmeCARoot != "" {
Expand All @@ -67,7 +63,13 @@ func runACME(listenAddr string, m http.Handler) error {
log.Warn("Failed to parse CA Root certificate, using default CA trust: %v", err)
}
}
myACME := certmagic.NewACMEIssuer(magic, certmagic.ACMEIssuer{
// FIXME: this path is not right, it uses "AppWorkPath" incorrectly, and writes the data into "AppWorkPath/https"
// Ideally it should migrate to AppDataPath write to "AppDataPath/https"
// And one more thing, no idea why we should set the global default variables here
// But it seems that the current ACME code needs these global variables to make renew work.
// Otherwise, "renew" will use incorrect storage path
certmagic.Default.Storage = &certmagic.FileStorage{Path: setting.AcmeLiveDirectory}
certmagic.DefaultACME = certmagic.ACMEIssuer{
CA: setting.AcmeURL,
TrustedRoots: certPool,
Email: setting.AcmeEmail,
Expand All @@ -77,8 +79,10 @@ func runACME(listenAddr string, m http.Handler) error {
ListenHost: setting.HTTPAddr,
AltTLSALPNPort: altTLSALPNPort,
AltHTTPPort: altHTTPPort,
})
}

magic := certmagic.NewDefault()
myACME := certmagic.NewACMEIssuer(magic, certmagic.DefaultACME)
magic.Issuers = []certmagic.Issuer{myACME}

// this obtains certificates or renews them if necessary
Expand Down
1 change: 1 addition & 0 deletions models/organization/org_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func GetUserOrgsList(ctx context.Context, user *user_model.User) ([]*MinimalOrg,
if err := db.GetEngine(ctx).Select(columnsStr).
Table("user").
Where(builder.In("`user`.`id`", queryUserOrgIDs(user.ID, true))).
OrderBy("`user`.lower_name ASC").
Find(&orgs); err != nil {
return nil, err
}
Expand Down
5 changes: 3 additions & 2 deletions models/repo/user_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package repo

import (
"context"
"strings"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
Expand Down Expand Up @@ -149,9 +150,9 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
// If isShowFullName is set to true, also include full name prefix search
func GetIssuePostersWithSearch(ctx context.Context, repo *Repository, isPull bool, search string, isShowFullName bool) ([]*user_model.User, error) {
users := make([]*user_model.User, 0, 30)
var prefixCond builder.Cond = builder.Like{"name", search + "%"}
var prefixCond builder.Cond = builder.Like{"lower_name", strings.ToLower(search) + "%"}
if isShowFullName {
prefixCond = prefixCond.Or(builder.Like{"full_name", "%" + search + "%"})
prefixCond = prefixCond.Or(db.BuildCaseInsensitiveLike("full_name", "%"+search+"%"))
}

cond := builder.In("`user`.id",
Expand Down
17 changes: 17 additions & 0 deletions models/repo/user_repo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
user_model "code.gitea.io/gitea/models/user"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestRepoAssignees(t *testing.T) {
Expand All @@ -38,3 +39,19 @@ func TestRepoAssignees(t *testing.T) {
assert.NotContains(t, []int64{users[0].ID, users[1].ID, users[2].ID}, 15)
}
}

func TestGetIssuePostersWithSearch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())

repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})

users, err := repo_model.GetIssuePostersWithSearch(db.DefaultContext, repo2, false, "USER", false /* full name */)
require.NoError(t, err)
require.Len(t, users, 1)
assert.Equal(t, "user2", users[0].Name)

users, err = repo_model.GetIssuePostersWithSearch(db.DefaultContext, repo2, false, "TW%O", true /* full name */)
require.NoError(t, err)
require.Len(t, users, 1)
assert.Equal(t, "user2", users[0].Name)
}
25 changes: 16 additions & 9 deletions modules/setting/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,20 +169,24 @@ func loadServerFrom(rootCfg ConfigProvider) {
HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
HTTPPort = sec.Key("HTTP_PORT").MustString("3000")

// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version
// if these are removed, the warning will not be shown
if sec.HasKey("ENABLE_ACME") {
EnableAcme = sec.Key("ENABLE_ACME").MustBool(false)
} else {
deprecatedSetting(rootCfg, "server", "ENABLE_LETSENCRYPT", "server", "ENABLE_ACME", "v1.19.0")
EnableAcme = sec.Key("ENABLE_LETSENCRYPT").MustBool(false)
}

Protocol = HTTP
protocolCfg := sec.Key("PROTOCOL").String()
if protocolCfg != "https" && EnableAcme {
log.Fatal("ACME could only be used with HTTPS protocol")
}

switch protocolCfg {
case "https":
Protocol = HTTPS

// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version
// if these are removed, the warning will not be shown
if sec.HasKey("ENABLE_ACME") {
EnableAcme = sec.Key("ENABLE_ACME").MustBool(false)
} else {
deprecatedSetting(rootCfg, "server", "ENABLE_LETSENCRYPT", "server", "ENABLE_ACME", "v1.19.0")
EnableAcme = sec.Key("ENABLE_LETSENCRYPT").MustBool(false)
}
if EnableAcme {
AcmeURL = sec.Key("ACME_URL").MustString("")
AcmeCARoot = sec.Key("ACME_CA_ROOT").MustString("")
Expand Down Expand Up @@ -210,6 +214,9 @@ func loadServerFrom(rootCfg ConfigProvider) {
deprecatedSetting(rootCfg, "server", "LETSENCRYPT_EMAIL", "server", "ACME_EMAIL", "v1.19.0")
AcmeEmail = sec.Key("LETSENCRYPT_EMAIL").MustString("")
}
if AcmeEmail == "" {
log.Fatal("ACME Email is not set (ACME_EMAIL).")
}
} else {
CertFile = sec.Key("CERT_FILE").String()
KeyFile = sec.Key("KEY_FILE").String()
Expand Down
20 changes: 20 additions & 0 deletions options/locale/locale_ja-JP.ini
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,12 @@ show_only_public=公開のみ表示

issues.in_your_repos=あなたのリポジトリ

guide_title=アクティビティはありません
guide_desc=現在フォロー中のリポジトリやユーザーがないため、表示するコンテンツがありません。 以下のリンクから、興味のあるリポジトリやユーザーを探すことができます。
explore_repos=リポジトリを探す
explore_users=ユーザーを探す
empty_org=組織はまだありません。
empty_repo=リポジトリはまだありません。

[explore]
repos=リポジトリ
Expand Down Expand Up @@ -1348,6 +1354,8 @@ editor.new_branch_name_desc=新しいブランチ名…
editor.cancel=キャンセル
editor.filename_cannot_be_empty=ファイル名は空にできません。
editor.filename_is_invalid=`ファイル名が不正です: "%s"`
editor.commit_email=コミット メールアドレス
editor.invalid_commit_email=コミットに使うメールアドレスが正しくありません。
editor.branch_does_not_exist=このリポジトリにブランチ "%s" は存在しません。
editor.branch_already_exists=ブランチ "%s" は、このリポジトリに既に存在します。
editor.directory_is_a_file=ディレクトリ名 "%s" はすでにリポジトリ内のファイルで使用されています。
Expand Down Expand Up @@ -1693,7 +1701,9 @@ issues.time_estimate_invalid=見積時間のフォーマットが不正です
issues.start_tracking_history=が作業を開始 %s
issues.tracker_auto_close=タイマーは、このイシューがクローズされると自動的に終了します
issues.tracking_already_started=`<a href="%s">別のイシュー</a>で既にタイムトラッキングを開始しています!`
issues.stop_tracking=タイマー終了
issues.stop_tracking_history=が <b>%[1]s</b> の作業を終了 %[2]s
issues.cancel_tracking=破棄
issues.cancel_tracking_history=`がタイムトラッキングを中止 %s`
issues.del_time=このタイムログを削除
issues.add_time_history=が作業時間 <b>%[1]s</b> を追加 %[2]s
Expand Down Expand Up @@ -2329,6 +2339,8 @@ settings.event_fork=フォーク
settings.event_fork_desc=リポジトリがフォークされたとき。
settings.event_wiki=Wiki
settings.event_wiki_desc=Wikiページが作成・名前変更・編集・削除されたとき。
settings.event_statuses=ステータス
settings.event_statuses_desc=APIによってコミットのステータスが更新されたとき。
settings.event_release=リリース
settings.event_release_desc=リポジトリでリリースが作成・更新・削除されたとき。
settings.event_push=プッシュ
Expand Down Expand Up @@ -2876,6 +2888,14 @@ view_as_role=表示: %s
view_as_public_hint=READMEを公開ユーザーとして見ています。
view_as_member_hint=READMEをこの組織のメンバーとして見ています。

worktime=作業時間
worktime.date_range_start=期間 (自)
worktime.date_range_end=期間 (至)
worktime.query=集計
worktime.time=時間
worktime.by_repositories=リポジトリ別
worktime.by_milestones=マイルストーン別
worktime.by_members=メンバー別

[admin]
maintenance=メンテナンス
Expand Down
9 changes: 3 additions & 6 deletions routers/api/packages/maven/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strings"

packages_model "code.gitea.io/gitea/models/packages"
maven_module "code.gitea.io/gitea/modules/packages/maven"
)

// MetadataResponse https://maven.apache.org/ref/3.2.5/maven-repository-metadata/repository-metadata.html
Expand All @@ -22,7 +21,7 @@ type MetadataResponse struct {
}

// pds is expected to be sorted ascending by CreatedUnix
func createMetadataResponse(pds []*packages_model.PackageDescriptor) *MetadataResponse {
func createMetadataResponse(pds []*packages_model.PackageDescriptor, groupID, artifactID string) *MetadataResponse {
var release *packages_model.PackageDescriptor

versions := make([]string, 0, len(pds))
Expand All @@ -35,11 +34,9 @@ func createMetadataResponse(pds []*packages_model.PackageDescriptor) *MetadataRe

latest := pds[len(pds)-1]

metadata := latest.Metadata.(*maven_module.Metadata)

resp := &MetadataResponse{
GroupID: metadata.GroupID,
ArtifactID: metadata.ArtifactID,
GroupID: groupID,
ArtifactID: artifactID,
Latest: latest.Version.Version,
Version: versions,
}
Expand Down
17 changes: 8 additions & 9 deletions routers/api/packages/maven/maven.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,19 @@ func handlePackageFile(ctx *context.Context, serveContent bool) {
}

func serveMavenMetadata(ctx *context.Context, params parameters) {
// /com/foo/project/maven-metadata.xml[.md5/.sha1/.sha256/.sha512]

pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, params.toInternalPackageName())
if errors.Is(err, util.ErrNotExist) {
pvs, err = packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, params.toInternalPackageNameLegacy())
}
// path pattern: /com/foo/project/maven-metadata.xml[.md5/.sha1/.sha256/.sha512]
// in case there are legacy package names ("GroupID-ArtifactID") we need to check both, new packages always use ":" as separator("GroupID:ArtifactID")
pvsLegacy, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, params.toInternalPackageNameLegacy())
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
if len(pvs) == 0 {
apiError(ctx, http.StatusNotFound, packages_model.ErrPackageNotExist)
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, params.toInternalPackageName())
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
pvs = append(pvsLegacy, pvs...)

pds, err := packages_model.GetPackageDescriptors(ctx, pvs)
if err != nil {
Expand All @@ -110,7 +109,7 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
return pds[i].Version.CreatedUnix < pds[j].Version.CreatedUnix
})

xmlMetadata, err := xml.Marshal(createMetadataResponse(pds))
xmlMetadata, err := xml.Marshal(createMetadataResponse(pds, params.GroupID, params.ArtifactID))
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
Expand Down
2 changes: 0 additions & 2 deletions routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
// This documentation describes the Gitea API.
//
// Schemes: https, http
// BasePath: /api/v1
// Version: {{AppVer | JSEscape}}
// License: MIT http://opensource.org/licenses/MIT
//
// Consumes:
Expand Down
6 changes: 4 additions & 2 deletions routers/api/v1/repo/collaborators.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package repo
import (
"errors"
"net/http"
"strings"

"code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access"
Expand Down Expand Up @@ -274,12 +275,13 @@ func GetRepoPermissions(ctx *context.APIContext) {
// "403":
// "$ref": "#/responses/forbidden"

if !ctx.Doer.IsAdmin && ctx.Doer.LoginName != ctx.PathParam("collaborator") && !ctx.IsUserRepoAdmin() {
collaboratorUsername := ctx.PathParam("collaborator")
if !ctx.Doer.IsAdmin && ctx.Doer.LowerName != strings.ToLower(collaboratorUsername) && !ctx.IsUserRepoAdmin() {
ctx.APIError(http.StatusForbidden, "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own")
return
}

collaborator, err := user_model.GetUserByName(ctx, ctx.PathParam("collaborator"))
collaborator, err := user_model.GetUserByName(ctx, collaboratorUsername)
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.APIError(http.StatusNotFound, err)
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/githttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func httpBase(ctx *context.Context) *serviceHandler {
strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") {
isPull = true
} else {
isPull = ctx.Req.Method == "GET"
isPull = ctx.Req.Method == "HEAD" || ctx.Req.Method == "GET"
}

var accessMode perm.AccessMode
Expand Down
5 changes: 5 additions & 0 deletions services/context/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,11 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ctx := GetAPIContext(req)

if ctx.Repo.Repository.IsEmpty {
ctx.APIErrorNotFound("repository is empty")
return
}

if ctx.Repo.GitRepo == nil {
ctx.APIErrorInternal(fmt.Errorf("no open git repo"))
return
Expand Down
6 changes: 6 additions & 0 deletions services/repository/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
packages_model "code.gitea.io/gitea/models/packages"
access_model "code.gitea.io/gitea/models/perm/access"
project_model "code.gitea.io/gitea/models/project"
repo_model "code.gitea.io/gitea/models/repo"
Expand Down Expand Up @@ -267,6 +268,11 @@ func DeleteRepositoryDirectly(ctx context.Context, doer *user_model.User, repoID
return err
}

// unlink packages linked to this repository
if err = packages_model.UnlinkRepositoryFromAllPackages(ctx, repoID); err != nil {
return err
}

if err = committer.Commit(); err != nil {
return err
}
Expand Down
Loading

0 comments on commit debdd78

Please sign in to comment.