// GetCC accepts a request to retrieve the latest build // status for the given repository from the datastore and // in CCTray XML format. // // GET /api/badge/:host/:owner/:name/cc.xml // func GetCC(c web.C, w http.ResponseWriter, r *http.Request) { var ctx = context.FromC(c) var ( host = c.URLParams["host"] owner = c.URLParams["owner"] name = c.URLParams["name"] ) w.Header().Set("Content-Type", "application/xml") repo, err := datastore.GetRepoName(ctx, host, owner, name) if err != nil { w.WriteHeader(http.StatusNotFound) return } commits, err := datastore.GetCommitList(ctx, repo, 1, 0) if err != nil || len(commits) == 0 { w.WriteHeader(http.StatusNotFound) return } var link = httputil.GetURL(r) + "/" + repo.Host + "/" + repo.Owner + "/" + repo.Name var cc = model.NewCC(repo, commits[0], link) xml.NewEncoder(w).Encode(cc) }
// PostHook accepts a post-commit hook and parses the payload // in order to trigger a build. The payload is specified to the // remote system (ie GitHub) and will therefore get parsed by // the appropriate remote plugin. // // POST /api/repos/{host}/{owner}/{name}/branches/{branch}/commits/{commit} // func PostCommit(c web.C, w http.ResponseWriter, r *http.Request) { var ctx = context.FromC(c) var ( branch = c.URLParams["branch"] hash = c.URLParams["commit"] host = c.URLParams["host"] repo = ToRepo(c) remote = remote.Lookup(host) ) commit, err := datastore.GetCommitSha(ctx, repo, branch, hash) if err != nil { w.WriteHeader(http.StatusNotFound) return } if commit.Status == model.StatusStarted || commit.Status == model.StatusEnqueue { w.WriteHeader(http.StatusConflict) return } commit.Status = model.StatusEnqueue commit.Started = 0 commit.Finished = 0 commit.Duration = 0 if err := datastore.PutCommit(ctx, commit); err != nil { w.WriteHeader(http.StatusInternalServerError) return } owner, err := datastore.GetUser(ctx, repo.UserID) if err != nil { w.WriteHeader(http.StatusBadRequest) return } // Request a new token and update user_token, err := remote.GetToken(owner) if user_token != nil { owner.Access = user_token.AccessToken owner.Secret = user_token.RefreshToken owner.TokenExpiry = user_token.Expiry datastore.PutUser(ctx, owner) } else if err != nil { w.WriteHeader(http.StatusBadRequest) return } // drop the items on the queue go worker.Do(ctx, &worker.Work{ User: owner, Repo: repo, Commit: commit, Host: httputil.GetURL(r), }) w.WriteHeader(http.StatusOK) }
// 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 }