diff --git a/conf/config.default.ini b/conf/config.default.ini index fc48518..e9d5ead 100644 --- a/conf/config.default.ini +++ b/conf/config.default.ini @@ -1,5 +1,6 @@ [app] port=8080 +auth=false [etcd] root_key=e3w_test diff --git a/conf/config.go b/conf/config.go index a5fc53d..2b2e1b3 100644 --- a/conf/config.go +++ b/conf/config.go @@ -6,6 +6,7 @@ import ( type Config struct { Port string + Auth bool EtcdRootKey string EtcdEndPoints []string EtcdUsername string @@ -22,6 +23,7 @@ func Init(filepath string) (*Config, error) { appSec := cfg.Section("app") c.Port = appSec.Key("port").Value() + c.Auth = appSec.Key("auth").MustBool() etcdSec := cfg.Section("etcd") c.EtcdRootKey = etcdSec.Key("root_key").Value() diff --git a/e3ch/e3ch.go b/e3ch/e3ch.go new file mode 100644 index 0000000..cd0d5e1 --- /dev/null +++ b/e3ch/e3ch.go @@ -0,0 +1,36 @@ +package e3ch + +import ( + "github.com/coreos/etcd/clientv3" + "github.com/soyking/e3ch" + "github.com/soyking/e3w/conf" +) + +func NewE3chClient(config *conf.Config) (*client.EtcdHRCHYClient, error) { + clt, err := clientv3.New(clientv3.Config{ + Endpoints: config.EtcdEndPoints, + Username: config.EtcdUsername, + Password: config.EtcdPassword, + }) + if err != nil { + return nil, err + } + + client, err := client.New(clt, config.EtcdRootKey) + if err != nil { + return nil, err + } + return client, client.FormatRootKey() +} + +func CloneE3chClient(username, password string, client *client.EtcdHRCHYClient) (*client.EtcdHRCHYClient, error) { + clt, err := clientv3.New(clientv3.Config{ + Endpoints: client.EtcdClient().Endpoints(), + Username: username, + Password: password, + }) + if err != nil { + return nil, err + } + return client.Clone(clt), nil +} diff --git a/main.go b/main.go index 0f284d8..87a9cd6 100644 --- a/main.go +++ b/main.go @@ -3,10 +3,9 @@ package main import ( "flag" "fmt" - "github.com/coreos/etcd/clientv3" "github.com/gin-gonic/gin" - "github.com/soyking/e3ch" "github.com/soyking/e3w/conf" + "github.com/soyking/e3w/e3ch" "github.com/soyking/e3w/routers" "os" ) @@ -33,35 +32,18 @@ func init() { } } -func initClient(config *conf.Config) (*clientv3.Client, *client.EtcdHRCHYClient, error) { - clt, err := clientv3.New(clientv3.Config{ - Endpoints: config.EtcdEndPoints, - Username: config.EtcdUsername, - Password: config.EtcdPassword, - }) - if err != nil { - return nil, nil, err - } - - client, err := client.New(clt, config.EtcdRootKey) - if err != nil { - return nil, nil, err - } - return clt, client, client.FormatRootKey() -} - func main() { config, err := conf.Init(configFilepath) if err != nil { panic(err) } - etcdClt, client, err := initClient(config) + client, err := e3ch.NewE3chClient(config) if err != nil { panic(err) } router := gin.Default() - routers.InitRouters(router, etcdClt, client) + routers.InitRouters(router, config, client) router.Run(":" + config.Port) } diff --git a/routers/routers.go b/routers/routers.go index 9740da4..00c3924 100644 --- a/routers/routers.go +++ b/routers/routers.go @@ -4,17 +4,33 @@ import ( "github.com/coreos/etcd/clientv3" "github.com/gin-gonic/gin" "github.com/soyking/e3ch" + "github.com/soyking/e3w/conf" + "github.com/soyking/e3w/e3ch" +) + +const ( + ETCD_USERNAME_HEADER = "X-Etcd-Username" + ETCD_PASSWORD_HEADER = "X-Etcd-Password" ) type e3chHandler func(*gin.Context, *client.EtcdHRCHYClient) (interface{}, error) type groupHandler func(e3chHandler) respHandler -func withE3chGroup(e3chClt *client.EtcdHRCHYClient) groupHandler { +func withE3chGroup(e3chClt *client.EtcdHRCHYClient, config *conf.Config) groupHandler { return func(h e3chHandler) respHandler { return func(c *gin.Context) (interface{}, error) { - // TODO: make new client - return h(c, e3chClt) + clt := e3chClt + if config.Auth { + var err error + username := c.Request.Header.Get(ETCD_USERNAME_HEADER) + password := c.Request.Header.Get(ETCD_PASSWORD_HEADER) + clt, err = e3ch.CloneE3chClient(username, password, e3chClt) + if err != nil { + return nil, err + } + } + return h(c, clt) } } } @@ -27,13 +43,13 @@ func etcdWrapper(h etcdHandler) e3chHandler { } } -func InitRouters(g *gin.Engine, etcdClt *clientv3.Client, client *client.EtcdHRCHYClient) { +func InitRouters(g *gin.Engine, config *conf.Config, e3chClt *client.EtcdHRCHYClient) { g.GET("/", func(c *gin.Context) { c.File("./static/dist/index.html") }) g.Static("/public", "./static/dist") - e3chGroup := withE3chGroup(client) + e3chGroup := withE3chGroup(e3chClt, config) // key/value actions g.GET("/kv/*key", resp(e3chGroup(getKeyHandler)))