diff options
| author | Christine Dodrill <me@christine.website> | 2019-01-12 16:04:16 -0800 |
|---|---|---|
| committer | Christine Dodrill <me@christine.website> | 2019-01-12 16:04:16 -0800 |
| commit | f042c7fcf9989bbcc8ebb95e35c90de8b300e4b3 (patch) | |
| tree | d2df7dc8d6fcdd66a9764a980bfdf8da1557838f /idp/idpmiddleware | |
| parent | f1958d7425466a17c8f4cf6f8c11efe5f5091ad9 (diff) | |
| download | x-f042c7fcf9989bbcc8ebb95e35c90de8b300e4b3.tar.xz x-f042c7fcf9989bbcc8ebb95e35c90de8b300e4b3.zip | |
experiment: idp for indieauth
Diffstat (limited to 'idp/idpmiddleware')
| -rw-r--r-- | idp/idpmiddleware/doc.go | 4 | ||||
| -rw-r--r-- | idp/idpmiddleware/middleware.go | 69 |
2 files changed, 73 insertions, 0 deletions
diff --git a/idp/idpmiddleware/doc.go b/idp/idpmiddleware/doc.go new file mode 100644 index 0000000..e4f06ee --- /dev/null +++ b/idp/idpmiddleware/doc.go @@ -0,0 +1,4 @@ +// Package idpmiddleware is a simple HTTP middleware that protects routes using +// idp(1). This only allows users that the given idp(1) instance is configured. +// to allow. +package idpmiddleware diff --git a/idp/idpmiddleware/middleware.go b/idp/idpmiddleware/middleware.go new file mode 100644 index 0000000..eaec2ce --- /dev/null +++ b/idp/idpmiddleware/middleware.go @@ -0,0 +1,69 @@ +package idpmiddleware + +import ( + "net/http" + "net/url" + "sync" + "time" + + "github.com/pborman/uuid" +) + +// Protect protects a given URL behind your given idp(1) server. +func Protect(idpServer, me, selfURL string) func(next http.Handler) http.Handler { + lock := sync.Mutex{} + codes := map[string]string{} + + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/auth/challenge" { + v := r.URL.Query() + lock.Lock() + defer lock.Unlock() + if cd := v.Get("code"); codes[cd] == cd { + http.SetCookie(w, &http.Cookie{ + Name: "idp", + Value: me, + HttpOnly: true, + Expires: time.Now().Add(900 * time.Hour), + }) + + http.Redirect(w, r, selfURL, http.StatusTemporaryRedirect) + return + } + } + + cookie, err := r.Cookie("idp") + if err != nil { + u, err := url.Parse(idpServer) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + code := uuid.New() + lock.Lock() + codes[code] = code + lock.Unlock() + + u.Path = "/auth" + v := url.Values{} + v.Set("me", me) + v.Set("client_id", selfURL) + v.Set("redirect_uri", selfURL+"/auth/challenge") + v.Set("state", code) + v.Set("response_type", "id") + + http.Redirect(w, r, u.String(), http.StatusTemporaryRedirect) + return + } + + if cookie.Value != me { + http.Error(w, "wrong identity", http.StatusBadRequest) + return + } + + next.ServeHTTP(w, r) + }) + } +} |
