Exemplo n.º 1
0
// Refresh refreshes an oauth token and expiration for the given
// user. It returns true if the token was refreshed, false if the
// token was not refreshed, and error if it failed to refersh.
func (bb *Bitbucket) Refresh(user *model.User) (bool, error) {
	config := &oauth2.Config{
		ClientID:     bb.Client,
		ClientSecret: bb.Secret,
		Endpoint:     bitbucket.Endpoint,
	}

	// creates a token source with just the refresh token.
	// this will ensure an access token is automatically
	// requested.
	source := config.TokenSource(
		oauth2.NoContext, &oauth2.Token{RefreshToken: user.Secret})

	// requesting the token automatically refreshes and
	// returns a new access token.
	token, err := source.Token()
	if err != nil || len(token.AccessToken) == 0 {
		return false, err
	}

	// update the user to include tne new access token
	user.Token = token.AccessToken
	user.Secret = token.RefreshToken
	user.Expiry = token.Expiry.UTC().Unix()
	return true, nil
}
Exemplo n.º 2
0
// Login authenticates the session and returns the
// remote user details.
func (bb *Bitbucket) Login(res http.ResponseWriter, req *http.Request) (*model.User, bool, error) {

	config := &oauth2.Config{
		ClientID:     bb.Client,
		ClientSecret: bb.Secret,
		Endpoint:     bitbucket.Endpoint,
		RedirectURL:  fmt.Sprintf("%s/authorize", httputil.GetURL(req)),
	}

	// get the OAuth code
	var code = req.FormValue("code")
	if len(code) == 0 {
		http.Redirect(res, req, config.AuthCodeURL("drone"), http.StatusSeeOther)
		return nil, false, nil
	}

	var token, err = config.Exchange(oauth2.NoContext, code)
	if err != nil {
		return nil, false, fmt.Errorf("Error exchanging token. %s", err)
	}

	client := NewClient(config.Client(oauth2.NoContext, token))
	curr, err := client.FindCurrent()
	if err != nil {
		return nil, false, err
	}

	// convers the current bitbucket user to the
	// common drone user structure.
	user := model.User{}
	user.Login = curr.Login
	user.Token = token.AccessToken
	user.Secret = token.RefreshToken
	user.Expiry = token.Expiry.UTC().Unix()
	user.Avatar = curr.Links.Avatar.Href

	// gets the primary, confirmed email from bitbucket
	emails, err := client.ListEmail()
	if err != nil {
		return nil, false, err
	}
	for _, email := range emails.Values {
		if email.IsPrimary && email.IsConfirmed {
			user.Email = email.Email
			break
		}
	}

	// if the installation is restricted to a subset
	// of organizations, get the orgs and verify the
	// user is a member.
	if len(bb.Orgs) != 0 {
		resp, err := client.ListTeams(&ListTeamOpts{Page: 1, PageLen: 100, Role: "member"})
		if err != nil {
			return nil, false, err
		}

		var member bool
		for _, team := range resp.Values {
			for _, team_ := range bb.Orgs {
				if team.Login == team_ {
					member = true
					break
				}
			}
		}

		if !member {
			return nil, false, fmt.Errorf("User does not belong to correct org. Must belong to %v", bb.Orgs)
		}
	}

	return &user, bb.Open, nil
}