diff --git a/docs/content/page/index.de-de.md b/docs/content/page/index.de-de.md index 8f8f264ed1..3b344db144 100644 --- a/docs/content/page/index.de-de.md +++ b/docs/content/page/index.de-de.md @@ -1,5 +1,5 @@ --- -date: "2016-11-08T16:00:00+02:00" +date: "2023-01-07T22:03:00+01:00" title: "Dokumentation" slug: "documentation" url: "/de-de/" @@ -27,11 +27,11 @@ Gitea ist ein [Gogs](http://gogs.io)-Fork. * 2 CPU Kerne und 1GB RAM sind für kleine Teams/Projekte ausreichend. * Gitea sollte unter einem seperaten nicht-root Account auf UNIX-Systemen ausgeführt werden. * Achtung: Gitea verwaltet die `~/.ssh/authorized_keys` Datei. Gitea unter einem normalen Benutzer auszuführen könnte dazu führen, dass dieser sich nicht mehr anmelden kann. -* [Git](https://git-scm.com/) Version 2.0 oder später wird benötigt. - * Wenn git >= 2.1.2. und [Git large file storage](https://git-lfs.github.com/) aktiviert ist, dann wird es auch in Gitea verwendbar sein. - * Wenn git >= 2.18, dann wird das Rendern von Commit-Graphen automatisch aktiviert. +* [Git](https://git-scm.com/) Version 2.0 oder aktueller wird benötigt. + * Wenn Git >= 2.1.2 und [Git LFS](https://git-lfs.github.com/) vorhanden ist, dann wird Git LFS Support automatisch für Gitea aktiviert. + * Wenn Git >= 2.18, dann wird das Rendern von Commit-Graphen automatisch aktiviert. ## Browser Unterstützung -* Letzten 2 Versions von Chrome, Firefox, Safari und Edge +* Die neuesten zwei Versionen von Chrome, Firefox, Safari und Edge * Firefox ESR diff --git a/models/db/context.go b/models/db/context.go index 455f3d1c5d..911dbd1c6f 100644 --- a/models/db/context.go +++ b/models/db/context.go @@ -98,19 +98,31 @@ type Committer interface { // halfCommitter is a wrapper of Committer. // It can be closed early, but can't be committed early, it is useful for reusing a transaction. type halfCommitter struct { - Committer + committer Committer + committed bool } -func (*halfCommitter) Commit() error { - // do nothing +func (c *halfCommitter) Commit() error { + c.committed = true + // should do nothing, and the parent committer will commit later return nil } +func (c *halfCommitter) Close() error { + if c.committed { + // it's "commit and close", should do nothing, and the parent committer will commit later + return nil + } + + // it's "rollback and close", let the parent committer rollback right now + return c.committer.Close() +} + // TxContext represents a transaction Context, // it will reuse the existing transaction in the parent context or create a new one. func TxContext(parentCtx context.Context) (*Context, Committer, error) { if sess, ok := inTransaction(parentCtx); ok { - return newContext(parentCtx, sess, true), &halfCommitter{Committer: sess}, nil + return newContext(parentCtx, sess, true), &halfCommitter{committer: sess}, nil } sess := x.NewSession() @@ -126,7 +138,12 @@ func TxContext(parentCtx context.Context) (*Context, Committer, error) { // this function will reuse it otherwise will create a new one and close it when finished. func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error { if sess, ok := inTransaction(parentCtx); ok { - return f(newContext(parentCtx, sess, true)) + err := f(newContext(parentCtx, sess, true)) + if err != nil { + // rollback immediately, in case the caller ignores returned error and tries to commit the transaction. + _ = sess.Close() + } + return err } return txWithNoCheck(parentCtx, f) } diff --git a/models/db/context_committer_test.go b/models/db/context_committer_test.go new file mode 100644 index 0000000000..38e91f22ed --- /dev/null +++ b/models/db/context_committer_test.go @@ -0,0 +1,102 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package db // it's not db_test, because this file is for testing the private type halfCommitter + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +type MockCommitter struct { + wants []string + gots []string +} + +func NewMockCommitter(wants ...string) *MockCommitter { + return &MockCommitter{ + wants: wants, + } +} + +func (c *MockCommitter) Commit() error { + c.gots = append(c.gots, "commit") + return nil +} + +func (c *MockCommitter) Close() error { + c.gots = append(c.gots, "close") + return nil +} + +func (c *MockCommitter) Assert(t *testing.T) { + assert.Equal(t, c.wants, c.gots, "want operations %v, but got %v", c.wants, c.gots) +} + +func Test_halfCommitter(t *testing.T) { + /* + Do something like: + + ctx, committer, err := db.TxContext(db.DefaultContext) + if err != nil { + return nil + } + defer committer.Close() + + // ... + + if err != nil { + return nil + } + + // ... + + return committer.Commit() + */ + + testWithCommitter := func(committer Committer, f func(committer Committer) error) { + if err := f(&halfCommitter{committer: committer}); err == nil { + committer.Commit() + } + committer.Close() + } + + t.Run("commit and close", func(t *testing.T) { + mockCommitter := NewMockCommitter("commit", "close") + + testWithCommitter(mockCommitter, func(committer Committer) error { + defer committer.Close() + return committer.Commit() + }) + + mockCommitter.Assert(t) + }) + + t.Run("rollback and close", func(t *testing.T) { + mockCommitter := NewMockCommitter("close", "close") + + testWithCommitter(mockCommitter, func(committer Committer) error { + defer committer.Close() + if true { + return fmt.Errorf("error") + } + return committer.Commit() + }) + + mockCommitter.Assert(t) + }) + + t.Run("close and commit", func(t *testing.T) { + mockCommitter := NewMockCommitter("close", "close") + + testWithCommitter(mockCommitter, func(committer Committer) error { + committer.Close() + committer.Commit() + return fmt.Errorf("error") + }) + + mockCommitter.Assert(t) + }) +} diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go index 7324328ee3..e7cc812eef 100644 --- a/modules/setting/mailer.go +++ b/modules/setting/mailer.go @@ -178,14 +178,25 @@ func newMailService() { // we want to warn if users use SMTP on a non-local IP; // we might as well take the opportunity to check that it has an IP at all - ips := tryResolveAddr(MailService.SMTPAddr) - if MailService.Protocol == "smtp" { - for _, ip := range ips { - if !ip.IsLoopback() { - log.Warn("connecting over insecure SMTP protocol to non-local address is not recommended") - break + // This check is not needed for sendmail + switch MailService.Protocol { + case "sendmail": + var err error + MailService.SendmailArgs, err = shellquote.Split(sec.Key("SENDMAIL_ARGS").String()) + if err != nil { + log.Error("Failed to parse Sendmail args: '%s' with error %v", sec.Key("SENDMAIL_ARGS").String(), err) + } + case "smtp", "smtps", "smtp+starttls", "smtp+unix": + ips := tryResolveAddr(MailService.SMTPAddr) + if MailService.Protocol == "smtp" { + for _, ip := range ips { + if !ip.IsLoopback() { + log.Warn("connecting over insecure SMTP protocol to non-local address is not recommended") + break + } } } + case "dummy": // just mention and do nothing } if MailService.From != "" { @@ -214,14 +225,6 @@ func newMailService() { MailService.EnvelopeFrom = parsed.Address } - if MailService.Protocol == "sendmail" { - var err error - MailService.SendmailArgs, err = shellquote.Split(sec.Key("SENDMAIL_ARGS").String()) - if err != nil { - log.Error("Failed to parse Sendmail args: %s with error %v", CustomConf, err) - } - } - log.Info("Mail Service Enabled") } diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 4fc61cf369..3c4670e418 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -77,6 +77,7 @@ {{else if .IsSigned}}
+ {{end}} diff --git a/tools/fuzz_test.go b/tests/fuzz/fuzz_test.go similarity index 98% rename from tools/fuzz_test.go rename to tests/fuzz/fuzz_test.go index 106ed19a42..6a7d9d2d32 100644 --- a/tools/fuzz_test.go +++ b/tests/fuzz/fuzz_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package main +package fuzz import ( "bytes" diff --git a/web_src/js/features/stopwatch.js b/web_src/js/features/stopwatch.js index b9042fae4c..33915a1d83 100644 --- a/web_src/js/features/stopwatch.js +++ b/web_src/js/features/stopwatch.js @@ -24,6 +24,7 @@ export function initStopwatch() { trigger: 'click', maxWidth: 'none', interactive: true, + hideOnClick: true, }); // global stop watch (in the head_navbar), it should always work in any case either the EventSource or the PeriodicPoller is used.