Beispiel #1
0
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
}
Beispiel #2
0
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)
	}
}
Beispiel #3
0
// 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)
}
Beispiel #4
0
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)

	}
}
Beispiel #5
0
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)
}
Beispiel #6
0
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)
	}
}
Beispiel #7
0
// 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
}
Beispiel #8
0
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))
}
Beispiel #9
0
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)
	}
}
Beispiel #10
0
// 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)
}