diff --git a/Gopkg.lock b/Gopkg.lock
index 10183c9..768d3ef 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -29,13 +29,13 @@
branch = "master"
name = "github.com/danielheath/gin-teeny-security"
packages = ["."]
- revision = "0bc769386cc5a75bd79ccdcceaf0f977eeb6990e"
+ revision = "5f00fb6ac0933c2b378c907a3e2a43667afc4289"
[[projects]]
name = "github.com/garyburd/redigo"
packages = ["internal","redis"]
- revision = "34a326de1fea52965fa5ad664d3fc7163dd4b0a1"
- version = "v1.2.0"
+ revision = "d1ed5c67e5794de818ea85e6b522fda02623a484"
+ version = "v1.4.0"
[[projects]]
branch = "master"
@@ -65,7 +65,7 @@
branch = "master"
name = "github.com/golang/protobuf"
packages = ["proto"]
- revision = "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
+ revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
[[projects]]
name = "github.com/gorilla/context"
@@ -107,7 +107,7 @@
branch = "master"
name = "github.com/microcosm-cc/bluemonday"
packages = ["."]
- revision = "68fecaef60268522d2ac3f0123cec9d3bcab7b6e"
+ revision = "542fd4642604d0d0c26112396ce5b1a9d01eee0b"
[[projects]]
name = "github.com/russross/blackfriday"
@@ -137,19 +137,19 @@
branch = "master"
name = "github.com/sergi/go-diff"
packages = ["diffmatchpatch"]
- revision = "2fc9cd33b5f86077aa3e0f442fa0476a9fa9a1dc"
+ revision = "1744e2970ca51c86172c8190fadad617561ed6e7"
[[projects]]
branch = "master"
name = "github.com/shurcooL/github_flavored_markdown"
packages = ["."]
- revision = "cccd3ce4f8e394ae9f87de0bd8b37e00625913d9"
+ revision = "28433ea3fc83827d77424782fefdcd94703366cc"
[[projects]]
branch = "master"
name = "github.com/shurcooL/go"
packages = ["parserutil","printerutil","reflectfind","reflectsource"]
- revision = "c661e953e604ba4a84a3c4e458462a481bd6ce72"
+ revision = "004faa6b0118cf52635363b72b51cdcc297800a2"
[[projects]]
branch = "master"
@@ -161,7 +161,7 @@
branch = "master"
name = "github.com/shurcooL/graphql"
packages = ["ident"]
- revision = "cf6db17b893acfad0ca1929ba6be45bf854790ed"
+ revision = "d0549edd16dceb6939e538fdb1b4f2ec7ee816cc"
[[projects]]
branch = "master"
@@ -179,7 +179,7 @@
branch = "master"
name = "github.com/shurcooL/octiconssvg"
packages = ["."]
- revision = "8c9861b86a08c72d14e0285d0dc313bb6df52295"
+ revision = "38b02129bb6460858e11f90798a3832da1e502bd"
[[projects]]
branch = "master"
@@ -200,28 +200,28 @@
revision = "bd320f5d308e1a3c4314c678d8227a0d72574ae7"
[[projects]]
- branch = "master"
name = "github.com/ugorji/go"
packages = ["codec"]
- revision = "50189f05eaf5a0c17e5084eb8f7fb91e23699840"
+ revision = "9831f2c3ac1068a78f50999a30db84270f647af6"
+ version = "v1.1"
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
packages = ["bcrypt","blowfish"]
- revision = "bd6f299fb381e4c3393d1c4b1f0b94f5e77650c8"
+ revision = "39efaea5da11abd5e2b90a435b1f338cdb94619c"
[[projects]]
branch = "master"
name = "golang.org/x/net"
packages = ["html","html/atom"]
- revision = "01c190206fbdffa42f334f4b2bf2220f50e64920"
+ revision = "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["unix"]
- revision = "4fe5d7925040acd225bf9c7cee65e82d07f06bff"
+ revision = "af50095a40f9041b3b38960738837185c26e9419"
[[projects]]
name = "gopkg.in/go-playground/validator.v8"
@@ -245,7 +245,7 @@
branch = "v2"
name = "gopkg.in/yaml.v2"
packages = ["."]
- revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f"
+ revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4"
[solve-meta]
analyzer-name = "dep"
diff --git a/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go b/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go
index e645ed3..c73c772 100644
--- a/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go
+++ b/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go
@@ -1,9 +1,14 @@
// A GIN middleware providing low-fi security for personal stuff.
+
package gin_teeny_security
import "github.com/gin-gonic/gin"
import "github.com/gin-contrib/sessions"
import "net/http"
+import "net/url"
+import "fmt"
+import "io"
+import "html/template"
// Forces you to a login page until you provide a secret code.
// No CSRF protection, so any script on any page can log you
@@ -12,54 +17,135 @@ import "net/http"
// net can inject stuff. If you're sending open CORS headers this
// would be particularly bad.
func RequiresSecretAccessCode(secretAccessCode, path string) gin.HandlerFunc {
- return func(c *gin.Context) {
- session := sessions.Default(c)
- if c.Request.URL.Path == path {
- if c.Request.Method == "POST" {
- c.Request.ParseForm()
+ cfg := &Config{
+ Path: path,
+ Secret: secretAccessCode,
+ }
- if c.Request.PostForm.Get("secretAccessCode") == secretAccessCode {
- c.Header("Location", "/")
- session.Set("secretAccessCode", secretAccessCode)
- session.Save()
- c.AbortWithStatus(http.StatusFound)
- return
- } else {
- session.Set("secretAccessCode", "")
- session.Save()
- c.Data(http.StatusForbidden, "text/html", []byte(`
-
Login
- Wrong password
-
- `))
- c.Abort()
- return
- }
- } else if c.Request.Method == "GET" {
- c.Data(http.StatusOK, "text/html", []byte(`
- Login
-
- `))
- c.Abort()
+ return cfg.Middleware
+}
+
+type Config struct {
+ Path string // defaults to login
+ Secret string
+ RequireAuth func(*gin.Context) bool // defaults to always requiring auth if unset
+ Template *template.Template
+ SaveKeyToSession func(*gin.Context, string)
+ GetKeyFromSession func(*gin.Context) string
+}
+
+func (c Config) saveKey(ctx *gin.Context, k string) {
+ if c.SaveKeyToSession == nil {
+ c.SaveKeyToSession = DefaultSetSession
+ }
+ c.SaveKeyToSession(ctx, k)
+}
+
+func (c Config) getKey(ctx *gin.Context) string {
+ if c.GetKeyFromSession == nil {
+ c.GetKeyFromSession = DefaultGetSession
+ }
+ return c.GetKeyFromSession(ctx)
+}
+
+func DefaultSetSession(c *gin.Context, secret string) {
+ session := sessions.Default(c)
+ session.Set("secretAccessCode", secret)
+ session.Save()
+}
+
+func DefaultGetSession(c *gin.Context) string {
+ session := sessions.Default(c)
+ str, ok := session.Get("secretAccessCode").(string)
+ if !ok {
+ fmt.Println(session.Get("secretAccessCode"))
+ return ""
+ }
+ return str
+}
+
+func (c Config) path() string {
+ if c.Path == "" {
+ return "/login/"
+ }
+ return c.Path
+}
+
+func (c Config) requireAuth(ctx *gin.Context) bool {
+ if ctx.Request.Header.Get("Authorization") == c.Secret {
+ return false
+ }
+ return c.RequireAuth == nil || c.RequireAuth(ctx)
+}
+
+func (c Config) template() *template.Template {
+ if c.Template == nil {
+ return DEFAULT_LOGIN_PAGE
+ }
+ return c.Template
+}
+
+func (c Config) ExecTemplate(w io.Writer, message, returnUrl string) error {
+ return c.template().Execute(w, LoginPageParams{
+ Message: message,
+ Path: c.path() + "?" + url.Values{"return": []string{returnUrl}}.Encode(),
+ })
+}
+
+type LoginPageParams struct {
+ Message string
+ Path string
+}
+
+var DEFAULT_LOGIN_PAGE = template.Must(template.New("login").Parse(`
+Login
+{{ if .Message }}{{ .Message }}
{{ end }}
+
+`))
+
+func (cfg *Config) Middleware(c *gin.Context) {
+ if c.Request.URL.Path == cfg.path() {
+ returnTo := c.Request.URL.Query().Get("return")
+ if returnTo == "" {
+ returnTo = "/"
+ }
+
+ if c.Request.Method == "POST" {
+ c.Request.ParseForm()
+
+ fmt.Println(c.Request.PostForm.Get("secretAccessCode"))
+ if c.Request.PostForm.Get("secretAccessCode") == cfg.Secret {
+
+ c.Header("Location", returnTo)
+ cfg.saveKey(c, cfg.Secret)
+
+ c.AbortWithStatus(http.StatusFound)
return
} else {
- c.Next()
+ cfg.saveKey(c, "")
+ c.Writer.WriteHeader(http.StatusForbidden)
+ cfg.ExecTemplate(c.Writer, "Wrong Password", returnTo)
+ c.Abort()
return
}
- }
-
- v := session.Get("secretAccessCode")
- if v != secretAccessCode {
- c.Header("Location", path)
- c.AbortWithStatus(http.StatusTemporaryRedirect)
+ } else if c.Request.Method == "GET" {
+ cfg.ExecTemplate(c.Writer, "", returnTo)
+ c.Abort()
+ return
} else {
c.Next()
+ return
}
}
+
+ v := cfg.getKey(c)
+ if cfg.requireAuth(c) && (v != cfg.Secret) {
+ c.Header("Location", cfg.Path+"?"+url.Values{"return": []string{c.Request.URL.RequestURI()}}.Encode())
+ c.AbortWithStatus(http.StatusTemporaryRedirect)
+ } else {
+ c.Next()
+ }
}
diff --git a/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security_test.go b/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security_test.go
new file mode 100644
index 0000000..f16d121
--- /dev/null
+++ b/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security_test.go
@@ -0,0 +1,109 @@
+package gin_teeny_security
+
+import "net/http/cookiejar"
+import "strings"
+import "net/http/httptest"
+import "net/http"
+import "net/url"
+import "log"
+import "io"
+import "io/ioutil"
+import "testing"
+import "github.com/gin-gonic/gin"
+import "github.com/gin-contrib/sessions"
+
+func init() {
+ http.DefaultClient.Jar, _ = cookiejar.New(nil)
+}
+
+func SampleGinApp() *gin.Engine {
+ router := gin.Default()
+ store := sessions.NewCookieStore([]byte("tis a secret"))
+ router.Use(sessions.Sessions("mysession", store))
+ cfg := &Config{
+ Path: "/enter-password/",
+ Secret: "garden",
+ RequireAuth: func(c *gin.Context) bool {
+ return !strings.HasPrefix(c.Request.URL.Path, "/public")
+ },
+ }
+ router.Use(cfg.Middleware)
+
+ router.GET("/private", func(c *gin.Context) {
+ c.Data(http.StatusOK, "application/html", []byte("private stuff"))
+ })
+
+ router.GET("/public", func(c *gin.Context) {
+ c.Data(http.StatusOK, "application/html", []byte("public stuff"))
+ })
+
+ return router
+}
+
+func TestAuth(t *testing.T) {
+ ts := httptest.NewServer(SampleGinApp())
+
+ // Check public stuff can be accessed
+ res, err := http.Get(ts.URL + "/public/")
+ die(err)
+ mustBe("public stuff", readString(res.Body))
+
+ // Check private stuff can't be accessed
+ res, err = http.Get(ts.URL + "/private/")
+ die(err)
+
+ // Check entering the password as an HTTP header instead of a cookie works
+ r, err := http.NewRequest("GET", ts.URL+"/private/", nil)
+ die(err)
+ r.Header.Set("Authorization", "garden")
+ res, err = http.DefaultClient.Do(r)
+ die(err)
+ mustBe("private stuff", readString(res.Body))
+
+ // Check entering the wrong password as an HTTP header instead of a cookie works
+ r, err = http.NewRequest("GET", ts.URL+"/private/", nil)
+ die(err)
+ r.Header.Set("Authorization", "wrong")
+ res, err = http.DefaultClient.Do(r)
+ die(err)
+ mustStartWith("Login
\n\n