Ejemplo n.º 1
0
func LinkBitbucket(w http.ResponseWriter, r *http.Request, u *User) error {

	// get settings from database
	settings := database.SettingsMust()

	// bitbucket oauth1 consumer
	var consumer = oauth1.Consumer{
		RequestTokenURL:  "https://bitbucket.org/api/1.0/oauth/request_token/",
		AuthorizationURL: "https://bitbucket.org/!api/1.0/oauth/authenticate",
		AccessTokenURL:   "https://bitbucket.org/api/1.0/oauth/access_token/",
		CallbackURL:      settings.URL().String() + "/auth/login/bitbucket",
		ConsumerKey:      settings.BitbucketKey,
		ConsumerSecret:   settings.BitbucketSecret,
	}

	// get the oauth verifier
	verifier := r.FormValue("oauth_verifier")
	if len(verifier) == 0 {
		// Generate a Request Token
		requestToken, err := consumer.RequestToken()
		if err != nil {
			return err
		}

		// add the request token as a signed cookie
		SetCookie(w, r, "bitbucket_token", requestToken.Encode())

		url, _ := consumer.AuthorizeRedirect(requestToken)
		http.Redirect(w, r, url, http.StatusSeeOther)
		return nil
	}

	// remove bitbucket token data once before redirecting
	// back to the application.
	defer DelCookie(w, r, "bitbucket_token")

	// get the tokens from the request
	requestTokenStr := GetCookie(r, "bitbucket_token")
	requestToken, err := oauth1.ParseRequestTokenStr(requestTokenStr)
	if err != nil {
		return err
	}

	// exchange for an access token
	accessToken, err := consumer.AuthorizeToken(requestToken, verifier)
	if err != nil {
		return err
	}

	// create the Bitbucket client
	client := bitbucket.New(
		settings.BitbucketKey,
		settings.BitbucketSecret,
		accessToken.Token(),
		accessToken.Secret(),
	)

	// get the currently authenticated Bitbucket User
	user, err := client.Users.Current()
	if err != nil {
		return err
	}

	// update the user account
	u.BitbucketLogin = user.User.Username
	u.BitbucketToken = accessToken.Token()
	u.BitbucketSecret = accessToken.Secret()
	if err := database.SaveUser(u); err != nil {
		return err
	}

	http.Redirect(w, r, "/new/bitbucket.org", http.StatusSeeOther)
	return nil
}
Ejemplo n.º 2
0
// Authorize handles Bitbucket API Authorization
func (r *Bitbucket) Authorize(res http.ResponseWriter, req *http.Request) (*model.Login, error) {
	consumer := oauth1.Consumer{
		RequestTokenURL:  "https://bitbucket.org/api/1.0/oauth/request_token/",
		AuthorizationURL: "https://bitbucket.org/!api/1.0/oauth/authenticate",
		AccessTokenURL:   "https://bitbucket.org/api/1.0/oauth/access_token/",
		CallbackURL:      httputil.GetScheme(req) + "://" + httputil.GetHost(req) + "/api/auth/bitbucket.org",
		ConsumerKey:      r.Client,
		ConsumerSecret:   r.Secret,
	}

	// get the oauth verifier
	verifier := req.FormValue("oauth_verifier")
	if len(verifier) == 0 {
		// Generate a Request Token
		requestToken, err := consumer.RequestToken()
		if err != nil {
			return nil, err
		}

		// add the request token as a signed cookie
		httputil.SetCookie(res, req, "bitbucket_token", requestToken.Encode())

		url, _ := consumer.AuthorizeRedirect(requestToken)
		http.Redirect(res, req, url, http.StatusSeeOther)
		return nil, nil
	}

	// remove bitbucket token data once before redirecting
	// back to the application.
	defer httputil.DelCookie(res, req, "bitbucket_token")

	// get the tokens from the request
	requestTokenStr := httputil.GetCookie(req, "bitbucket_token")
	requestToken, err := oauth1.ParseRequestTokenStr(requestTokenStr)
	if err != nil {
		return nil, err
	}

	// exchange for an access token
	accessToken, err := consumer.AuthorizeToken(requestToken, verifier)
	if err != nil {
		return nil, err
	}

	// create the Bitbucket client
	client := bitbucket.New(
		r.Client,
		r.Secret,
		accessToken.Token(),
		accessToken.Secret(),
	)

	// get the currently authenticated Bitbucket User
	user, err := client.Users.Current()
	if err != nil {
		return nil, err
	}

	// put the user data in the common format
	login := model.Login{
		Login:  user.User.Username,
		Access: accessToken.Token(),
		Secret: accessToken.Secret(),
		Name:   user.User.DisplayName,
	}

	email, _ := client.Emails.FindPrimary(user.User.Username)
	if email != nil {
		login.Email = email.Email
	}

	return &login, nil
}
Ejemplo n.º 3
0
func (c *Client) do(method string, path string, params url.Values, values url.Values, v interface{}) error {

	// if this is the guest client then we don't need
	// to sign the request ... we will execute just
	// a simple http request.
	if c == Guest {
		return c.guest(method, path, params, values, v)
	}

	// create the client
	var client = oauth1.Consumer{
		ConsumerKey:    c.ConsumerKey,
		ConsumerSecret: c.ConsumerSecret,
	}

	// create the URI
	uri, err := url.Parse("https://api.bitbucket.org/1.0" + path)
	if err != nil {
		return err
	}

	if params != nil && len(params) > 0 {
		uri.RawQuery = params.Encode()
	}

	// create the access token
	token := oauth1.NewAccessToken(c.AccessToken, c.TokenSecret, nil)

	// create the request
	req := &http.Request{
		URL:        uri,
		Method:     method,
		ProtoMajor: 1,
		ProtoMinor: 1,
		Close:      true,
	}

	if values != nil && len(values) > 0 {
		body := []byte(values.Encode())
		buf := bytes.NewBuffer(body)
		req.Body = ioutil.NopCloser(buf)
	}

	// add the Form data to the request
	// (we'll need this in order to sign the request)
	req.Form = values

	// sign the request
	if err := client.Sign(req, token); err != nil {
		return err
	}

	// make the request using the default http client
	resp, err := DefaultClient.Do(req)
	if err != nil {
		return err
	}

	// Read the bytes from the body (make sure we defer close the body)
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	// Check for an http error status (ie not 200 StatusOK)
	switch resp.StatusCode {
	case 404:
		return ErrNotFound
	case 403:
		return ErrForbidden
	case 401:
		return ErrNotAuthorized
	case 400:
		return ErrBadRequest
	}

	// Unmarshall the JSON response
	if v != nil {
		return json.Unmarshal(body, v)
	}

	return nil
}