From 291a3f80c3e64fee0a8a25b895d0c3761d9acd8c Mon Sep 17 00:00:00 2001 From: Colin Henry Date: Sun, 29 Sep 2019 12:30:24 -0700 Subject: [PATCH] added amore robust user model, and some notes on a subscription based callback redirect --- auth/callback.go | 29 +++++++++++++++++++++++------ auth/config.go | 8 ++++++-- auth/middleware.go | 1 + auth/session.go | 2 ++ auth/user.go | 22 ++++++++++++++++++++++ cmd/auth-demo/main.go | 2 +- cmd/auth-demo/user.html | 4 ++-- 7 files changed, 57 insertions(+), 11 deletions(-) diff --git a/auth/callback.go b/auth/callback.go index c344b1b..c217b93 100644 --- a/auth/callback.go +++ b/auth/callback.go @@ -42,7 +42,7 @@ func NewCallbackHandler(c Config) http.HandlerFunc { } oidcConfig := &oidc.Config{ - ClientID: "ae1e02bTwXA35O3r3Xxk4kbRf31j5ge9", + ClientID: c.ClientID, } idToken, err := authenticator.Provider.Verifier(oidcConfig).Verify(context.TODO(), rawIDToken) @@ -53,22 +53,39 @@ func NewCallbackHandler(c Config) http.HandlerFunc { } // Getting now the userInfo - var profile map[string]interface{} - if err := idToken.Claims(&profile); err != nil { + user := User{} + + // var profile map[string]interface{} + if err := idToken.Claims(&user); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } session.Values["id_token"] = rawIDToken session.Values["access_token"] = token.AccessToken - session.Values["profile"] = profile + session.Values["profile"] = user err = session.Save(r, w) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - // Redirect to logged in page - http.Redirect(w, r, "/user", http.StatusSeeOther) + // if application ID is non existent, and therefore does not have a tenant + // Create or associate? + // Create: + // - Create Tenant + // - Specify plan + // - Specify payment info + // - Associate Tenant + // - by email address domain? + //set tenant ID on application ID in App Metadata on user + + if c.CallbackFunc != nil { + c.CallbackFunc(c, user) + } else { + // Redirect to logged in page + http.Redirect(w, r, "/user", http.StatusSeeOther) + } + } } diff --git a/auth/config.go b/auth/config.go index 95f0f1c..7620186 100644 --- a/auth/config.go +++ b/auth/config.go @@ -10,17 +10,21 @@ type Config struct { ClientID string ClientSecret string CallbackURL string + CallbackFunc CallbackFunc } -func FromEnv() Config { +func FromEnv(c CallbackFunc) Config { return Config{ Domain: os.Getenv("AUTH_DOMAIN"), ClientID: os.Getenv("AUTH_CLIENT_ID"), ClientSecret: os.Getenv("AUTH_CLIENT_SECRET"), CallbackURL: os.Getenv("AUTH_CALLBACK_URL"), + CallbackFunc: c, } } func PrintConfig() { - fmt.Printf("%#v\n", FromEnv()) + fmt.Printf("%#v\n", FromEnv(nil)) } + +type CallbackFunc func(c Config, u User) error diff --git a/auth/middleware.go b/auth/middleware.go index 1295227..03c6105 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -11,6 +11,7 @@ func IsAuthenticated(w http.ResponseWriter, r *http.Request, next http.HandlerFu } if _, ok := session.Values["profile"]; !ok { + //TODO allow customization of redirect http.Redirect(w, r, "/", http.StatusSeeOther) } else { next(w, r) diff --git a/auth/session.go b/auth/session.go index 0315dcd..2381940 100644 --- a/auth/session.go +++ b/auth/session.go @@ -13,5 +13,7 @@ var ( func Init() error { Store = sessions.NewFilesystemStore("", []byte("something-very-secret")) gob.Register(map[string]interface{}{}) + gob.Register(User{}) + return nil } diff --git a/auth/user.go b/auth/user.go index 3e30909..0e7a977 100644 --- a/auth/user.go +++ b/auth/user.go @@ -16,3 +16,25 @@ func UserHandler(w http.ResponseWriter, r *http.Request) { jchenry_http.RenderTemplate(w, "user", session.Values["profile"]) } + +type User struct { + Email string `json:"email"` + FirstName string `json:"given_name"` + LastName string `json:"family_name"` + Picture string `json:"picture"` + Nickname string `json:"nickname"` + AppMetadata AppMetadata `json:"app_metadata"` + + //UserMetadata UserMetadata `json:"user_metadata"` +} + +type AppMetadata struct { + Apps map[string]string // an association between the unique applicationID and the tenantID that the user is associated with + // Apps []struct { + // ApplicationID string + // TenantID string + // } +} + +// type UserMetadata struct { +// } diff --git a/cmd/auth-demo/main.go b/cmd/auth-demo/main.go index 238ec4e..5967603 100644 --- a/cmd/auth-demo/main.go +++ b/cmd/auth-demo/main.go @@ -18,7 +18,7 @@ func StartServer() { auth.PrintConfig() s := jch_http.NewServer(negroni.New()). Static("/public/*filepath", http.Dir("public/")). - Service("", auth.Service(auth.FromEnv())). + Service("", auth.Service(auth.FromEnv(nil))). GET("/", "", http.HandlerFunc(HomeHandler)) port := os.Getenv("PORT") diff --git a/cmd/auth-demo/user.html b/cmd/auth-demo/user.html index 8bdba5c..e327ed3 100644 --- a/cmd/auth-demo/user.html +++ b/cmd/auth-demo/user.html @@ -15,8 +15,8 @@