diff --git a/.gitignore b/.gitignore index 1d74e21..21be33c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ +cmd/sub-demo/sub-demo +cmd/auth-demo/auth-demo .vscode/ diff --git a/auth/callback.go b/auth/callback.go index 0b02544..06266b6 100644 --- a/auth/callback.go +++ b/auth/callback.go @@ -11,7 +11,7 @@ import ( func NewCallbackHandler(c Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - session, err := Store.Get(r, "auth-session") + session, err := Store.Get(r, SessionName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/auth/config.go b/auth/config.go index a4c731b..e53329c 100644 --- a/auth/config.go +++ b/auth/config.go @@ -6,20 +6,26 @@ import ( ) type Config struct { - Domain string - ClientID string - ClientSecret string - CallbackURL string - RedirectURL string + Domain string + ClientID string + ClientSecret string + ManagementClientID string + ManagementClientSecret string + + CallbackURL string + RedirectURL string } func FromEnv() 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"), - RedirectURL: "/user", + Domain: os.Getenv("AUTH_DOMAIN"), + ClientID: os.Getenv("AUTH_CLIENT_ID"), + ClientSecret: os.Getenv("AUTH_CLIENT_SECRET"), + ManagementClientID: os.Getenv("AUTH_MGMT_CLIENT_ID"), + ManagementClientSecret: os.Getenv("AUTH_MGMT_CLIENT_SECRET"), + + CallbackURL: os.Getenv("AUTH_CALLBACK_URL"), + RedirectURL: "/user", } } diff --git a/auth/login.go b/auth/login.go index 673248a..5312158 100644 --- a/auth/login.go +++ b/auth/login.go @@ -19,7 +19,7 @@ func NewLoginHandler(c Config) http.HandlerFunc { } state := base64.StdEncoding.EncodeToString(b) - session, err := Store.Get(r, "auth-session") + session, err := Store.Get(r, SessionName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/auth/logout.go b/auth/logout.go index 75c66ac..497851a 100644 --- a/auth/logout.go +++ b/auth/logout.go @@ -7,20 +7,37 @@ import ( func LogoutHandler(w http.ResponseWriter, r *http.Request) { + if cook, err := r.Cookie(SessionName); err == nil { + cook.MaxAge = -1 + http.SetCookie(w, cook) + } + domain := "dev-pb4s8m55.auth0.com" - var Url *url.URL - Url, err := url.Parse("https://" + domain) + // var Url *url.URL + URL, err := url.Parse("https://" + domain) if err != nil { panic(err.Error()) } - Url.Path += "/v2/logout" + session, err := Store.Get(r, SessionName) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + session.Options.MaxAge = -1 + + err = session.Save(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + + URL.Path += "/v2/logout" parameters := url.Values{} parameters.Add("returnTo", "http://localhost:3000") parameters.Add("client_id", "ae1e02bTwXA35O3r3Xxk4kbRf31j5ge9") - Url.RawQuery = parameters.Encode() + URL.RawQuery = parameters.Encode() - http.Redirect(w, r, Url.String(), http.StatusTemporaryRedirect) + http.Redirect(w, r, URL.String(), http.StatusTemporaryRedirect) } diff --git a/auth/middleware.go b/auth/middleware.go index 03c6105..4e918b8 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -4,7 +4,7 @@ import "net/http" func IsAuthenticated(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { - session, err := Store.Get(r, "auth-session") + session, err := Store.Get(r, SessionName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/auth/service.go b/auth/service.go index d7e0cf3..ef01116 100644 --- a/auth/service.go +++ b/auth/service.go @@ -5,6 +5,7 @@ import ( "github.com/codegangsta/negroni" jch_http "github.com/jchenry/jchenry/http" + "gopkg.in/auth0.v1/management" ) func Service(c Config) ServiceInstance { @@ -25,3 +26,15 @@ func (si ServiceInstance) Register(uriBase string, s *jch_http.Server) { negroni.Wrap(http.HandlerFunc(UserHandler)), )) } + +func (si ServiceInstance) UpdateUser(u User) error { + + m, err := management.New(si.c.Domain, si.c.ManagementClientID, si.c.ManagementClientSecret) + if err != nil { + return err + } + + um := management.NewUserManager(m) + + return um.Update(u.ID, &management.User{AppMetadata: u.Apps}) +} diff --git a/auth/session.go b/auth/session.go index 2381940..287d1b7 100644 --- a/auth/session.go +++ b/auth/session.go @@ -6,14 +6,14 @@ import ( "github.com/gorilla/sessions" ) +const SessionName = "auth-session" + var ( Store *sessions.FilesystemStore ) 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 0e7a977..225d4ff 100644 --- a/auth/user.go +++ b/auth/user.go @@ -8,7 +8,7 @@ import ( func UserHandler(w http.ResponseWriter, r *http.Request) { - session, err := Store.Get(r, "auth-session") + session, err := Store.Get(r, SessionName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -18,23 +18,16 @@ func UserHandler(w http.ResponseWriter, r *http.Request) { } 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"` + ID string `json:"sub"` + Email string `json:"email"` + FirstName string `json:"given_name"` + LastName string `json:"family_name"` + Picture string `json:"picture"` + Nickname string `json:"nickname"` + Apps map[string]interface{} `json:"app_metadata,omitempty"` //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/sub-demo/main.go b/cmd/sub-demo/main.go index 77ccd7f..ac33afe 100644 --- a/cmd/sub-demo/main.go +++ b/cmd/sub-demo/main.go @@ -18,10 +18,12 @@ func main() { func StartServer() { auth.PrintConfig() payments.PrintConfig() + + auth_service := auth.Service(auth.FromEnv()) s := jch_http.NewServer(negroni.New()). Static("/public/*filepath", http.Dir("public/")). - Service("", auth.Service(auth.FromEnv())). - Service("", payments.Service(payments.FromEnv())). + Service("", auth_service). + Service("", payments.Service(payments.FromEnv(), &auth_service)). GET("/", "", http.HandlerFunc(HomeHandler)) port := os.Getenv("PORT") diff --git a/cmd/sub-demo/run.sh b/cmd/sub-demo/run.sh index 85406e3..c95d2ac 100755 --- a/cmd/sub-demo/run.sh +++ b/cmd/sub-demo/run.sh @@ -3,6 +3,8 @@ AUTH_DOMAIN="https://dev-pb4s8m55.auth0.com/" \ AUTH_CLIENT_ID="ae1e02bTwXA35O3r3Xxk4kbRf31j5ge9" \ AUTH_CLIENT_SECRET="NFC5KYeM9GA2z0ptvzKPo9jmkQDRjx_WcsWyK0hzOJmr1CykS9cEmTcNh0-hKiMd" \ AUTH_CALLBACK_URL="http://localhost:3000/callback" \ +AUTH_MGMT_CLIENT_ID="0SpgXDo7HleFZ6NH9ds2t2vkntEzgYqy" \ +AUTH_MGMT_CLIENT_SECRET="DhOE1JqO7A2uosadjuyCluK5P3NlxOf4V9mPkEDy4gDO_lYnMffzYfVpgcINvzfr" \ STRIPE_KEY="sk_test_3yIcJl5ev3WfFZ4HNbTMqWv800B26e0c4V" \ STRIPE_PRODUCT_ID="prod_FtzugcD89mNVhp" \ ./sub-demo \ No newline at end of file diff --git a/cmd/sub-demo/subscription.html b/cmd/sub-demo/subscription.html index e0df646..f30daa1 100644 --- a/cmd/sub-demo/subscription.html +++ b/cmd/sub-demo/subscription.html @@ -10,26 +10,114 @@ + +