示例#1
0
文件: gogs.go 项目: armab/drone
// Authorize handles Gogs authorization
func (r *Gogs) Authorize(res http.ResponseWriter, req *http.Request) (*model.Login, error) {
	var username = req.FormValue("username")
	var password = req.FormValue("password")
	var client = gogs.NewClient(r.URL, "")

	// try to fetch drone token if it exists
	var accessToken = ""
	tokens, err := client.ListAccessTokens(username, password)
	if err != nil {
		return nil, err
	}
	for _, token := range tokens {
		if token.Name == "drone" {
			accessToken = token.Sha1
			break
		}
	}

	// if drone token not found, create it
	if accessToken == "" {
		token, err := client.CreateAccessToken(username, password, gogs.CreateAccessTokenOption{Name: "drone"})
		if err != nil {
			return nil, err
		}
		accessToken = token.Sha1
	}

	// update client
	client = gogs.NewClient(r.URL, accessToken)

	// fetch user information
	user, err := client.GetUserInfo(username)
	if err != nil {
		return nil, err
	}

	var login = new(model.Login)
	login.Name = user.FullName
	login.Email = user.Email
	login.Access = accessToken
	login.Login = username
	return login, nil
}
示例#2
0
文件: github.go 项目: armab/drone
// Authorize handles GitHub API Authorization.
func (r *GitHub) Authorize(res http.ResponseWriter, req *http.Request) (*model.Login, error) {
	var config = &oauth.Config{
		ClientId:     r.Client,
		ClientSecret: r.Secret,
		Scope:        DefaultScope,
		AuthURL:      fmt.Sprintf("%s/login/oauth/authorize", r.URL),
		TokenURL:     fmt.Sprintf("%s/login/oauth/access_token", r.URL),
		RedirectURL:  fmt.Sprintf("%s/api/auth/%s", httputil.GetURL(req), r.GetKind()),
	}

	// get the OAuth code
	var code = req.FormValue("code")
	var state = req.FormValue("state")
	if len(code) == 0 {
		var random = GetRandom()
		httputil.SetCookie(res, req, "github_state", random)
		http.Redirect(res, req, config.AuthCodeURL(random), http.StatusSeeOther)
		return nil, nil
	}

	cookieState := httputil.GetCookie(req, "github_state")
	httputil.DelCookie(res, req, "github_state")
	if cookieState != state {
		return nil, fmt.Errorf("Error matching state in OAuth2 redirect")
	}

	var trans = &oauth.Transport{Config: config}
	var token, err = trans.Exchange(code)
	if err != nil {
		return nil, fmt.Errorf("Error exchanging token. %s", err)
	}

	var client = NewClient(r.API, token.AccessToken, r.SkipVerify)
	var useremail, errr = GetUserEmail(client)
	if errr != nil {
		return nil, fmt.Errorf("Error retrieving user or verified email. %s", errr)
	}

	if len(r.Orgs) > 0 {
		allowedOrg, err := UserBelongsToOrg(client, r.Orgs)
		if err != nil {
			return nil, fmt.Errorf("Could not check org membership. %s", err)
		}
		if !allowedOrg {
			return nil, fmt.Errorf("User does not belong to correct org. Must belong to %v", r.Orgs)
		}
	}

	var login = new(model.Login)
	login.ID = int64(*useremail.ID)
	login.Access = token.AccessToken
	login.Login = *useremail.Login
	login.Email = *useremail.Email
	if useremail.Name != nil {
		login.Name = *useremail.Name
	}

	return login, nil
}
示例#3
0
文件: gitlab.go 项目: armab/drone
// Authorize handles authentication with thrid party remote systems,
// such as github or bitbucket, and returns user data.
func (r *Gitlab) Authorize(res http.ResponseWriter, req *http.Request) (*model.Login, error) {
	host := httputil.GetURL(req)
	config := NewOauthConfig(r, host)

	var code = req.FormValue("code")
	var state = req.FormValue("state")

	if len(code) == 0 {
		var random = GetRandom()
		httputil.SetCookie(res, req, "gitlab_state", random)
		http.Redirect(res, req, config.AuthCodeURL(random), http.StatusSeeOther)
		return nil, nil
	}

	cookieState := httputil.GetCookie(req, "gitlab_state")
	httputil.DelCookie(res, req, "gitlab_state")
	if cookieState != state {
		return nil, fmt.Errorf("Error matching state in OAuth2 redirect")
	}

	var trans = &oauth.Transport{
		Config: config,
		Transport: &http.Transport{
			Proxy:           http.ProxyFromEnvironment,
			TLSClientConfig: &tls.Config{InsecureSkipVerify: r.SkipVerify},
		},
	}
	var token, err = trans.Exchange(code)
	if err != nil {
		return nil, fmt.Errorf("Error exchanging token. %s", err)
	}

	var client = NewClient(r.url, token.AccessToken, r.SkipVerify)

	var user, errr = client.CurrentUser()
	if errr != nil {
		return nil, fmt.Errorf("Error retrieving current user. %s", errr)
	}

	var login = new(model.Login)
	login.ID = int64(user.Id)
	login.Access = token.AccessToken
	login.Secret = token.RefreshToken
	login.Login = user.Username
	login.Email = user.Email
	return login, nil
}
示例#4
0
文件: bitbucket.go 项目: armab/drone
// 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
}