-
Notifications
You must be signed in to change notification settings - Fork 3
/
routes.go
81 lines (63 loc) · 2.02 KB
/
routes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package handlers
import (
"fmt"
"net/http"
"github.com/go-chi/chi"
"github.com/go-chi/jwtauth"
"github.com/go-chi/render"
"github.com/go-social/social"
"github.com/go-social/social/providers"
)
type ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error)
type CallbackHandlerFunc func(w http.ResponseWriter, r *http.Request, creds []social.Credentials, user *social.User, err error)
func Routes(oauthErrorFn ErrorHandlerFunc, oauthCallbackFn CallbackHandlerFunc) http.Handler {
r := chi.NewRouter()
r.Get("/", ListProviders)
r.Route("/{provider}", func(r chi.Router) {
r.Use(ProviderCtx(oauthErrorFn))
r.Get("/", OAuth(oauthErrorFn)) // open
r.Group(func(r chi.Router) {
// secure, via jwt state token
r.Use(jwtauth.Verify(providers.TokenAuth, tokenFromQuery("state")))
r.Use(jwtauth.Authenticator)
r.Get("/callback", OAuthCallback(oauthCallbackFn))
})
})
// TODO: this needs to be secured as well, as
// its a callback router
r.Get("/loopback/{route}", Loopback)
return r
}
func ListProviders(w http.ResponseWriter, r *http.Request) {
plist := []string{}
for id, _ := range providers.Registry {
plist = append(plist, id)
}
// TODO: make payloads for all request / response objects, and render.Render()
render.JSON(w, r, plist)
}
// Loopback redirects the client to another path on our router
func Loopback(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
_, claims, _ := jwtauth.FromContext(ctx)
route := chi.URLParam(r, "route")
providerID, ok := claims["provider"]
if !ok {
render.Status(r, 403) // TODO: defined payload..
render.JSON(w, r, "invalid provider id")
return
}
switch route {
case "googleapi":
redirectURL := fmt.Sprintf("/auth/%s/callback?%s", providerID, r.URL.Query().Encode())
http.Redirect(w, r, redirectURL, 302)
return
}
w.WriteHeader(http.StatusNoContent)
}
func tokenFromQuery(param string) func(r *http.Request) string {
// Get token from query param
return func(r *http.Request) string {
return r.URL.Query().Get(param)
}
}