func getUser(r *http.Request) (user common.User, target string, err error) { provider, err := gomniauth.Provider("google") if err != nil { log.Fatal(err) } omap, err := objx.FromURLQuery(r.URL.RawQuery) if err != nil { return } creds, err := provider.CompleteAuth(omap) if err != nil { return } state, err := gomniauth.StateFromParam(omap.Get("state").String()) if err != nil { return } target = state.Get("redirect").String() user, err = provider.GetUser(creds) return }
func callbackHandler(providerName string, auth bool) http.HandlerFunc { if auth != true { return func(w http.ResponseWriter, r *http.Request) {} } return func(w http.ResponseWriter, r *http.Request) { provider, err := gomniauth.Provider(providerName) if err != nil { log.Printf("error getting gomniauth provider") http.Error(w, err.Error(), http.StatusInternalServerError) return } omap, err := objx.FromURLQuery(r.URL.RawQuery) if err != nil { log.Printf("error getting resp from callback") http.Error(w, err.Error(), http.StatusInternalServerError) return } creds, err := provider.CompleteAuth(omap) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } user, userErr := provider.GetUser(creds) if userErr != nil { log.Printf("Failed to get user from Github %s", user) http.Error(w, err.Error(), http.StatusInternalServerError) return } session, err := store.Get(r, sessionName) if err != nil { log.Printf("Failed to get Session %s", user) http.Error(w, err.Error(), http.StatusInternalServerError) return } session.Options = &sessions.Options{ Path: "/", MaxAge: 86400 * 7, HttpOnly: true, } session.Values["userName"] = user.Nickname() session.Values["avatarURL"] = user.AvatarURL() session.Save(r, w) http.Redirect(w, r, os.Getenv("GITHUB_CALLBACK_URL"), http.StatusFound) } }
// CallbackHandler receives callback from github OAuth provider func CallbackHandler(w http.ResponseWriter, r *http.Request) { if !enabled { http.Error(w, "authenticatin disabled", http.StatusBadRequest) return } provider, err := gomniauth.Provider(providerName) if err != nil { glog.Errorf("failed to get authentication provider %s: %v", providerName, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } omap, err := objx.FromURLQuery(r.URL.RawQuery) if err != nil { glog.Errorf("Failed to parse querystring: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } creds, err := provider.CompleteAuth(omap) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } user, userErr := provider.GetUser(creds) if userErr != nil { glog.Errorf("Failed to get user from Github %s", user) http.Error(w, err.Error(), http.StatusInternalServerError) return } session, err := store.Get(r, sessionName) if err != nil { glog.Errorf("Failed to fetch current session: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } session.Options = &sessions.Options{ Path: "/", MaxAge: 86400 * 7, HttpOnly: true, } session.Values["userName"] = user.Nickname() session.Values["avatarURL"] = user.AvatarURL() session.Save(r, w) http.Redirect(w, r, os.Getenv("GITHUB_CALLBACK_URL"), http.StatusFound) }
func callbackHandler(providerName string) http.HandlerFunc { provider, err := gomniauth.Provider(providerName) if err != nil { panic(err) } return func(w http.ResponseWriter, r *http.Request) { omap, err := objx.FromURLQuery(r.URL.RawQuery) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } creds, err := provider.CompleteAuth(omap) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } /* // This code borrowed from goweb example and not fixed. // get the state state, err := gomniauth.StateFromParam(ctx.QueryValue("state")) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // redirect to the 'after' URL afterUrl := state.GetStringOrDefault("after", "error?e=No after parameter was set in the state") */ // load the user user, userErr := provider.GetUser(creds) if userErr != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } data := fmt.Sprintf("%#v", user) io.WriteString(w, data) // redirect //return goweb.Respond.WithRedirect(ctx, afterUrl) } }
func oauth2callback(params martini.Params, s sessions.Session, c martini.Context, w http.ResponseWriter, r *http.Request) { providerName := params["provider"] if providerName == "" { http.Error(w, "Unknown provider", http.StatusBadRequest) return } provider, err := gomniauth.Provider(providerName) if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Printf("ERROR: %s", err) return } omap, err := objx.FromURLQuery(r.URL.RawQuery) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } creds, err := provider.CompleteAuth(omap) if err != nil { s.Delete("username") http.Redirect(w, r, "/signin?error=Access+Denied", http.StatusFound) log.Printf("ERROR: %s", err) return } user, err := provider.GetUser(creds) if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Printf("ERROR: %s", err) return } if strings.HasSuffix(user.Email(), authDomain) { log.Printf("%s authenticated via %s", user.Email(), providerName) s.Set("username", user.Email()) } else { http.Redirect(w, r, "/signin", http.StatusFound) return } http.Redirect(w, r, "/", http.StatusFound) }
func callbackHandler(providerName string) http.HandlerFunc { provider, err := gomniauth.Provider(providerName) if err != nil { panic(err) } return func(w http.ResponseWriter, r *http.Request) { omap, err := objx.FromURLQuery(r.URL.RawQuery) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } creds, err := provider.CompleteAuth(omap) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // load the user user, userErr := provider.GetUser(creds) if userErr != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } log.Printf("Authenticated as %s", user.Email()) sig := aDB.Register(user.Email(), user.Email(), time.Now().AddDate(0, 0, 1)) cookie := http.Cookie{Name: "auth", Value: string(sig.Sig), Expires: sig.Expiration, Path: "/"} http.SetCookie(w, &cookie) // data := fmt.Sprintf("%#v", user) // io.WriteString(w, data) // redirect http.Redirect(w, r, "/", http.StatusFound) } }
// CompleteAuth takes a map of arguments that are used to // complete the authorisation process, completes it, and returns // the appropriate common.Credentials. // // The data must contain an OAuth2KeyCode obtained from the auth // server. func CompleteAuth(tripperFactory common.TripperFactory, data objx.Map, config *common.Config, provider common.Provider) (*common.Credentials, error) { // get the code codeList := data.Get(OAuth2KeyCode).Data() code, ok := codeList.(string) if !ok { if codeList == nil || len(codeList.([]string)) == 0 { return nil, &common.MissingParameterError{ParameterName: OAuth2KeyCode} } code = codeList.([]string)[0] if len(code) == 0 { return nil, &common.MissingParameterError{ParameterName: OAuth2KeyCode} } } client, clientErr := GetClient(tripperFactory, common.EmptyCredentials, provider) if clientErr != nil { return nil, clientErr } params := objx.MSI(OAuth2KeyGrantType, OAuth2GrantTypeAuthorizationCode, OAuth2KeyRedirectUrl, config.Get(OAuth2KeyRedirectUrl).Str(), OAuth2KeyScope, config.Get(OAuth2KeyScope).Str(), OAuth2KeyCode, code, OAuth2KeyClientID, config.Get(OAuth2KeyClientID).Str(), OAuth2KeySecret, config.Get(OAuth2KeySecret).Str()) // post the form response, requestErr := client.PostForm(config.Get(OAuth2KeyTokenURL).Str(), params.URLValues()) if requestErr != nil { return nil, requestErr } // make sure we close the body defer func() { if response.Body != nil { response.Body.Close() } }() // make sure we have an OK response if response.StatusCode != http.StatusOK { return nil, &common.AuthServerError{ ErrorMessage: fmt.Sprintf("Server replied with %s.", response.Status), Response: response, } } content, _, mimeTypeErr := mime.ParseMediaType(response.Header.Get("Content-Type")) if mimeTypeErr != nil { return nil, mimeTypeErr } // prepare the credentials object creds := &common.Credentials{Map: objx.MSI()} body, err := ioutil.ReadAll(response.Body) if err != nil { return nil, err } switch content { case "application/x-www-form-urlencoded", "text/plain": vals, err := objx.FromURLQuery(string(body)) if err != nil { return nil, err } // did an error occur? if len(vals.Get("error").Str()) > 0 { return nil, &common.AuthServerError{ ErrorMessage: vals.Get("error").Str(), Response: response, } } expiresIn, _ := time.ParseDuration(vals.Get(OAuth2KeyExpiresIn).Str() + "s") creds.Set(OAuth2KeyAccessToken, vals.Get(OAuth2KeyAccessToken).Str()) creds.Set(OAuth2KeyRefreshToken, vals.Get(OAuth2KeyRefreshToken).Str()) creds.Set(OAuth2KeyExpiresIn, expiresIn) default: // use JSON var data objx.Map jsonErr := json.Unmarshal(body, &data) if jsonErr != nil { return nil, jsonErr } // handle the time timeDuration := data.Get(OAuth2KeyExpiresIn).Float64() data.Set(OAuth2KeyExpiresIn, time.Duration(timeDuration)*time.Second) // merge this data into the creds creds.MergeHere(data) } return creds, nil }
func main() { usr := hero.User{ UserName: "******", Password: "******", Email: "*****@*****.**", } genericClient := hero.Client{ Name: "simple", UUID: "sampleUUID", Secret: "mysecret", } heroCfg := hero.DefaultConfig() heroURL := "http://localhost:8000" demoserver := "http://localhost:8001" s := hero.NewServer(heroCfg, &hero.SimpleTokenGen{}, nil) s.DropAllTables() s.Migrate() cCliet := genericClient cCliet.RedirectURL = demoserver + "/callback" cUsr := usr s.TestClient(&cUsr, &cCliet) clientCfg := &client.Config{ ProviderName: "hero", ProviderDisplayName: "Hero", AuthURL: fmt.Sprintf("%s%s", heroURL, heroCfg.AuthEndpoint), TokenURL: fmt.Sprintf("%s%s", heroURL, heroCfg.TokenEndpoint), ProfileURL: heroURL + heroCfg.InfoEndpoint, CLientID: genericClient.UUID, CLientSecret: genericClient.Secret, DefaultScope: "user", RedirectURL: fmt.Sprintf("%s/callback", demoserver), } gomniauth.SetSecurityKey("ylqRcG4sLnhgOUIt3hbPKiHULHgrutOkpBNwibeJjL4eZ08zzR6YQ0WPl476Cubo") gomniauth.WithProviders( client.New(clientCfg), ) demo := http.NewServeMux() demo.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) { provider, err := gomniauth.Provider(clientCfg.ProviderName) if err != nil { // w.Write([]byte(err.Error())) // return panic(err) } state := gomniauth.NewState("after", "success") // This code borrowed from goweb example and not fixed. // if you want to request additional scopes from the provider, // pass them as login?scope=scope1,scope2 //options := objx.MSI("scope", ctx.QueryValue("scope")) authUrl, err := provider.GetBeginAuthURL(state, nil) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // redirect http.Redirect(w, r, authUrl, http.StatusFound) }) demo.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) { provider, err := gomniauth.Provider(clientCfg.ProviderName) if err != nil { panic(err) } omap, err := objx.FromURLQuery(r.URL.RawQuery) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } creds, err := provider.CompleteAuth(omap) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } /* // This code borrowed from goweb example and not fixed. // get the state state, err := gomniauth.StateFromParam(ctx.QueryValue("state")) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // redirect to the 'after' URL afterUrl := state.GetStringOrDefault("after", "error?e=No after parameter was set in the state") */ // load the user user, userErr := provider.GetUser(creds) if userErr != nil { http.Error(w, userErr.Error(), http.StatusInternalServerError) return } rst := make(map[string]interface{}) rst["name"] = user.Name() rst["email"] = user.Email() json.NewEncoder(w).Encode(rst) // redirect //return goweb.Respond.WithRedirect(ctx, afterUrl) }) go http.ListenAndServe(":8000", s) log.Println(" visit server at " + demoserver + "/login") log.Fatal(http.ListenAndServe(":8001", demo)) }
func loginHandler(w http.ResponseWriter, r *http.Request) { segs := strings.Split(r.URL.Path, "/") action := segs[2] provider := segs[3] switch action { case "callback": providerobj, err := gomniauth.Provider(provider) log.Println("providerobj: ", providerobj) if err != nil { log.Fatalln("Error when trying to get provider", provider, "-", err) } omap, err := objx.FromURLQuery(r.URL.RawQuery) log.Println(omap) if err != nil { log.Fatalln("Error when trying to get object from query", provider, "-", err) } creds, err := providerobj.CompleteAuth(omap) log.Println("creds: ", creds, err) if err != nil { log.Fatalln("Error when trying to complete auth for", provider, "-", err) } log.Println("retrieving user") user, err := providerobj.GetUser(creds) log.Println("user: "******"Error when trying to get user from", provider, "-", err) } m := md5.New() io.WriteString(m, strings.ToLower(user.Name())) userId := fmt.Sprintf("%x", m.Sum(nil)) authCookieValue := objx.New(map[string]interface{}{ "userid": userId, "name": user.Name(), "avatar_url": user.AvatarURL(), "email": user.Email(), }).MustBase64() http.SetCookie(w, &http.Cookie{ Name: "auth", Value: authCookieValue, Path: "/"}) w.Header()["Location"] = []string{"/chat"} w.WriteHeader(http.StatusTemporaryRedirect) case "login": providerobj, err := gomniauth.Provider(provider) if err != nil { log.Fatalln("Error when trying to get the provider", provider, "-", err) } loginUrl, err := providerobj.GetBeginAuthURL(nil, nil) if err != nil { log.Fatalln("error when trying to GetBeginAuthURL for", provider, "-", err) } w.Header().Set("Location", loginUrl) w.WriteHeader(http.StatusTemporaryRedirect) default: w.WriteHeader(http.StatusNotFound) fmt.Fprintf(w, "Auth action %s not supported", action) } }
// parseParams processes the parameter string and returns a // map of the keys and values. func parseParams(s string) (objx.Map, error) { return objx.FromURLQuery(s) }