Exemple #1
0
func AuthorizedAtHeyService() error {
	authCode := oauth2.SetAuthURLParam("client_key", "demo")
	glog.Infof("oauth login url='%v'", heyOauth2Config.AuthCodeURL("csrf", authCode))

	resp, err := http.Get(heyOauth2Config.AuthCodeURL("csrf", authCode))

	if err != nil {
		glog.Infof("error connect client_id=%v, err=%v", clientId, err)
		return err
	}

	if resp.StatusCode == http.StatusOK {
		glog.Infof("connect success client_id=%v", clientId)
		return nil
	}

	return errors.New("authorization error. unknown reason")
}
Exemple #2
0
func (mw *OAuthMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path == "/oauth2callback" {
		mw.handleOAuth2Callback(w, r)
		return
	}

	_, err := mw.plugin.AuthenticatedUser(r)
	if err != nil {
		if r.URL.Path == "/" {
			log.Println("Not logged in", err)
			url := mw.oauthCfg.AuthCodeURL("", oauth2.SetAuthURLParam("team", mw.bot.Config.TeamID))
			http.Redirect(w, r, url, http.StatusFound)
		} else {
			w.WriteHeader(http.StatusForbidden)
		}
		return
	}

	// Check if session exists, yield a 403 unless we're on the main page
	mw.handler.ServeHTTP(w, r)
}
Exemple #3
0
// Nonce returns an auth code option which requires the ID Token created by the
// OpenID Connect provider to contain the specified nonce.
func Nonce(nonce string) oauth2.AuthCodeOption {
	return oauth2.SetAuthURLParam("nonce", nonce)
}
Exemple #4
0
func (a *authGoogle) AuthCodeUrl() (url, token, secret string) {
	return a.config.AuthCodeURL("", xoauth2.SetAuthURLParam("access_type", "offline")), "", ""

}
Exemple #5
0
// SetPrompt sets the prompt values for the GPlus OAuth call. Use this to
// force users to choose and account every time by passing "select_account",
// for example.
// See https://developers.google.com/identity/protocols/OpenIDConnect#authenticationuriparameters
func (p *Provider) SetPrompt(prompt ...string) {
	if len(prompt) == 0 {
		return
	}
	p.prompt = oauth2.SetAuthURLParam("prompt", strings.Join(prompt, " "))
}
Exemple #6
0
func TestOAuth2ImplicitFlow(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	httpServer, s := newTestServer(ctx, t, func(c *Config) {
		// Enable support for the implicit flow.
		c.SupportedResponseTypes = []string{"code", "token"}
	})
	defer httpServer.Close()

	p, err := oidc.NewProvider(ctx, httpServer.URL)
	if err != nil {
		t.Fatalf("failed to get provider: %v", err)
	}

	var (
		reqDump, respDump []byte
		gotIDToken        bool
		state             = "a_state"
		nonce             = "a_nonce"
	)
	defer func() {
		if !gotIDToken {
			t.Errorf("never got a id token in fragment\n%s\n%s", reqDump, respDump)
		}
	}()

	var oauth2Config *oauth2.Config
	oauth2Server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/callback" {
			q := r.URL.Query()
			if errType := q.Get("error"); errType != "" {
				if desc := q.Get("error_description"); desc != "" {
					t.Errorf("got error from server %s: %s", errType, desc)
				} else {
					t.Errorf("got error from server %s", errType)
				}
				w.WriteHeader(http.StatusInternalServerError)
				return
			}
			// Fragment is checked by the client since net/http servers don't preserve URL fragments.
			// E.g.
			//
			//    r.URL.Fragment
			//
			// Will always be empty.
			w.WriteHeader(http.StatusOK)
			return
		}
		u := oauth2Config.AuthCodeURL(state, oauth2.SetAuthURLParam("response_type", "token"), oidc.Nonce(nonce))
		http.Redirect(w, r, u, http.StatusSeeOther)
	}))

	defer oauth2Server.Close()

	redirectURL := oauth2Server.URL + "/callback"
	client := storage.Client{
		ID:           "testclient",
		Secret:       "testclientsecret",
		RedirectURIs: []string{redirectURL},
	}
	if err := s.storage.CreateClient(client); err != nil {
		t.Fatalf("failed to create client: %v", err)
	}

	src := &nonceSource{nonce: nonce}

	idTokenVerifier := p.Verifier(oidc.VerifyAudience(client.ID), oidc.VerifyNonce(src))

	oauth2Config = &oauth2.Config{
		ClientID:     client.ID,
		ClientSecret: client.Secret,
		Endpoint:     p.Endpoint(),
		Scopes:       []string{oidc.ScopeOpenID, "profile", "email", "offline_access"},
		RedirectURL:  redirectURL,
	}

	checkIDToken := func(u *url.URL) error {
		if u.Fragment == "" {
			return fmt.Errorf("url has no fragment: %s", u)
		}
		v, err := url.ParseQuery(u.Fragment)
		if err != nil {
			return fmt.Errorf("failed to parse fragment: %v", err)
		}
		idToken := v.Get("id_token")
		if idToken == "" {
			return errors.New("no id_token in fragment")
		}
		if _, err := idTokenVerifier.Verify(ctx, idToken); err != nil {
			return fmt.Errorf("failed to verify id_token: %v", err)
		}
		return nil
	}

	httpClient := &http.Client{
		// net/http servers don't preserve URL fragments when passing the request to
		// handlers. The only way to get at that values is to check the redirect on
		// the client side.
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			if len(via) > 10 {
				return errors.New("too many redirects")
			}

			// If we're being redirected back to the client server, inspect the URL fragment
			// for an ID Token.
			u := req.URL.String()
			if strings.HasPrefix(u, oauth2Server.URL) {
				if err := checkIDToken(req.URL); err == nil {
					gotIDToken = true
				} else {
					t.Error(err)
				}
			}
			return nil
		},
	}

	resp, err := httpClient.Get(oauth2Server.URL + "/login")
	if err != nil {
		t.Fatalf("get failed: %v", err)
	}
	if reqDump, err = httputil.DumpRequest(resp.Request, false); err != nil {
		t.Fatal(err)
	}
	if respDump, err = httputil.DumpResponse(resp, true); err != nil {
		t.Fatal(err)
	}
}
Exemple #7
0
package main

import "golang.org/x/oauth2"

const DEFAULT_PORT = 8080

var (
	AuthCodeFlow   = oauth2.SetAuthURLParam("response_type", "code")
	ExpireIn30Days = oauth2.SetAuthURLParam("expires_in", "2592000")
)

type LoginCommand struct{}

func (LoginCommand) Help() string {
	return "login"
}

func (LoginCommand) Synopsis() string {
	return "login command"
}

func (LoginCommand) Run(args []string) int {
	var (
		err    error
		config *Config
		token  *oauth2.Token
		code   string
	)
	if config, err = LoadConfig(); err != nil {
		ERR.Print(err)
		return 1
Exemple #8
0
// AuthCodeURL creates and returns an auth URL which contains an auth code.
func (o *OAuthSession) AuthCodeURL(state string, scopes []string, duration string) string {
	o.OAuthConfig.Scopes = scopes
	return o.OAuthConfig.AuthCodeURL(state, oauth2.AccessTypeOnline, oauth2.SetAuthURLParam("duration", duration))
}
Exemple #9
0
func main() {
	flag.Parse()

	if *clientSecret == "" {
		log.Fatal("-oauth2_client_secret not specified. Register an app at https://dev.fitbit.com to get one.")
	}

	conf := &oauth2.Config{
		ClientID:     "228XTZ",
		ClientSecret: *clientSecret,
		Scopes:       []string{"weight"},
		Endpoint: oauth2.Endpoint{
			AuthURL:  "https://www.fitbit.com/oauth2/authorize",
			TokenURL: "https://api.fitbit.com/oauth2/token",
		},
	}

	c := oauth2.NewClient(
		context.Background(),
		oauth2.ReuseTokenSource(nil, &FileTokenSource{
			Config:    conf,
			CacheFile: *cachePath,
			AuthCode: func() string {
				// Request an access token that expires in 30 days, so that we
				// have plenty of time to refresh it.
				authUrl := conf.AuthCodeURL("state", oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("expires_in", "2592000"))

				fmt.Println("Get auth code from:")
				fmt.Println(authUrl)
				fmt.Println("Enter auth code (or entire URL):")
				sc := bufio.NewScanner(os.Stdin)
				sc.Scan()
				if u, err := url.Parse(sc.Text()); err == nil {
					if c := u.Query().Get("code"); c != "" {
						return c
					}
				}
				return strings.TrimSpace(sc.Text())
			},
		}))

	type weight struct {
		Bmi    float64 `json:"bmi"`
		Date   string  `json:"date"`
		Logid  uint    `json:"logid"`
		Time   string  `json:"time"`
		Weight float64 `json:"weight"`
	}

	type timeSeriesEntry struct {
		DateTime string `json:"dateTime"`
		Value    string `json:"value"`
	}

	type timeSeriesReply struct {
		Entries []timeSeriesEntry `json:"body-weight"`
	}

	type weightReply struct {
		Weights []weight `json:"weight"`
	}

	var timeseries timeSeriesReply
	var weights weightReply

	// The get-time-series reply lacks the time, it only contains the date.
	// Also, it returns one entry for each day of the month with the averaged
	// values instead of the raw measurement data.
	//
	// Therefore, we use get-body-weight repeatedly and just use
	// get-time-series to figure out when the first entry was recorded. We
	// cannot use the user’s registration date since she might backfill data
	// into the system using the API.
	tries := 0
	var response *http.Response
	var err error
	for tries < 2 {
		response, err = c.Get(
			"https://api.fitbit.com/1/user/-/body/weight/date/today/max.json")
		tries += 1
		if err != nil {
			log.Fatal(err)
		}
	}

	decoder := json.NewDecoder(response.Body)
	if err := decoder.Decode(&timeseries); err != nil {
		log.Fatal(err)
	}

	// No entries recorded? Nothing to do.
	if len(timeseries.Entries) == 0 {
		log.Printf("The fitbit API returned no values.")
		os.Exit(0)
	}

	endDate, err := time.Parse("2006-01-02", timeseries.Entries[0].DateTime)
	if err != nil {
		log.Fatalf(`Could not parse timeseries date value "%s": %v`,
			timeseries.Entries[0].DateTime,
			err)
	}

	// Subtract 24 hours to make sure that no value is missed.
	endDate = endDate.Add(-24 * time.Hour)

	for endDate.Before(time.Now()) {
		endDate = endDate.Add(30 * 24 * time.Hour)
		requestUrl := fmt.Sprintf(
			"https://api.fitbit.com/1/user/-/body/log/weight/date/%s/30d.json",
			endDate.Format("2006-01-02"))

		response, err := c.Get(
			requestUrl)
		if err != nil {
			log.Fatal(err)
		}

		decoder := json.NewDecoder(response.Body)
		err = decoder.Decode(&weights)
		if err != nil {
			log.Fatal(err)
		}
		for _, entry := range weights.Weights {
			fmt.Printf("%s %s %.1f\n", entry.Date, entry.Time[0:5], entry.Weight)
		}
	}
}