mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-08 05:02:38 +09:00
Compare commits
15 Commits
v1.3.0-rc2
...
v1.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81fd8c8fb6 | ||
|
|
fd7686171e | ||
|
|
ec6718ef40 | ||
|
|
8f7054a864 | ||
|
|
84352316a9 | ||
|
|
237df2f339 | ||
|
|
b9abcb3b61 | ||
|
|
9832b9509d | ||
|
|
3d688bd2cc | ||
|
|
ce4a52c22c | ||
|
|
974cffead9 | ||
|
|
8cdd5a33cd | ||
|
|
992ee21a29 | ||
|
|
5ec9c45661 | ||
|
|
b5bdb0474a |
13
.drone.yml
13
.drone.yml
@@ -86,6 +86,19 @@ pipeline:
|
||||
event: [ push, pull_request ]
|
||||
branch: [ master ]
|
||||
|
||||
test:
|
||||
image: webhippie/golang:edge
|
||||
pull: true
|
||||
group: test
|
||||
environment:
|
||||
TAGS: bindata sqlite
|
||||
GOPATH: /srv/app
|
||||
commands:
|
||||
- make test
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
branch: [ release/* ]
|
||||
|
||||
test:
|
||||
image: webhippie/golang:edge
|
||||
pull: true
|
||||
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,15 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## [1.3.0-rc2](https://github.com/go-gitea/gitea/releases/tag/v1.3.0-rc2) - 2017-11-27
|
||||
## [1.3.1](https://github.com/go-gitea/gitea/releases/tag/v1.3.1) - 2017-12-08
|
||||
* BUGFIXES
|
||||
* Fix memcache support when value is returned as string always (#2950)
|
||||
* Update golang x/crypto dependencies - Fix SSH transport fail (#2951)
|
||||
* Fix files/commits of merged PRs (#2970)
|
||||
* Fix error when add user has full name to team (#2975)
|
||||
* Fix go-get, src and raw urls to new scheme (#2986)
|
||||
* Fix over-escaped characters (#2992)
|
||||
* Sanitize logs for mirror sync (#3057, #3082) (#3078)
|
||||
* Fix missing branch in release bug (#3108) (#3117)
|
||||
* Fix repo indexer and submodule bug (#3107) (#3110)
|
||||
* Fix legacy URL redirects (#3100) (#3106)
|
||||
* Fix redis session failed (#3086) (#3089)
|
||||
* Fix issue list branch link broken (#3061) (#3070)
|
||||
* Fix missing password length check when change password (#3039) (#3071)
|
||||
|
||||
## [1.3.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.3.0-rc1) - 2017-11-15
|
||||
## [1.3.0](https://github.com/go-gitea/gitea/releases/tag/v1.3.0) - 2017-11-29
|
||||
* BREAKING
|
||||
* Make URL scheme unambiguous (#2408)
|
||||
* FEATURE
|
||||
@@ -30,6 +31,14 @@
|
||||
* Disable custom Git Hooks globally via configuration file (#2450)
|
||||
* Sync releases table with tags on push and for mirrors (#2459)
|
||||
* BUGFIXES
|
||||
* Fix label comments for French locale (#3017)
|
||||
* Remove duplicate "Max Diff Lines" from config view (#3001)
|
||||
* Fix over-escaped characters (#2992)
|
||||
* Fix go-get, src and raw urls to new scheme (#2986)
|
||||
* Fix error when add user has full name to team (#2975)
|
||||
* Fix files/commits of merged PRs (#2970)
|
||||
* Update golang x/crypto dependencies - Fix SSH transport fail (#2951)
|
||||
* Fix memcache support when value is returned as string always (#2950)
|
||||
* Fix issue link rendering in commit messages (#2897)
|
||||
* Fix adding a new authentication source after selecting OAuth (#2889)
|
||||
* Fix new branch creation to new url scheme (#2884)
|
||||
@@ -109,6 +118,8 @@
|
||||
* Fix duplicated rel attribute (#2549)
|
||||
* Fix tests code to prevent some runtime errors (#2381)
|
||||
* ENHANCEMENT
|
||||
* Memory usage improvements and lower minimal git requirement to 1.7.2 (#3013) (#3028)
|
||||
* Set OpenID support on by default when installing new instance (#3010) (#3027)
|
||||
* Use api.TrackedTime in API (#2807)
|
||||
* Configurable SSH key exchange algorithm and MAC suite (#2806)
|
||||
* Add Safari pinned tab icon (#2799)
|
||||
|
||||
@@ -46,8 +46,10 @@ func TestRedirectsNoLogin(t *testing.T) {
|
||||
prepareTestEnv(t)
|
||||
|
||||
var redirects = map[string]string{
|
||||
"/user2/repo1/commits/master": "/user2/repo1/commits/branch/master",
|
||||
"/user2/repo1/src/master": "/user2/repo1/src/branch/master",
|
||||
"/user2/repo1/commits/master": "/user2/repo1/commits/branch/master",
|
||||
"/user2/repo1/src/master": "/user2/repo1/src/branch/master",
|
||||
"/user2/repo1/src/master/file.txt": "/user2/repo1/src/branch/master/file.txt",
|
||||
"/user2/repo1/src/master/directory/file.txt": "/user2/repo1/src/branch/master/directory/file.txt",
|
||||
}
|
||||
for link, redirectLink := range redirects {
|
||||
req := NewRequest(t, "GET", link)
|
||||
|
||||
@@ -605,9 +605,14 @@ func (repo *Repository) RepoPath() string {
|
||||
return repo.repoPath(x)
|
||||
}
|
||||
|
||||
// GitConfigPath returns the path to a repository's git config/ directory
|
||||
func GitConfigPath(repoPath string) string {
|
||||
return filepath.Join(repoPath, "config")
|
||||
}
|
||||
|
||||
// GitConfigPath returns the repository git config path
|
||||
func (repo *Repository) GitConfigPath() string {
|
||||
return filepath.Join(repo.RepoPath(), "config")
|
||||
return GitConfigPath(repo.RepoPath())
|
||||
}
|
||||
|
||||
// RelLink returns the repository relative link
|
||||
|
||||
@@ -100,10 +100,6 @@ func populateRepoIndexer() error {
|
||||
}
|
||||
}
|
||||
|
||||
type updateBatch struct {
|
||||
updates []indexer.RepoIndexerUpdate
|
||||
}
|
||||
|
||||
func updateRepoIndexer(repo *Repository) error {
|
||||
changes, err := getRepoChanges(repo)
|
||||
if err != nil {
|
||||
@@ -163,6 +159,10 @@ func addUpdate(filename string, repo *Repository, batch *indexer.Batch) error {
|
||||
return err
|
||||
} else if stat.Size() > setting.Indexer.MaxIndexerFileSize {
|
||||
return nil
|
||||
} else if stat.IsDir() {
|
||||
// file could actually be a directory, if it is the root of a submodule.
|
||||
// We do not index submodule contents, so don't do anything.
|
||||
return nil
|
||||
}
|
||||
fileContents, err := ioutil.ReadFile(filepath)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,18 +6,18 @@ package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-xorm/xorm"
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"code.gitea.io/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/process"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/sync"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-xorm/xorm"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
// MirrorQueue holds an UniqueQueue object of the mirror
|
||||
@@ -76,41 +76,41 @@ func (m *Mirror) ScheduleNextUpdate() {
|
||||
m.NextUpdate = time.Now().Add(m.Interval)
|
||||
}
|
||||
|
||||
func remoteAddress(repoPath string) (string, error) {
|
||||
cfg, err := ini.Load(GitConfigPath(repoPath))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return cfg.Section("remote \"origin\"").Key("url").Value(), nil
|
||||
}
|
||||
|
||||
func (m *Mirror) readAddress() {
|
||||
if len(m.address) > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
cfg, err := ini.Load(m.Repo.GitConfigPath())
|
||||
var err error
|
||||
m.address, err = remoteAddress(m.Repo.RepoPath())
|
||||
if err != nil {
|
||||
log.Error(4, "Load: %v", err)
|
||||
return
|
||||
log.Error(4, "remoteAddress: %v", err)
|
||||
}
|
||||
m.address = cfg.Section("remote \"origin\"").Key("url").Value()
|
||||
}
|
||||
|
||||
// HandleCloneUserCredentials replaces user credentials from HTTP/HTTPS URL
|
||||
// with placeholder <credentials>.
|
||||
// It will fail for any other forms of clone addresses.
|
||||
func HandleCloneUserCredentials(url string, mosaics bool) string {
|
||||
i := strings.Index(url, "@")
|
||||
if i == -1 {
|
||||
return url
|
||||
// sanitizeOutput sanitizes output of a command, replacing occurrences of the
|
||||
// repository's remote address with a sanitized version.
|
||||
func sanitizeOutput(output, repoPath string) (string, error) {
|
||||
remoteAddr, err := remoteAddress(repoPath)
|
||||
if err != nil {
|
||||
// if we're unable to load the remote address, then we're unable to
|
||||
// sanitize.
|
||||
return "", err
|
||||
}
|
||||
start := strings.Index(url, "://")
|
||||
if start == -1 {
|
||||
return url
|
||||
}
|
||||
if mosaics {
|
||||
return url[:start+3] + "<credentials>" + url[i:]
|
||||
}
|
||||
return url[:start+3] + url[i+1:]
|
||||
return util.SanitizeMessage(output, remoteAddr), nil
|
||||
}
|
||||
|
||||
// Address returns mirror address from Git repository config without credentials.
|
||||
func (m *Mirror) Address() string {
|
||||
m.readAddress()
|
||||
return HandleCloneUserCredentials(m.address, false)
|
||||
return util.SanitizeURLCredentials(m.address, false)
|
||||
}
|
||||
|
||||
// FullAddress returns mirror address from Git repository config.
|
||||
@@ -145,7 +145,14 @@ func (m *Mirror) runSync() bool {
|
||||
if _, stderr, err := process.GetManager().ExecDir(
|
||||
timeout, repoPath, fmt.Sprintf("Mirror.runSync: %s", repoPath),
|
||||
"git", gitArgs...); err != nil {
|
||||
desc := fmt.Sprintf("Failed to update mirror repository '%s': %s", repoPath, stderr)
|
||||
// sanitize the output, since it may contain the remote address, which may
|
||||
// contain a password
|
||||
message, err := sanitizeOutput(stderr, repoPath)
|
||||
if err != nil {
|
||||
log.Error(4, "sanitizeOutput: %v", err)
|
||||
return false
|
||||
}
|
||||
desc := fmt.Sprintf("Failed to update mirror repository '%s': %s", repoPath, message)
|
||||
log.Error(4, desc)
|
||||
if err = CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error(4, "CreateRepositoryNotice: %v", err)
|
||||
@@ -170,7 +177,14 @@ func (m *Mirror) runSync() bool {
|
||||
if _, stderr, err := process.GetManager().ExecDir(
|
||||
timeout, wikiPath, fmt.Sprintf("Mirror.runSync: %s", wikiPath),
|
||||
"git", "remote", "update", "--prune"); err != nil {
|
||||
desc := fmt.Sprintf("Failed to update mirror wiki repository '%s': %s", wikiPath, stderr)
|
||||
// sanitize the output, since it may contain the remote address, which may
|
||||
// contain a password
|
||||
message, err := sanitizeOutput(stderr, wikiPath)
|
||||
if err != nil {
|
||||
log.Error(4, "sanitizeOutput: %v", err)
|
||||
return false
|
||||
}
|
||||
desc := fmt.Sprintf("Failed to update mirror wiki repository '%s': %s", wikiPath, message)
|
||||
log.Error(4, desc)
|
||||
if err = CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error(4, "CreateRepositoryNotice: %v", err)
|
||||
|
||||
@@ -143,6 +143,9 @@ func (r *Repository) GetEditorconfig() (*editorconfig.Editorconfig, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if treeEntry.Blob().Size() >= setting.UI.MaxDisplayFileSize {
|
||||
return nil, git.ErrNotExist{ID: "", RelPath: ".editorconfig"}
|
||||
}
|
||||
reader, err := treeEntry.Blob().Data()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -615,7 +618,11 @@ func RepoRefByType(refType RepoRefType) macaron.Handler {
|
||||
|
||||
if refType == RepoRefLegacy {
|
||||
// redirect from old URL scheme to new URL scheme
|
||||
ctx.Redirect(path.Join(setting.AppSubURL, strings.TrimSuffix(ctx.Req.URL.String(), ctx.Params("*")), ctx.Repo.BranchNameSubURL()))
|
||||
ctx.Redirect(path.Join(
|
||||
setting.AppSubURL,
|
||||
strings.TrimSuffix(ctx.Req.URL.String(), ctx.Params("*")),
|
||||
ctx.Repo.BranchNameSubURL(),
|
||||
ctx.Repo.TreePath))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error {
|
||||
var closeError error
|
||||
var waitError error
|
||||
|
||||
args := []string{"-F", from, "-i"}
|
||||
args := []string{"-f", from, "-i"}
|
||||
args = append(args, setting.MailService.SendmailArgs...)
|
||||
args = append(args, to...)
|
||||
log.Trace("Sending with: %s %v", setting.MailService.SendmailPath, args)
|
||||
|
||||
@@ -1166,7 +1166,7 @@ func newService() {
|
||||
Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org")
|
||||
|
||||
sec = Cfg.Section("openid")
|
||||
Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(false)
|
||||
Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock)
|
||||
Service.EnableOpenIDSignUp = sec.Key("ENABLE_OPENID_SIGNUP").MustBool(!Service.DisableRegistration && Service.EnableOpenIDSignIn)
|
||||
pats := sec.Key("WHITELISTED_URIS").Strings(" ")
|
||||
if len(pats) != 0 {
|
||||
@@ -1392,7 +1392,7 @@ func newSessionService() {
|
||||
SessionConfig.Provider = Cfg.Section("session").Key("PROVIDER").In("memory",
|
||||
[]string{"memory", "file", "redis", "mysql"})
|
||||
SessionConfig.ProviderConfig = strings.Trim(Cfg.Section("session").Key("PROVIDER_CONFIG").MustString(path.Join(AppDataPath, "sessions")), "\" ")
|
||||
if !filepath.IsAbs(SessionConfig.ProviderConfig) {
|
||||
if SessionConfig.Provider == "file" && !filepath.IsAbs(SessionConfig.ProviderConfig) {
|
||||
SessionConfig.ProviderConfig = path.Join(AppWorkPath, SessionConfig.ProviderConfig)
|
||||
}
|
||||
SessionConfig.CookieName = Cfg.Section("session").Key("COOKIE_NAME").MustString("i_like_gitea")
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
||||
"github.com/go-macaron/session"
|
||||
"github.com/stretchr/testify/assert"
|
||||
macaron "gopkg.in/macaron.v1"
|
||||
)
|
||||
@@ -33,6 +34,9 @@ func MockContext(t *testing.T) *context.Context {
|
||||
macaronContext.Render = &mockRender{ResponseWriter: macaronContext.Resp}
|
||||
return &context.Context{
|
||||
Context: macaronContext,
|
||||
Flash: &session.Flash{
|
||||
Values: make(url.Values),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
48
modules/util/sanitize.go
Normal file
48
modules/util/sanitize.go
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// urlSafeError wraps an error whose message may contain a sensitive URL
|
||||
type urlSafeError struct {
|
||||
err error
|
||||
unsanitizedURL string
|
||||
}
|
||||
|
||||
func (err urlSafeError) Error() string {
|
||||
return SanitizeMessage(err.err.Error(), err.unsanitizedURL)
|
||||
}
|
||||
|
||||
// URLSanitizedError returns the sanitized version an error whose message may
|
||||
// contain a sensitive URL
|
||||
func URLSanitizedError(err error, unsanitizedURL string) error {
|
||||
return urlSafeError{err: err, unsanitizedURL: unsanitizedURL}
|
||||
}
|
||||
|
||||
// SanitizeMessage sanitizes a message which may contains a sensitive URL
|
||||
func SanitizeMessage(message, unsanitizedURL string) string {
|
||||
sanitizedURL := SanitizeURLCredentials(unsanitizedURL, true)
|
||||
return strings.Replace(message, unsanitizedURL, sanitizedURL, -1)
|
||||
}
|
||||
|
||||
// SanitizeURLCredentials sanitizes a url, either removing user credentials
|
||||
// or replacing them with a placeholder.
|
||||
func SanitizeURLCredentials(unsanitizedURL string, usePlaceholder bool) string {
|
||||
u, err := url.Parse(unsanitizedURL)
|
||||
if err != nil {
|
||||
// don't log the error, since it might contain unsanitized URL.
|
||||
return "(unparsable url)"
|
||||
}
|
||||
if u.User != nil && usePlaceholder {
|
||||
u.User = url.User("<credentials>")
|
||||
} else {
|
||||
u.User = nil
|
||||
}
|
||||
return u.String()
|
||||
}
|
||||
@@ -627,8 +627,8 @@ issues.label_templates.info=Il n'y a pas encore d'étiquettes. Vous pouvez cliqu
|
||||
issues.label_templates.helper=Sélectionnez un ensemble d'étiquettes
|
||||
issues.label_templates.use=Utiliser ce jeu d'étiquettes
|
||||
issues.label_templates.fail_to_load_file=Impossible de charger le fichier de modèle étiquette '%s' : %v
|
||||
issues.add_label_at=« enlevé la <div class="ui label" style="color: %s\; background-color: %s">%s</div> étiquette %s »
|
||||
issues.remove_label_at=« enlevé la <div class="ui label" style="color: %s\; background-color: %s">%s</div> étiquette %s »
|
||||
issues.add_label_at=`a ajouté l'étiquette <div class="ui label" style="color: %s\; background-color: %s">%s</div> %s`
|
||||
issues.remove_label_at=`a supprimé l'étiquette <div class="ui label" style="color: %s\; background-color: %s">%s</div> %s`
|
||||
issues.add_milestone_at=`a ajouté cela au jalon <b>%s</b> %s`
|
||||
issues.change_milestone_at=`a modifié le jalon de <b>%s</b> à <b>%s</b> %s`
|
||||
issues.remove_milestone_at=`a supprimé cela du jalon <b>%s</b> %s`
|
||||
|
||||
@@ -9,8 +9,6 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
api "code.gitea.io/sdk/gitea"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/auth"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -18,6 +16,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
api "code.gitea.io/sdk/gitea"
|
||||
)
|
||||
|
||||
// Search repositories via options
|
||||
@@ -322,12 +321,13 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
|
||||
RemoteAddr: remoteAddr,
|
||||
})
|
||||
if err != nil {
|
||||
err = util.URLSanitizedError(err, remoteAddr)
|
||||
if repo != nil {
|
||||
if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
|
||||
log.Error(4, "DeleteRepository: %v", errDelete)
|
||||
}
|
||||
}
|
||||
ctx.Error(500, "MigrateRepository", models.HandleCloneUserCredentials(err.Error(), true))
|
||||
ctx.Error(500, "MigrateRepository", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -108,8 +108,8 @@ func Install(ctx *context.Context) {
|
||||
form.OfflineMode = setting.OfflineMode
|
||||
form.DisableGravatar = setting.DisableGravatar
|
||||
form.EnableFederatedAvatar = setting.EnableFederatedAvatar
|
||||
form.EnableOpenIDSignIn = true
|
||||
form.EnableOpenIDSignUp = true
|
||||
form.EnableOpenIDSignIn = setting.Service.EnableOpenIDSignIn
|
||||
form.EnableOpenIDSignUp = setting.Service.EnableOpenIDSignUp
|
||||
form.DisableRegistration = setting.Service.DisableRegistration
|
||||
form.EnableCaptcha = setting.Service.EnableCaptcha
|
||||
form.RequireSignInView = setting.Service.RequireSignInView
|
||||
|
||||
@@ -45,10 +45,11 @@ func ServeData(ctx *context.Context, name string, reader io.Reader) error {
|
||||
|
||||
// ServeBlob download a git.Blob
|
||||
func ServeBlob(ctx *context.Context, blob *git.Blob) error {
|
||||
dataRc, err := blob.Data()
|
||||
dataRc, err := blob.DataAsync()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dataRc.Close()
|
||||
|
||||
return ServeData(ctx, ctx.Repo.TreePath, dataRc)
|
||||
}
|
||||
|
||||
@@ -73,11 +73,16 @@ func editFile(ctx *context.Context, isNewFile bool) {
|
||||
|
||||
// No way to edit a directory online.
|
||||
if entry.IsDir() {
|
||||
ctx.Handle(404, "", nil)
|
||||
ctx.Handle(404, "entry.IsDir", nil)
|
||||
return
|
||||
}
|
||||
|
||||
blob := entry.Blob()
|
||||
if blob.Size() >= setting.UI.MaxDisplayFileSize {
|
||||
ctx.Handle(404, "blob.Size", err)
|
||||
return
|
||||
}
|
||||
|
||||
dataRc, err := blob.Data()
|
||||
if err != nil {
|
||||
ctx.Handle(404, "blob.Data", err)
|
||||
@@ -93,7 +98,7 @@ func editFile(ctx *context.Context, isNewFile bool) {
|
||||
|
||||
// Only text file are editable online.
|
||||
if !base.IsTextFile(buf) {
|
||||
ctx.Handle(404, "", nil)
|
||||
ctx.Handle(404, "base.IsTextFile", nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -319,6 +319,9 @@ func getFileContentFromDefaultBranch(ctx *context.Context, filename string) (str
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
if entry.Blob().Size() >= setting.UI.MaxDisplayFileSize {
|
||||
return "", false
|
||||
}
|
||||
r, err = entry.Blob().Data()
|
||||
if err != nil {
|
||||
return "", false
|
||||
|
||||
@@ -191,6 +191,7 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
|
||||
|
||||
rel.Title = form.Title
|
||||
rel.Note = form.Content
|
||||
rel.Target = form.Target
|
||||
rel.IsDraft = len(form.Draft) > 0
|
||||
rel.IsPrerelease = form.Prerelease
|
||||
rel.PublisherID = ctx.User.ID
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -232,6 +233,9 @@ func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) {
|
||||
return
|
||||
}
|
||||
|
||||
// remoteAddr may contain credentials, so we sanitize it
|
||||
err = util.URLSanitizedError(err, remoteAddr)
|
||||
|
||||
if repo != nil {
|
||||
if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
|
||||
log.Error(4, "DeleteRepository: %v", errDelete)
|
||||
@@ -241,11 +245,11 @@ func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) {
|
||||
if strings.Contains(err.Error(), "Authentication failed") ||
|
||||
strings.Contains(err.Error(), "could not read Username") {
|
||||
ctx.Data["Err_Auth"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.auth_failed", models.HandleCloneUserCredentials(err.Error(), true)), tplMigrate, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("form.auth_failed", err.Error()), tplMigrate, &form)
|
||||
return
|
||||
} else if strings.Contains(err.Error(), "fatal:") {
|
||||
ctx.Data["Err_CloneAddr"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.migrate.failed", models.HandleCloneUserCredentials(err.Error(), true)), tplMigrate, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.migrate.failed", err.Error()), tplMigrate, &form)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -76,11 +76,12 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
ctx.Data["ReadmeInList"] = true
|
||||
ctx.Data["ReadmeExist"] = true
|
||||
|
||||
dataRc, err := readmeFile.Data()
|
||||
dataRc, err := readmeFile.DataAsync()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "Data", err)
|
||||
return
|
||||
}
|
||||
defer dataRc.Close()
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
n, _ := dataRc.Read(buf)
|
||||
@@ -91,14 +92,21 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
ctx.Data["FileName"] = readmeFile.Name()
|
||||
// FIXME: what happens when README file is an image?
|
||||
if isTextFile {
|
||||
d, _ := ioutil.ReadAll(dataRc)
|
||||
buf = append(buf, d...)
|
||||
if markup.Type(readmeFile.Name()) != "" {
|
||||
ctx.Data["IsMarkup"] = true
|
||||
ctx.Data["FileContent"] = string(markup.Render(readmeFile.Name(), buf, treeLink, ctx.Repo.Repository.ComposeMetas()))
|
||||
if readmeFile.Size() >= setting.UI.MaxDisplayFileSize {
|
||||
// Pretend that this is a normal text file to display 'This file is too large to be shown'
|
||||
ctx.Data["IsFileTooLarge"] = true
|
||||
ctx.Data["IsTextFile"] = true
|
||||
ctx.Data["FileSize"] = readmeFile.Size()
|
||||
} else {
|
||||
ctx.Data["IsRenderedHTML"] = true
|
||||
ctx.Data["FileContent"] = string(bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1))
|
||||
d, _ := ioutil.ReadAll(dataRc)
|
||||
buf = append(buf, d...)
|
||||
if markup.Type(readmeFile.Name()) != "" {
|
||||
ctx.Data["IsMarkup"] = true
|
||||
ctx.Data["FileContent"] = string(markup.Render(readmeFile.Name(), buf, treeLink, ctx.Repo.Repository.ComposeMetas()))
|
||||
} else {
|
||||
ctx.Data["IsRenderedHTML"] = true
|
||||
ctx.Data["FileContent"] = string(bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,11 +143,12 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
ctx.Data["IsViewFile"] = true
|
||||
|
||||
blob := entry.Blob()
|
||||
dataRc, err := blob.Data()
|
||||
dataRc, err := blob.DataAsync()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "Data", err)
|
||||
ctx.Handle(500, "DataAsync", err)
|
||||
return
|
||||
}
|
||||
defer dataRc.Close()
|
||||
|
||||
ctx.Data["FileSize"] = blob.Size()
|
||||
ctx.Data["FileName"] = blob.Name()
|
||||
|
||||
@@ -223,7 +223,9 @@ func SettingsSecurityPost(ctx *context.Context, form auth.ChangePasswordForm) {
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.User.IsPasswordSet() && !ctx.User.ValidatePassword(form.OldPassword) {
|
||||
if len(form.Password) < setting.MinPasswordLength {
|
||||
ctx.Flash.Error(ctx.Tr("auth.password_too_short", setting.MinPasswordLength))
|
||||
} else if ctx.User.IsPasswordSet() && !ctx.User.ValidatePassword(form.OldPassword) {
|
||||
ctx.Flash.Error(ctx.Tr("settings.password_incorrect"))
|
||||
} else if form.Password != form.Retype {
|
||||
ctx.Flash.Error(ctx.Tr("form.password_not_match"))
|
||||
|
||||
56
routers/user/setting_test.go
Normal file
56
routers/user/setting_test.go
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package user
|
||||
|
||||
/*func TestChangePassword(t *testing.T) {
|
||||
oldPassword := "password"
|
||||
setting.MinPasswordLength = 6
|
||||
|
||||
for _, req := range []struct {
|
||||
OldPassword string
|
||||
NewPassword string
|
||||
Retype string
|
||||
Message string
|
||||
}{
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "123456",
|
||||
Retype: "123456",
|
||||
Message: "",
|
||||
},
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "12345",
|
||||
Retype: "12345",
|
||||
Message: "auth.password_too_short",
|
||||
},
|
||||
{
|
||||
OldPassword: "12334",
|
||||
NewPassword: "123456",
|
||||
Retype: "123456",
|
||||
Message: "settings.password_incorrect",
|
||||
},
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "123456",
|
||||
Retype: "12345",
|
||||
Message: "form.password_not_match",
|
||||
},
|
||||
} {
|
||||
models.PrepareTestEnv(t)
|
||||
ctx := test.MockContext(t, "user/settings/security")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
|
||||
SettingsSecurityPost(ctx, auth.ChangePasswordForm{
|
||||
OldPassword: req.OldPassword,
|
||||
Password: req.NewPassword,
|
||||
Retype: req.Retype,
|
||||
})
|
||||
|
||||
assert.EqualValues(t, req.Message, ctx.Flash.ErrorMsg)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
}
|
||||
}*/
|
||||
@@ -264,8 +264,6 @@
|
||||
<dd>{{.Git.MaxGitDiffFiles}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.git_gc_args"}}</dt>
|
||||
<dd><code>{{.Git.GCArgs}}</code></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.git_max_diff_lines"}}</dt>
|
||||
<dd>{{.Git.MaxGitDiffLines}}</dd>
|
||||
<div class="ui divider"></div>
|
||||
<dt>{{.i18n.Tr "admin.config.git_migrate_timeout"}}</dt>
|
||||
<dd>{{.Git.Timeout.Migrate}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
<a class="title has-emoji" href="{{$.Link}}/{{.Index}}">{{.Title}}</a>
|
||||
|
||||
{{if .Ref}}
|
||||
<a class="ui label" href="{{$.RepoLink}}/src/commit/{{.Ref}}">{{.Ref}}</a>
|
||||
<a class="ui label" href="{{$.RepoLink}}/src/branch/{{.Ref}}">{{.Ref}}</a>
|
||||
{{end}}
|
||||
{{range .Labels}}
|
||||
<a class="ui label" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}">{{.Name}}</a>
|
||||
|
||||
50
vendor/code.gitea.io/git/blob.go
generated
vendored
50
vendor/code.gitea.io/git/blob.go
generated
vendored
@@ -6,7 +6,11 @@ package git
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// Blob represents a Git object.
|
||||
@@ -18,14 +22,52 @@ type Blob struct {
|
||||
// Data gets content of blob all at once and wrap it as io.Reader.
|
||||
// This can be very slow and memory consuming for huge content.
|
||||
func (b *Blob) Data() (io.Reader, error) {
|
||||
stdout, err := NewCommand("show", b.ID.String()).RunInDirBytes(b.repo.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
stdout := new(bytes.Buffer)
|
||||
stderr := new(bytes.Buffer)
|
||||
|
||||
// Preallocate memory to save ~50% memory usage on big files.
|
||||
stdout.Grow(int(b.Size() + 2048))
|
||||
|
||||
if err := b.DataPipeline(stdout, stderr); err != nil {
|
||||
return nil, concatenateError(err, stderr.String())
|
||||
}
|
||||
return bytes.NewBuffer(stdout), nil
|
||||
return stdout, nil
|
||||
}
|
||||
|
||||
// DataPipeline gets content of blob and write the result or error to stdout or stderr
|
||||
func (b *Blob) DataPipeline(stdout, stderr io.Writer) error {
|
||||
return NewCommand("show", b.ID.String()).RunInDirPipeline(b.repo.Path, stdout, stderr)
|
||||
}
|
||||
|
||||
type cmdReadCloser struct {
|
||||
cmd *exec.Cmd
|
||||
stdout io.Reader
|
||||
}
|
||||
|
||||
func (c cmdReadCloser) Read(p []byte) (int, error) {
|
||||
return c.stdout.Read(p)
|
||||
}
|
||||
|
||||
func (c cmdReadCloser) Close() error {
|
||||
io.Copy(ioutil.Discard, c.stdout)
|
||||
return c.cmd.Wait()
|
||||
}
|
||||
|
||||
// DataAsync gets a ReadCloser for the contents of a blob without reading it all.
|
||||
// Calling the Close function on the result will discard all unread output.
|
||||
func (b *Blob) DataAsync() (io.ReadCloser, error) {
|
||||
cmd := exec.Command("git", "show", b.ID.String())
|
||||
cmd.Dir = b.repo.Path
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StdoutPipe: %v", err)
|
||||
}
|
||||
|
||||
if err = cmd.Start(); err != nil {
|
||||
return nil, fmt.Errorf("Start: %v", err)
|
||||
}
|
||||
|
||||
return cmdReadCloser{stdout: stdout, cmd: cmd}, nil
|
||||
}
|
||||
|
||||
3
vendor/code.gitea.io/git/commit.go
generated
vendored
3
vendor/code.gitea.io/git/commit.go
generated
vendored
@@ -98,10 +98,11 @@ func (c *Commit) IsImageFile(name string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
dataRc, err := blob.Data()
|
||||
dataRc, err := blob.DataAsync()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer dataRc.Close()
|
||||
buf := make([]byte, 1024)
|
||||
n, _ := dataRc.Read(buf)
|
||||
buf = buf[:n]
|
||||
|
||||
2
vendor/code.gitea.io/git/git.go
generated
vendored
2
vendor/code.gitea.io/git/git.go
generated
vendored
@@ -25,7 +25,7 @@ var (
|
||||
// Prefix the log prefix
|
||||
Prefix = "[git-module] "
|
||||
// GitVersionRequired is the minimum Git version required
|
||||
GitVersionRequired = "1.8.1.6"
|
||||
GitVersionRequired = "1.7.2"
|
||||
)
|
||||
|
||||
func log(format string, args ...interface{}) {
|
||||
|
||||
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
@@ -3,10 +3,10 @@
|
||||
"ignore": "test appengine",
|
||||
"package": [
|
||||
{
|
||||
"checksumSHA1": "JN/re4+x/hCzMLGHmieUcykVDAg=",
|
||||
"checksumSHA1": "vAVjAz7Wpjnu7GGba4JLIDTpQEw=",
|
||||
"path": "code.gitea.io/git",
|
||||
"revision": "d47b98c44c9a6472e44ab80efe65235e11c6da2a",
|
||||
"revisionTime": "2017-10-23T00:52:09Z"
|
||||
"revision": "f9dd6826bbb51c92c6964ce18176c304ea286e54",
|
||||
"revisionTime": "2017-11-28T15:25:05Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "OICEgmUefW4L4l/FK/NVFnl/aOM=",
|
||||
|
||||
Reference in New Issue
Block a user