* Explode out mirror username and password * Update models/repo_mirror.go * Just roundtrip the password * remove unused declaration * Update templates/repo/settings/options.tmpltags/v1.21.12.1
| @@ -7,6 +7,7 @@ package models | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| "net/url" | |||||
| "strings" | "strings" | ||||
| "time" | "time" | ||||
| @@ -119,7 +120,7 @@ func sanitizeOutput(output, repoPath string) (string, error) { | |||||
| return util.SanitizeMessage(output, remoteAddr), nil | return util.SanitizeMessage(output, remoteAddr), nil | ||||
| } | } | ||||
| // Address returns mirror address from Git repository config without credentials. | |||||
| // Address returns mirror address from Git repository config with credentials censored. | |||||
| func (m *Mirror) Address() string { | func (m *Mirror) Address() string { | ||||
| m.readAddress() | m.readAddress() | ||||
| return util.SanitizeURLCredentials(m.address, false) | return util.SanitizeURLCredentials(m.address, false) | ||||
| @@ -131,6 +132,41 @@ func (m *Mirror) FullAddress() string { | |||||
| return m.address | return m.address | ||||
| } | } | ||||
| // AddressNoCredentials returns mirror address from Git repository config without credentials. | |||||
| func (m *Mirror) AddressNoCredentials() string { | |||||
| m.readAddress() | |||||
| u, err := url.Parse(m.address) | |||||
| if err != nil { | |||||
| // this shouldn't happen but just return it unsanitised | |||||
| return m.address | |||||
| } | |||||
| u.User = nil | |||||
| return u.String() | |||||
| } | |||||
| // Username returns the mirror address username | |||||
| func (m *Mirror) Username() string { | |||||
| m.readAddress() | |||||
| u, err := url.Parse(m.address) | |||||
| if err != nil { | |||||
| // this shouldn't happen but if it does return "" | |||||
| return "" | |||||
| } | |||||
| return u.User.Username() | |||||
| } | |||||
| // Password returns the mirror address password | |||||
| func (m *Mirror) Password() string { | |||||
| m.readAddress() | |||||
| u, err := url.Parse(m.address) | |||||
| if err != nil { | |||||
| // this shouldn't happen but if it does return "" | |||||
| return "" | |||||
| } | |||||
| password, _ := u.User.Password() | |||||
| return password | |||||
| } | |||||
| // SaveAddress writes new address to Git repository config. | // SaveAddress writes new address to Git repository config. | ||||
| func (m *Mirror) SaveAddress(addr string) error { | func (m *Mirror) SaveAddress(addr string) error { | ||||
| repoPath := m.Repo.RepoPath() | repoPath := m.Repo.RepoPath() | ||||
| @@ -98,13 +98,15 @@ func (f MigrateRepoForm) ParseRemoteAddr(user *models.User) (string, error) { | |||||
| // RepoSettingForm form for changing repository settings | // RepoSettingForm form for changing repository settings | ||||
| type RepoSettingForm struct { | type RepoSettingForm struct { | ||||
| RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"` | |||||
| Description string `binding:"MaxSize(255)"` | |||||
| Website string `binding:"ValidUrl;MaxSize(255)"` | |||||
| Interval string | |||||
| MirrorAddress string | |||||
| Private bool | |||||
| EnablePrune bool | |||||
| RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"` | |||||
| Description string `binding:"MaxSize(255)"` | |||||
| Website string `binding:"ValidUrl;MaxSize(255)"` | |||||
| Interval string | |||||
| MirrorAddress string | |||||
| MirrorUsername string | |||||
| MirrorPassword string | |||||
| Private bool | |||||
| EnablePrune bool | |||||
| // Advanced settings | // Advanced settings | ||||
| EnableWiki bool | EnableWiki bool | ||||
| @@ -584,7 +584,7 @@ mirror_prune_desc = Remove obsolete remote-tracking references | |||||
| mirror_interval = Mirror Interval (valid time units are 'h', 'm', 's'). 0 to disable automatic sync. | mirror_interval = Mirror Interval (valid time units are 'h', 'm', 's'). 0 to disable automatic sync. | ||||
| mirror_interval_invalid = The mirror interval is not valid. | mirror_interval_invalid = The mirror interval is not valid. | ||||
| mirror_address = Clone From URL | mirror_address = Clone From URL | ||||
| mirror_address_desc = Include any required authorization credentials in the URL. These must be url escaped as appropriate | |||||
| mirror_address_desc = Put any required credentials in the Clone Authorization section. | |||||
| mirror_address_url_invalid = The provided url is invalid. You must escape all components of the url correctly. | mirror_address_url_invalid = The provided url is invalid. You must escape all components of the url correctly. | ||||
| mirror_address_protocol_invalid = The provided url is invalid. Only http(s):// or git:// locations can be mirrored from. | mirror_address_protocol_invalid = The provided url is invalid. Only http(s):// or git:// locations can be mirrored from. | ||||
| mirror_last_synced = Last Synchronized | mirror_last_synced = Last Synchronized | ||||
| @@ -169,6 +169,10 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { | |||||
| return | return | ||||
| } | } | ||||
| if form.MirrorUsername != "" || form.MirrorPassword != "" { | |||||
| u.User = url.UserPassword(form.MirrorUsername, form.MirrorPassword) | |||||
| } | |||||
| // Now use xurls | // Now use xurls | ||||
| address := validFormAddress.FindString(form.MirrorAddress) | address := validFormAddress.FindString(form.MirrorAddress) | ||||
| if address != form.MirrorAddress && form.MirrorAddress != "" { | if address != form.MirrorAddress && form.MirrorAddress != "" { | ||||
| @@ -80,9 +80,26 @@ | |||||
| </div> | </div> | ||||
| <div class="field {{if .Err_MirrorAddress}}error{{end}}"> | <div class="field {{if .Err_MirrorAddress}}error{{end}}"> | ||||
| <label for="mirror_address">{{.i18n.Tr "repo.mirror_address"}}</label> | <label for="mirror_address">{{.i18n.Tr "repo.mirror_address"}}</label> | ||||
| <input id="mirror_address" name="mirror_address" value="{{.Mirror.FullAddress}}" required> | |||||
| <input id="mirror_address" name="mirror_address" value="{{.Mirror.AddressNoCredentials}}" required> | |||||
| <p class="help">{{.i18n.Tr "repo.mirror_address_desc"}}</p> | <p class="help">{{.i18n.Tr "repo.mirror_address_desc"}}</p> | ||||
| </div> | </div> | ||||
| <div class="ui accordion optional field"> | |||||
| <label class="ui title {{if .Err_Auth}}text red active{{end}}"> | |||||
| <i class="icon dropdown"></i> | |||||
| <label for="">{{.i18n.Tr "repo.need_auth"}}</label> | |||||
| </label> | |||||
| <div class="content {{if .Err_Auth}}active{{else if .Mirror.Username}}active{{end}}"> | |||||
| <div class="inline field {{if .Err_Auth}}error{{end}}"> | |||||
| <label for="mirror_username">{{.i18n.Tr "username"}}</label> | |||||
| <input id="mirror_username" name="mirror_username" value="{{.Mirror.Username}}" {{if not .mirror_username}}data-need-clear="true"{{end}}> | |||||
| </div> | |||||
| <input class="fake" type="password"> | |||||
| <div class="inline field {{if .Err_Auth}}error{{end}}"> | |||||
| <label for="mirror_password">{{.i18n.Tr "password"}}</label> | |||||
| <input id="mirror_password" name="mirror_password" type="password" value="{{.Mirror.Password}}" {{if not .mirror_password}}data-need-clear="true"{{end}}> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="field"> | <div class="field"> | ||||
| <button class="ui green button">{{$.i18n.Tr "repo.settings.update_settings"}}</button> | <button class="ui green button">{{$.i18n.Tr "repo.settings.update_settings"}}</button> | ||||