Skip to content

Commit

Permalink
Try to fix various git issues
Browse files Browse the repository at this point in the history
  • Loading branch information
mirandachrist committed Jun 18, 2019
1 parent d8131de commit d67ec86
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 56 deletions.
8 changes: 4 additions & 4 deletions prow/cmd/deck/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,13 +451,14 @@ func prodOnlyMain(cfg config.Getter, o options, mux *http.ServeMux) *http.ServeM
githubOAuthConfig.InitGitHubOAuthConfig(cookie)

goa := githuboauth.NewAgent(&githubOAuthConfig, logrus.WithField("client", "githuboauth"))
oauthClient := &oauth2.Config{
oauthClient := githuboauth.NewClient(&oauth2.Config{
ClientID: githubOAuthConfig.ClientID,
ClientSecret: githubOAuthConfig.ClientSecret,
RedirectURL: githubOAuthConfig.RedirectURL,
Scopes: githubOAuthConfig.Scopes,
Endpoint: github.Endpoint,
}
},
)

repoSet := make(map[string]bool)
for r := range cfg().Presubmits {
Expand Down Expand Up @@ -1211,6 +1212,5 @@ func handleFavicon(staticFilesLocation string, cfg config.Getter) http.HandlerFu

func isValidatedGitOAuthConfig(githubOAuthConfig *config.GitHubOAuthConfig) bool {
return githubOAuthConfig.ClientID != "" && githubOAuthConfig.ClientSecret != "" &&
githubOAuthConfig.RedirectURL != "" &&
githubOAuthConfig.FinalRedirectURL != ""
githubOAuthConfig.RedirectURL != ""
}
17 changes: 17 additions & 0 deletions prow/cmd/deck/static/common/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,20 @@ export namespace tidehistory {
return link;
}
}

export namespace cookies {
export function getCookieByName(name: string): string {
if (!document.cookie) {
return "";
}
const docCookies = decodeURIComponent(document.cookie).split(";");
for (const cookie of docCookies) {
const c = cookie.trim();
const pref = name + "=";
if (c.indexOf(pref) === 0) {
return c.slice(pref.length);
}
}
return "";
}
}
28 changes: 5 additions & 23 deletions prow/cmd/deck/static/pr/pr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {Context} from '../api/github';
import {Label, PullRequest, UserData} from '../api/pr';
import {Job, JobState} from '../api/prow';
import {Blocker, TideData, TidePool, TideQuery as ITideQuery} from '../api/tide';
import {tidehistory} from '../common/common';
import {cookies, tidehistory} from '../common/common';

declare const tideData: TideData;
declare const allBuilds: Job[];
Expand Down Expand Up @@ -179,24 +179,6 @@ function onLoadQuery(): string {
return "";
}

/**
* Gets cookie by its name.
*/
function getCookieByName(name: string): string {
if (!document.cookie) {
return "";
}
const cookies = decodeURIComponent(document.cookie).split(";");
for (const cookie of cookies) {
const c = cookie.trim();
const pref = name + "=";
if (c.indexOf(pref) === 0) {
return c.slice(pref.length);
}
}
return "";
}

/**
* Creates an alert for merge blocking issues on tide.
*/
Expand Down Expand Up @@ -250,7 +232,7 @@ window.onload = () => {
// Check URL, if the search is empty, adds search query by default format
// ?is:pr state:open query="author:<user_login>"
if (window.location.search === "") {
const login = getCookieByName("github_login");
const login = cookies.getCookieByName("github_login");
const searchQuery = "is:pr state:open author:" + login;
window.location.search = "?query=" + encodeURIComponent(searchQuery);
}
Expand Down Expand Up @@ -301,7 +283,7 @@ function createSearchCard(): HTMLElement {
}, true);
const userBtn = createIcon("person", "Show my open pull requests", ["search-button"], true);
userBtn.addEventListener("click", () => {
const login = getCookieByName("github_login");
const login = cookies.getCookieByName("github_login");
const searchQuery = "is:pr state:open author:" + login;
window.location.search = "?query=" + encodeURIComponent(searchQuery);
});
Expand All @@ -310,7 +292,7 @@ function createSearchCard(): HTMLElement {
actionCtn.id = "search-action";
actionCtn.appendChild(userBtn);
actionCtn.appendChild(refBtn);
actionCtn.appendChild(tidehistory.authorIcon(getCookieByName("github_login")));
actionCtn.appendChild(tidehistory.authorIcon(cookies.getCookieByName("github_login")));

const inputContainer = document.createElement("div");
inputContainer.id = "search-input-ctn";
Expand Down Expand Up @@ -1154,7 +1136,7 @@ function createPRCard(pr: PullRequest, builds: UnifiedContext[] = [], queries: P
* Redirect to initiate github login flow.
*/
function forceGitHubLogin(): void {
window.location.href = window.location.origin + "/github-login";
window.location.href = window.location.origin + "/github-login?dest=%2Fpr";
}

type VagueState = "succeeded" | "failed" | "pending" | "unknown";
Expand Down
19 changes: 17 additions & 2 deletions prow/cmd/deck/static/prow/prow.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import moment from "moment";
import {Job, JobState, JobType} from "../api/prow";
import {cell, icon} from "../common/common";
import {cell, cookies, icon} from "../common/common";
import {FuzzySearch} from './fuzzy-search';
import {JobHistogram, JobSample} from './histogram';

Expand Down Expand Up @@ -397,6 +397,7 @@ function escapeRegexLiteral(s: string): string {
}

function redraw(fz: FuzzySearch): void {
const rerunStatus = getParameterByName("rerun");
const modal = document.getElementById('rerun')!;
const rerunCommand = document.getElementById('rerun-content')!;
window.onclick = (event) => {
Expand Down Expand Up @@ -648,12 +649,18 @@ function redraw(fz: FuzzySearch): void {
max = 2 * 3600;
}
drawJobHistogram(totalJob, jobHistogram, now - (12 * 3600), now, max);
if (rerunStatus != null) {
modal.style.display = "block";
rerunCommand.innerHTML = `Nice try! The direct rerun feature hasn't been implemented yet, so that button does nothing.`;
}

}

function createRerunCell(modal: HTMLElement, rerunElement: HTMLElement, prowjob: string): HTMLTableDataCellElement {
const url = `https://${window.location.hostname}/rerun?prowjob=${prowjob}`;
const url = `/rerun?prowjob=${prowjob}`;
const c = document.createElement("td");
const i = icon.create("refresh", "Show instructions for rerunning this job");
const login = cookies.getCookieByName("github_login");
i.onclick = () => {
modal.style.display = "block";
rerunElement.innerHTML = `kubectl create -f "<a href="${url}">${url}</a>"`;
Expand All @@ -662,6 +669,14 @@ function createRerunCell(modal: HTMLElement, rerunElement: HTMLElement, prowjob:
copyButton.onclick = () => copyToClipboardWithToast(`kubectl create -f "${url}"`);
copyButton.innerHTML = "<i class='material-icons state triggered' style='color: gray'>file_copy</i>";
rerunElement.appendChild(copyButton);
const runButton = document.createElement('a');
runButton.innerHTML = "<button class='mdl-button mdl-js-button'>Run</button>";
if (login === "") {
runButton.href = `/github-login?dest=%2F?rerun=work_in_progress`;
} else {
runButton.href = `/?rerun=work_in_progress`;
}
rerunElement.appendChild(runButton);
};
c.appendChild(i);
c.classList.add("icon-cell");
Expand Down
9 changes: 4 additions & 5 deletions prow/config/githuboauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@ type Cookie struct {
// GitHubOAuthConfig is a config for requesting users access tokens from GitHub API. It also has
// a Cookie Store that retains user credentials deriving from GitHub API.
type GitHubOAuthConfig struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
RedirectURL string `json:"redirect_url"`
Scopes []string `json:"scopes,omitempty"`
FinalRedirectURL string `json:"final_redirect_url"`
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
RedirectURL string `json:"redirect_url"`
Scopes []string `json:"scopes,omitempty"`

CookieStore *sessions.CookieStore `json:"-"`
}
Expand Down
49 changes: 44 additions & 5 deletions prow/githuboauth/githuboauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"encoding/hex"
"fmt"
"net/http"
"net/url"
"time"

"github.com/google/go-github/github"
Expand Down Expand Up @@ -54,13 +55,43 @@ type GitHubClientGetter interface {

// OAuthClient is an interface for a GitHub OAuth client.
type OAuthClient interface {
WithFinalRedirectURL(url string) (OAuthClient, error)
// Exchanges code from GitHub OAuth redirect for user access token.
Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error)
// Returns a URL to GitHub's OAuth 2.0 consent page. The state is a token to protect the user
// from an XSRF attack.
AuthCodeURL(state string, opts ...oauth2.AuthCodeOption) string
}

type client struct {
*oauth2.Config
}

func NewClient(config *oauth2.Config) client {
return client{
config,
}
}

func (cli client) WithFinalRedirectURL(path string) (OAuthClient, error) {
parsedURL, err := url.Parse(cli.RedirectURL)
if err != nil {
return nil, err
}
q := parsedURL.Query()
q.Set("dest", path)
parsedURL.RawQuery = q.Encode()
return NewClient(
&oauth2.Config{
ClientID: cli.ClientID,
ClientSecret: cli.ClientSecret,
RedirectURL: parsedURL.String(),
Scopes: cli.Scopes,
Endpoint: cli.Endpoint,
},
), nil
}

type githubClientGetter struct{}

func (gci *githubClientGetter) GetGitHubClient(accessToken string, dryRun bool) GitHubClientWrapper {
Expand Down Expand Up @@ -92,6 +123,7 @@ func NewAgent(config *config.GitHubOAuthConfig, logger *logrus.Entry) *Agent {
// redirect user to GitHub OAuth end-point for authentication.
func (ga *Agent) HandleLogin(client OAuthClient) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
destPage := r.URL.Query().Get("dest")
stateToken := xsrftoken.Generate(ga.gc.ClientSecret, "", "")
state := hex.EncodeToString([]byte(stateToken))
oauthSession, err := ga.gc.CookieStore.New(r, oauthSessionCookie)
Expand All @@ -108,8 +140,11 @@ func (ga *Agent) HandleLogin(client OAuthClient) http.HandlerFunc {
ga.serverError(w, "Save oauth session", err)
return
}

redirectURL := client.AuthCodeURL(state, oauth2.ApprovalForce, oauth2.AccessTypeOnline)
newClient, err := client.WithFinalRedirectURL(destPage)
if err != nil {
ga.serverError(w, "Failed to parse redirect URL", err)
}
redirectURL := newClient.AuthCodeURL(state, oauth2.ApprovalForce, oauth2.AccessTypeOnline)
http.Redirect(w, r, redirectURL, http.StatusFound)
}
}
Expand All @@ -135,7 +170,7 @@ func (ga *Agent) HandleLogout(client OAuthClient) http.HandlerFunc {
loginCookie.Expires = time.Now().Add(-time.Hour * 24)
http.SetCookie(w, loginCookie)
}
http.Redirect(w, r, ga.gc.FinalRedirectURL, http.StatusFound)
http.Redirect(w, r, r.URL.Host, http.StatusFound)
}
}

Expand All @@ -144,6 +179,10 @@ func (ga *Agent) HandleLogout(client OAuthClient) http.HandlerFunc {
// the final destination in the config, which should be the front-end.
func (ga *Agent) HandleRedirect(client OAuthClient, getter GitHubClientGetter) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
finalRedirectURL, err := r.URL.Parse(r.URL.Query().Get("dest"))
if err != nil {
ga.serverError(w, "Failed to parse final destination from OAuth redirect payload", err)
}
state := r.FormValue("state")
stateTokenRaw, err := hex.DecodeString(state)
if err != nil {
Expand All @@ -163,7 +202,7 @@ func (ga *Agent) HandleRedirect(client OAuthClient, getter GitHubClientGetter) h
}
secretState, ok := oauthSession.Values[stateKey].(string)
if !ok {
ga.serverError(w, "Get secret state", fmt.Errorf("empty string or cannot convert to string"))
ga.serverError(w, "Get secret state", fmt.Errorf("empty string or cannot convert to string. this probably means the options passed to GitHub don't match what was expected"))
return
}
// Validate the state parameter to prevent cross-site attack.
Expand Down Expand Up @@ -219,7 +258,7 @@ func (ga *Agent) HandleRedirect(client OAuthClient, getter GitHubClientGetter) h
Expires: time.Now().Add(time.Hour * 24 * 30),
Secure: true,
})
http.Redirect(w, r, ga.gc.FinalRedirectURL, http.StatusFound)
http.Redirect(w, r, finalRedirectURL.String(), http.StatusFound)
}
}

Expand Down
Loading

0 comments on commit d67ec86

Please sign in to comment.