GUI Basic Authentication (fixes #90)

This commit is contained in:
Jakob Borg 2014-04-08 15:56:12 +02:00
parent 1443a1388e
commit cbae64fc06
4 changed files with 31 additions and 13 deletions

View File

@ -14,6 +14,7 @@ type Configuration struct {
Version int `xml:"version,attr" default:"2"`
Repositories []RepositoryConfiguration `xml:"repository"`
Nodes []NodeConfiguration `xml:"node"`
GUI GUIConfiguration `xml:"gui"`
Options OptionsConfiguration `xml:"options"`
XMLName xml.Name `xml:"configuration" json:"-"`
}
@ -43,9 +44,6 @@ type NodeConfiguration struct {
type OptionsConfiguration struct {
ListenAddress []string `xml:"listenAddress" default:":22000"`
ReadOnly bool `xml:"readOnly,omitempty"`
GUIEnabled bool `xml:"guiEnabled" default:"true"`
GUIAddress string `xml:"guiAddress" default:"127.0.0.1:8080"`
GlobalAnnServer string `xml:"globalAnnounceServer" default:"announce.syncthing.net:22025"`
GlobalAnnEnabled bool `xml:"globalAnnounceEnabled" default:"true"`
LocalAnnEnabled bool `xml:"localAnnounceEnabled" default:"true"`
@ -55,6 +53,17 @@ type OptionsConfiguration struct {
ReconnectIntervalS int `xml:"reconnectionIntervalS" default:"60"`
MaxChangeKbps int `xml:"maxChangeKbps" default:"1000"`
StartBrowser bool `xml:"startBrowser" default:"true"`
Deprecated_ReadOnly bool `xml:"readOnly,omitempty"`
Deprecated_GUIEnabled bool `xml:"guiEnabled,omitempty"`
Deprecated_GUIAddress string `xml:"guiAddress,omitempty"`
}
type GUIConfiguration struct {
Enabled bool `xml:"enabled,attr" default:"true"`
Address string `xml:"address" default:"127.0.0.1:8080"`
User string `xml:"user,omitempty"`
Password string `xml:"password,omitempty"`
}
func setDefaults(data interface{}) error {
@ -148,6 +157,7 @@ func readConfigXML(rd io.Reader) (Configuration, error) {
setDefaults(&cfg)
setDefaults(&cfg.Options)
setDefaults(&cfg.GUI)
var err error
if rd != nil {
@ -184,7 +194,7 @@ func convertV1V2(cfg *Configuration) {
// Set all repositories to read only if the global read only flag is set.
var nodes = map[string]NodeConfiguration{}
for i, repo := range cfg.Repositories {
cfg.Repositories[i].ReadOnly = cfg.Options.ReadOnly
cfg.Repositories[i].ReadOnly = cfg.Options.Deprecated_ReadOnly
for j, node := range repo.Nodes {
if _, ok := nodes[node.NodeID]; !ok {
nodes[node.NodeID] = node
@ -192,6 +202,7 @@ func convertV1V2(cfg *Configuration) {
cfg.Repositories[i].Nodes[j] = NodeConfiguration{NodeID: node.NodeID}
}
}
cfg.Options.Deprecated_ReadOnly = false
// Set and sort the list of nodes.
for _, node := range nodes {
@ -199,7 +210,12 @@ func convertV1V2(cfg *Configuration) {
}
sort.Sort(NodeConfigurationList(cfg.Nodes))
cfg.Options.ReadOnly = false
// GUI
cfg.GUI.Address = cfg.Options.Deprecated_GUIAddress
cfg.GUI.Enabled = cfg.Options.Deprecated_GUIEnabled
cfg.Options.Deprecated_GUIEnabled = false
cfg.Options.Deprecated_GUIAddress = ""
cfg.Version = 2
}

View File

@ -10,8 +10,6 @@ import (
func TestDefaultValues(t *testing.T) {
expected := OptionsConfiguration{
ListenAddress: []string{":22000"},
GUIEnabled: true,
GUIAddress: "127.0.0.1:8080",
GlobalAnnServer: "announce.syncthing.net:22025",
GlobalAnnEnabled: true,
LocalAnnEnabled: true,

View File

@ -11,6 +11,7 @@ import (
"github.com/calmh/syncthing/scanner"
"github.com/codegangsta/martini"
"github.com/codegangsta/martini-contrib/auth"
)
type guiError struct {
@ -24,7 +25,7 @@ var (
guiErrorsMut sync.Mutex
)
func startGUI(addr string, m *Model) {
func startGUI(cfg GUIConfiguration, m *Model) {
router := martini.NewRouter()
router.Get("/", getRoot)
router.Get("/rest/version", restGetVersion)
@ -43,12 +44,15 @@ func startGUI(addr string, m *Model) {
go func() {
mr := martini.New()
if len(cfg.User) > 0 && len(cfg.Password) > 0 {
mr.Use(auth.Basic(cfg.User, cfg.Password))
}
mr.Use(embeddedStatic())
mr.Use(martini.Recovery())
mr.Use(restMiddleware)
mr.Action(router.Handle)
mr.Map(m)
err := http.ListenAndServe(addr, mr)
err := http.ListenAndServe(cfg.Address, mr)
if err != nil {
warnln("GUI not possible:", err)
}

View File

@ -185,10 +185,10 @@ func main() {
}
// GUI
if cfg.Options.GUIEnabled && cfg.Options.GUIAddress != "" {
addr, err := net.ResolveTCPAddr("tcp", cfg.Options.GUIAddress)
if cfg.GUI.Enabled && cfg.GUI.Address != "" {
addr, err := net.ResolveTCPAddr("tcp", cfg.GUI.Address)
if err != nil {
warnf("Cannot start GUI on %q: %v", cfg.Options.GUIAddress, err)
warnf("Cannot start GUI on %q: %v", cfg.GUI.Address, err)
} else {
var hostOpen, hostShow string
switch {
@ -204,7 +204,7 @@ func main() {
}
infof("Starting web GUI on http://%s:%d/", hostShow, addr.Port)
startGUI(cfg.Options.GUIAddress, m)
startGUI(cfg.GUI, m)
if cfg.Options.StartBrowser && len(os.Getenv("STRESTART")) == 0 {
openURL(fmt.Sprintf("http://%s:%d", hostOpen, addr.Port))
}