Ejemplo n.º 1
0
// 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
}
Ejemplo n.º 2
0
// 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
}
Ejemplo n.º 3
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.º 4
0
func GetLogin(c *gin.Context) {
	remote := remote.FromContext(c)

	tmpUser, err := remote.Login(c.Writer, c.Request)
	if err != nil {
		log.Errorf("failed to authenticate user. %s", err)
		c.Redirect(http.StatusSeeOther, "/login?error=oauth_error")
		return
	}

	if tmpUser == nil {
		return
	}

	u, err := store.GetUserLogin(c, tmpUser.Login)
	if err != nil {
		count, err := store.CountUsers(c)
		if err != nil {
			log.Errorf("cannot register %s. %s", tmpUser.Login, err)
			c.Redirect(http.StatusSeeOther, "/login?error=internal_error")
			return
		}

		// if self-registration is disabled we should
		// return a notAuthorized error. the only exception
		// is if no users exist yet in the system we'll proceed.
		if count != 0 {
			log.Errorf("failed to register %s.", tmpUser.Login)
			c.Redirect(http.StatusSeeOther, "/login?error=access_denied")
			return
		}

		// create the user account
		u = &model.User{}
		u.Login = tmpUser.Login
		u.Hash = base32.StdEncoding.EncodeToString(
			securecookie.GenerateRandomKey(32),
		)

		// insert the user into the database
		if err := store.CreateUser(c, u); err != nil {
			log.Errorf("failed to insert %s. %s", u.Login, err)
			c.Redirect(http.StatusSeeOther, "/login?error=internal_error")
			return
		}

		// if this is the first user, they
		// should be an admin.
		if count == 0 {
			u.Admin = true
		}
	}

	// update the user meta data and authorization
	// data and cache in the datastore.
	u.Token = tmpUser.Token

	if err := store.UpdateUser(c, u); err != nil {
		log.Errorf("failed to update %s. %s", u.Login, err)
		c.Redirect(http.StatusSeeOther, "/login?error=internal_error")
		return
	}

	exp := time.Now().Add(time.Hour * 72).Unix()
	token := token.New(token.SessToken, u.Login)
	tokenstr, err := token.SignExpires(u.Hash, exp)
	if err != nil {
		log.Errorf("failed to create token for %s. %s", u.Login, err)
		c.Redirect(http.StatusSeeOther, "/login?error=internal_error")
		return
	}

	httputil.SetCookie(c.Writer, c.Request, "user_sess", tokenstr)
	redirect := httputil.GetCookie(c.Request, "user_last")
	if len(redirect) == 0 {
		redirect = "/"
	}
	c.Redirect(http.StatusSeeOther, redirect)
}
Ejemplo n.º 5
0
// GetLogin handles authentication to third party, remote services
// and returns the required user data in a standard format.
func (r *Stash) Authorize(w http.ResponseWriter, req *http.Request) (*model.Login, error) {
	var consumer = oauth1.Consumer{
		RequestTokenURL:       r.URL + "/plugins/servlet/oauth/request-token",
		AuthorizationURL:      r.URL + "/plugins/servlet/oauth/authorize",
		AccessTokenURL:        r.URL + "/plugins/servlet/oauth/access-token",
		CallbackURL:           httputil.GetScheme(req) + "://" + httputil.GetHost(req) + "/api/auth/stash.atlassian.com",
		ConsumerKey:           r.Secret,
		ConsumerPrivateKeyPem: r.PrivateKey,
	}

	// 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(w, req, "stash_token", requestToken.Encode())

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

	// remove stash token data once before redirecting
	// back to the application.
	defer httputil.DelCookie(w, req, "stash_token")

	// get the tokens from the request
	requestTokenStr := httputil.GetCookie(req, "stash_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 Stash client
	var client = stash.New(
		r.URL,
		r.Secret,
		accessToken.Token(),
		accessToken.Secret(),
		r.PrivateKey,
	)

	// get the currently authenticated Stash 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.Username,
		Access: accessToken.Token(),
		Secret: accessToken.Secret(),
		//Name:   user.DisplayName,
	}

	return &login, nil
}
Ejemplo n.º 6
0
func GetLogin(c *gin.Context) {

	// when dealing with redirects we may need to adjust the content type. I
	// cannot, however, remember why, so need to revisit this line.
	c.Writer.Header().Del("Content-Type")

	tmpuser, err := remote.Login(c, c.Writer, c.Request)
	if err != nil {
		logrus.Errorf("cannot authenticate user. %s", err)
		c.Redirect(303, "/login?error=oauth_error")
		return
	}
	// this will happen when the user is redirected by the remote provider as
	// part of the authorization workflow.
	if tmpuser == nil {
		return
	}
	config := ToConfig(c)

	// get the user from the database
	u, err := store.GetUserLogin(c, tmpuser.Login)
	if err != nil {

		// if self-registration is disabled we should return a not authorized error
		if !config.Open && !config.IsAdmin(tmpuser) {
			logrus.Errorf("cannot register %s. registration closed", tmpuser.Login)
			c.Redirect(303, "/login?error=access_denied")
			return
		}

		// if self-registration is enabled for whitelisted organizations we need to
		// check the user's organization membership.
		if len(config.Orgs) != 0 {
			teams, terr := remote.Teams(c, tmpuser)
			if terr != nil || config.IsMember(teams) == false {
				logrus.Errorf("cannot verify team membership for %s.", u.Login)
				c.Redirect(303, "/login?error=access_denied")
				return
			}
		}

		// create the user account
		u = &model.User{
			Login:  tmpuser.Login,
			Token:  tmpuser.Token,
			Secret: tmpuser.Secret,
			Email:  tmpuser.Email,
			Avatar: tmpuser.Avatar,
			Hash: base32.StdEncoding.EncodeToString(
				securecookie.GenerateRandomKey(32),
			),
		}

		// insert the user into the database
		if err := store.CreateUser(c, u); err != nil {
			logrus.Errorf("cannot insert %s. %s", u.Login, err)
			c.Redirect(303, "/login?error=internal_error")
			return
		}
	}

	// update the user meta data and authorization data.
	u.Token = tmpuser.Token
	u.Secret = tmpuser.Secret
	u.Email = tmpuser.Email
	u.Avatar = tmpuser.Avatar

	// if self-registration is enabled for whitelisted organizations we need to
	// check the user's organization membership.
	if len(config.Orgs) != 0 {
		teams, terr := remote.Teams(c, u)
		if terr != nil || config.IsMember(teams) == false {
			logrus.Errorf("cannot verify team membership for %s.", u.Login)
			c.Redirect(303, "/login?error=access_denied")
			return
		}
	}

	if err := store.UpdateUser(c, u); err != nil {
		logrus.Errorf("cannot update %s. %s", u.Login, err)
		c.Redirect(303, "/login?error=internal_error")
		return
	}

	exp := time.Now().Add(time.Hour * 72).Unix()
	token := token.New(token.SessToken, u.Login)
	tokenstr, err := token.SignExpires(u.Hash, exp)
	if err != nil {
		logrus.Errorf("cannot create token for %s. %s", u.Login, err)
		c.Redirect(303, "/login?error=internal_error")
		return
	}

	httputil.SetCookie(c.Writer, c.Request, "user_sess", tokenstr)
	redirect := httputil.GetCookie(c.Request, "user_last")
	if len(redirect) == 0 {
		redirect = "/"
	}
	c.Redirect(303, redirect)

}
Ejemplo n.º 7
0
func GetLogin(c *gin.Context) {
	remote := remote.FromContext(c)

	// when dealing with redirects we may need
	// to adjust the content type. I cannot, however,
	// remember why, so need to revisit this line.
	c.Writer.Header().Del("Content-Type")

	tmpuser, open, err := remote.Login(c.Writer, c.Request)
	if err != nil {
		log.Errorf("cannot authenticate user. %s", err)
		c.Redirect(303, "/login?error=oauth_error")
		return
	}
	// this will happen when the user is redirected by
	// the remote provide as part of the oauth dance.
	if tmpuser == nil {
		return
	}

	// get the user from the database
	u, err := store.GetUserLogin(c, tmpuser.Login)
	if err != nil {
		count, err := store.CountUsers(c)
		if err != nil {
			log.Errorf("cannot register %s. %s", tmpuser.Login, err)
			c.Redirect(303, "/login?error=internal_error")
			return
		}

		// if self-registration is disabled we should
		// return a notAuthorized error. the only exception
		// is if no users exist yet in the system we'll proceed.
		if !open && count != 0 {
			log.Errorf("cannot register %s. registration closed", tmpuser.Login)
			c.Redirect(303, "/login?error=access_denied")
			return
		}

		// create the user account
		u = &model.User{}
		u.Login = tmpuser.Login
		u.Token = tmpuser.Token
		u.Secret = tmpuser.Secret
		u.Email = tmpuser.Email
		u.Avatar = tmpuser.Avatar
		u.Hash = crypto.Rand()

		// insert the user into the database
		if err := store.CreateUser(c, u); err != nil {
			log.Errorf("cannot insert %s. %s", u.Login, err)
			c.Redirect(303, "/login?error=internal_error")
			return
		}

		// if this is the first user, they
		// should be an admin.
		if count == 0 {
			u.Admin = true
		}
	}

	// update the user meta data and authorization
	// data and cache in the datastore.
	u.Token = tmpuser.Token
	u.Secret = tmpuser.Secret
	u.Email = tmpuser.Email
	u.Avatar = tmpuser.Avatar

	if err := store.UpdateUser(c, u); err != nil {
		log.Errorf("cannot update %s. %s", u.Login, err)
		c.Redirect(303, "/login?error=internal_error")
		return
	}

	exp := time.Now().Add(time.Hour * 72).Unix()
	token := token.New(token.SessToken, u.Login)
	tokenstr, err := token.SignExpires(u.Hash, exp)
	if err != nil {
		log.Errorf("cannot create token for %s. %s", u.Login, err)
		c.Redirect(303, "/login?error=internal_error")
		return
	}

	httputil.SetCookie(c.Writer, c.Request, "user_sess", tokenstr)
	redirect := httputil.GetCookie(c.Request, "user_last")
	if len(redirect) == 0 {
		redirect = "/"
	}
	c.Redirect(303, redirect)

}