diff options
| author | Niall Sheridan <nsheridan@gmail.com> | 2017-02-19 23:28:33 +0000 | 
|---|---|---|
| committer | Niall Sheridan <nsheridan@gmail.com> | 2017-02-20 22:13:56 +0000 | 
| commit | fb830dc3531904be0a58e2c4dd4638b390bbdab2 (patch) | |
| tree | fa9dc298dc7463be55d66ea855d82b9d111382fe /server/server.go | |
| parent | eb57eaf30965ba24ff669d6f9c8d11cd24951777 (diff) | |
Split the servers out of main
Diffstat (limited to 'server/server.go')
| -rw-r--r-- | server/server.go | 117 | 
1 files changed, 117 insertions, 0 deletions
| diff --git a/server/server.go b/server/server.go new file mode 100644 index 0000000..676a61b --- /dev/null +++ b/server/server.go @@ -0,0 +1,117 @@ +package server + +import ( +	"crypto/tls" +	"fmt" +	"log" +	"net" + +	"github.com/pkg/errors" +	"github.com/soheilhy/cmux" + +	"go4.org/wkfs" +	"golang.org/x/crypto/acme/autocert" + +	wkfscache "github.com/nsheridan/autocert-wkfs-cache" +	"github.com/nsheridan/cashier/server/auth" +	"github.com/nsheridan/cashier/server/auth/github" +	"github.com/nsheridan/cashier/server/auth/gitlab" +	"github.com/nsheridan/cashier/server/auth/google" +	"github.com/nsheridan/cashier/server/config" +	"github.com/nsheridan/cashier/server/metrics" +	"github.com/nsheridan/cashier/server/signer" +	"github.com/nsheridan/cashier/server/store" +	"github.com/sid77/drop" +) + +var ( +	authprovider auth.Provider +	certstore    store.CertStorer +	keysigner    *signer.KeySigner +) + +func loadCerts(certFile, keyFile string) (tls.Certificate, error) { +	key, err := wkfs.ReadFile(keyFile) +	if err != nil { +		return tls.Certificate{}, errors.Wrap(err, "error reading TLS private key") +	} +	cert, err := wkfs.ReadFile(certFile) +	if err != nil { +		return tls.Certificate{}, errors.Wrap(err, "error reading TLS certificate") +	} +	return tls.X509KeyPair(cert, key) +} + +// Run the HTTP and RPC servers. +func Run(conf *config.Config) { +	var err error +	keysigner, err = signer.New(conf.SSH) +	if err != nil { +		log.Fatal(err) +	} + +	laddr := fmt.Sprintf("%s:%d", conf.Server.Addr, conf.Server.Port) +	l, err := net.Listen("tcp", laddr) +	if err != nil { +		log.Fatal(errors.Wrapf(err, "unable to listen on %s:%d", conf.Server.Addr, conf.Server.Port)) +	} + +	tlsConfig := &tls.Config{} +	if conf.Server.UseTLS { +		if conf.Server.LetsEncryptServername != "" { +			m := autocert.Manager{ +				Prompt:     autocert.AcceptTOS, +				Cache:      wkfscache.Cache(conf.Server.LetsEncryptCache), +				HostPolicy: autocert.HostWhitelist(conf.Server.LetsEncryptServername), +			} +			tlsConfig.GetCertificate = m.GetCertificate +		} else { +			if conf.Server.TLSCert == "" || conf.Server.TLSKey == "" { +				log.Fatal("TLS cert or key not specified in config") +			} +			tlsConfig.Certificates = make([]tls.Certificate, 1) +			tlsConfig.Certificates[0], err = loadCerts(conf.Server.TLSCert, conf.Server.TLSKey) +			if err != nil { +				log.Fatal(errors.Wrap(err, "unable to create TLS listener")) +			} +		} +		l = tls.NewListener(l, tlsConfig) +	} + +	if conf.Server.User != "" { +		log.Print("Dropping privileges...") +		if err := drop.DropPrivileges(conf.Server.User); err != nil { +			log.Fatal(errors.Wrap(err, "unable to drop privileges")) +		} +	} + +	// Unprivileged section +	metrics.Register() + +	switch conf.Auth.Provider { +	case "google": +		authprovider, err = google.New(conf.Auth) +	case "github": +		authprovider, err = github.New(conf.Auth) +	case "gitlab": +		authprovider, err = gitlab.New(conf.Auth) +	default: +		log.Fatalf("Unknown provider %s\n", conf.Auth.Provider) +	} +	if err != nil { +		log.Fatal(errors.Wrapf(err, "unable to use provider '%s'", conf.Auth.Provider)) +	} + +	certstore, err = store.New(conf.Server.Database) +	if err != nil { +		log.Fatal(err) +	} + +	log.Printf("Starting server on %s", laddr) +	cm := cmux.New(l) +	httpl := cm.Match(cmux.HTTP1Fast()) +	grpcl := cm.Match(cmux.HTTP2HeaderField("content-type", "application/grpc")) +	go runHTTPServer(conf.Server, httpl) +	go runGRPCServer(grpcl) +	log.Fatal(cm.Serve()) +} | 
