diff options
author | Unknwon <u@gogs.io> | 2017-04-04 20:21:35 -0400 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2017-04-04 20:21:35 -0400 |
commit | 5a488b6517bd6a9980c3f226231ff21a4ca06746 (patch) | |
tree | 0b2d32d1797ede0ba57c54bf34980f958516dc81 /models/mirror.go | |
parent | ae1d50d19a4ffe1b527429978ebff6fdd35b71e8 (diff) |
models/mirror: unescape credentials at read (#4014)
If we save credentials already escaped, 'url.QueryEscape' still
escapes it and makes the credentials become incorrect.
Diffstat (limited to 'models/mirror.go')
-rw-r--r-- | models/mirror.go | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/models/mirror.go b/models/mirror.go index 46ef7452..754ee25f 100644 --- a/models/mirror.go +++ b/models/mirror.go @@ -71,6 +71,46 @@ func (m *Mirror) ScheduleNextUpdate() { m.NextUpdate = time.Now().Add(time.Duration(m.Interval) * time.Hour) } +// findPasswordInMirrorAddress returns start (inclusive) and end index (exclusive) +// of password portion of credentials in given mirror address. +// It returns a boolean value to indicate whether password portion is found. +func findPasswordInMirrorAddress(addr string) (start int, end int, found bool) { + // Find end of credentials (start of path) + end = strings.LastIndex(addr, "@") + if end == -1 { + return -1, -1, false + } + + // Find delimiter of credentials (end of username) + start = strings.Index(addr, "://") + if start == -1 { + return -1, -1, false + } + start += 3 + delim := strings.Index(addr[start:], ":") + if delim == -1 { + return -1, -1, false + } + delim += 1 + + if start+delim >= end { + return -1, -1, false // No password portion presented + } + + return start + delim, end, true +} + +// unescapeMirrorCredentials returns mirror address with unescaped credentials. +func unescapeMirrorCredentials(addr string) string { + start, end, found := findPasswordInMirrorAddress(addr) + if !found { + return addr + } + + password, _ := url.QueryUnescape(addr[start:end]) + return addr[:start] + password + addr[end:] +} + func (m *Mirror) readAddress() { if len(m.address) > 0 { return @@ -81,7 +121,7 @@ func (m *Mirror) readAddress() { log.Error(2, "Load: %v", err) return } - m.address = cfg.Section("remote \"origin\"").Key("url").Value() + m.address = unescapeMirrorCredentials(cfg.Section("remote \"origin\"").Key("url").Value()) } // HandleCloneUserCredentials replaces user credentials from HTTP/HTTPS URL @@ -122,29 +162,12 @@ func (m *Mirror) FullAddress() string { // escapeCredentials returns mirror address with escaped credentials. func escapeMirrorCredentials(addr string) string { - // Find end of credentials (start of path) - end := strings.LastIndex(addr, "@") - if end == -1 { + start, end, found := findPasswordInMirrorAddress(addr) + if !found { return addr } - // Find delimiter of credentials (end of username) - start := strings.Index(addr, "://") - if start == -1 { - return addr - } - start += 3 - delim := strings.Index(addr[:start], ":") - if delim == -1 { - return addr - } - delim += 1 - - if start+delim > end { - return addr // No password portion presented - } - - return addr[:start+delim] + url.QueryEscape(addr[start+delim:end]) + addr[end:] + return addr[:start] + url.QueryEscape(addr[start:end]) + addr[end:] } // SaveAddress writes new address to Git repository config. |