From ee2f34bef002e0eaf2bc80ef7bc30797d873af3f Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Fri, 4 Nov 2016 11:23:52 +0000 Subject: [PATCH] Add simple authentication blueprint to extend further --- web/auth.go | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++ web/conf.go | 5 --- web/web.go | 19 +-------- 3 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 web/auth.go diff --git a/web/auth.go b/web/auth.go new file mode 100644 index 00000000..b4378b16 --- /dev/null +++ b/web/auth.go @@ -0,0 +1,109 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package web + +import ( + "bytes" + "encoding/base64" + + "github.com/abcum/fibre" + "github.com/abcum/surreal/cnf" + "github.com/abcum/surreal/sql" +) + +func auth() fibre.MiddlewareFunc { + return func(h fibre.HandlerFunc) fibre.HandlerFunc { + return func(c *fibre.Context) error { + + auth := map[string]string{"NS": "", "DB": ""} + c.Set("auth", auth) + + conf := map[string]string{"NS": "", "DB": ""} + c.Set("conf", conf) + + // ------------------------------ + // Deny authentication + // ------------------------------ + + c.Set("kind", sql.AuthNO) + + // ------------------------------ + // Root authentication + // ------------------------------ + + head := c.Request().Header().Get("Authorization") + + if head != "" && head[:5] == "Basic" { + + base, err := base64.StdEncoding.DecodeString(head[6:]) + + if err == nil { + + user := []byte(cnf.Settings.Auth.User) + pass := []byte(cnf.Settings.Auth.Pass) + cred := bytes.SplitN(base, []byte(":"), 2) + + if len(cred) == 2 && bytes.Equal(cred[0], user) && bytes.Equal(cred[1], pass) { + c.Set("kind", sql.AuthKV) + auth["NS"] = "*" // Anything allowed + conf["NS"] = "" // Must specify + auth["DB"] = "*" // Anything allowed + conf["DB"] = "" // Must specify + return h(c) + } + + } + + } + + // ------------------------------ + // Namespace authentication + // ------------------------------ + + // c.Set("kind", sql.AuthNS) + // auth["NS"] = "SPECIFIED" // Not allowed to change + // conf["NS"] = "SPECIFIED" // Not allowed to change + // auth["DB"] = "*" // Anything allowed + // conf["DB"] = "" // Must specify + + // ------------------------------ + // Database authentication + // ------------------------------ + + // c.Set("kind", sql.AuthDB) + // auth["NS"] = "SPECIFIED" // Not allowed to change + // conf["NS"] = "SPECIFIED" // Not allowed to change + // auth["DB"] = "SPECIFIED" // Not allowed to change + // conf["DB"] = "SPECIFIED" // Not allowed to change + + // ------------------------------ + // Scoped authentication + // ------------------------------ + + // c.Set("kind", sql.AuthTB) + // auth["NS"] = "SPECIFIED" // Not allowed to change + // conf["NS"] = "SPECIFIED" // Not allowed to change + // auth["DB"] = "SPECIFIED" // Not allowed to change + // conf["DB"] = "SPECIFIED" // Not allowed to change + + if c.Request().Header().Get("Upgrade") == "websocket" { + return h(c) + } + + return fibre.NewHTTPError(401) + + } + } +} diff --git a/web/conf.go b/web/conf.go index feed76b9..cf6d5204 100644 --- a/web/conf.go +++ b/web/conf.go @@ -23,11 +23,6 @@ func conf() fibre.MiddlewareFunc { return func(h fibre.HandlerFunc) fibre.HandlerFunc { return func(c *fibre.Context) error { - opts := c.Fibre().Opts().(*cnf.Options) - - c.Set("KV", opts.DB.Base) - c.Set("NS", "*") - c.Set("DB", "*") return h(c) diff --git a/web/web.go b/web/web.go index 479743d2..7f76bf8b 100644 --- a/web/web.go +++ b/web/web.go @@ -37,6 +37,7 @@ func Setup(opts *cnf.Options) (err error) { // Setup middleware s.Use(conf()) // Setup conf + s.Use(auth()) // Setup auth s.Use(mw.Logs()) // Log requests s.Use(mw.Fail()) // Catch panics s.Use(mw.Gzip()) // Gzip responses @@ -59,24 +60,6 @@ func Setup(opts *cnf.Options) (err error) { }, })) - // Setup basic authentication - - s.Use(mw.Auth(&mw.AuthOpts{ - User: []byte(opts.Auth.User), - Pass: []byte(opts.Auth.Pass), - }).PathIs("/import", "/export")) - - // Setup special authentication - - s.Use(mw.Sign(&mw.SignOpts{ - Key: []byte(opts.Auth.Token), - Fnc: func(c *fibre.Context, h, d map[string]interface{}) error { - c.Set("NS", d["ns"]) - c.Set("DB", d["db"]) - return nil - }, - }).PathIs("/rpc", "/sql").PathBegsWith("/key")) - // Run the server if len(opts.Cert.Crt) == 0 || len(opts.Cert.Key) == 0 {