func ShowRepo(c *gin.Context) { user := session.User(c) repo := session.Repo(c) builds, _ := store.GetBuildList(c, repo) groups := []*model.BuildGroup{} var curr *model.BuildGroup for _, build := range builds { date := time.Unix(build.Created, 0).Format("Jan 2 2006") if curr == nil || curr.Date != date { curr = &model.BuildGroup{} curr.Date = date groups = append(groups, curr) } curr.Builds = append(curr.Builds, build) } httputil.SetCookie(c.Writer, c.Request, "user_last", repo.FullName) c.HTML(200, "repo.html", gin.H{ "User": user, "Repo": repo, "Builds": builds, "Groups": groups, }) }
// 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 }
func ShowBuild(c *gin.Context) { user := session.User(c) repo := session.Repo(c) num, _ := strconv.Atoi(c.Param("number")) seq, _ := strconv.Atoi(c.Param("job")) if seq == 0 { seq = 1 } build, err := store.GetBuildNumber(c, repo, num) if err != nil { c.AbortWithError(404, err) return } jobs, err := store.GetJobList(c, build) if err != nil { c.AbortWithError(404, err) return } var job *model.Job for _, j := range jobs { if j.Number == seq { job = j break } } httputil.SetCookie(c.Writer, c.Request, "user_last", repo.FullName) var csrf string if user != nil { csrf, _ = token.New( token.CsrfToken, user.Login, ).Sign(user.Hash) } c.HTML(200, "build.html", gin.H{ "User": user, "Repo": repo, "Build": build, "Jobs": jobs, "Job": job, "Csrf": csrf, }) }
// 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 }
// 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 }
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) }
// 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 }
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) c.Redirect(303, "/") }
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) }