Example #1
0
func (h RepoAdminHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	user, err := readUser(r)
	if err != nil {
		redirectLogin(w, r)
		return
	}

	// repository name from the URL parameters
	hostParam := r.FormValue(":host")
	userParam := r.FormValue(":owner")
	nameParam := r.FormValue(":name")
	repoName := fmt.Sprintf("%s/%s/%s", hostParam, userParam, nameParam)

	repo, err := database.GetRepoSlug(repoName)
	if err != nil {
		RenderNotFound(w)
		return
	}

	// The User must own the repository OR be a member
	// of the Team that owns the repository.
	if user.ID != repo.UserID {
		if admin, _ := database.IsMemberAdmin(user.ID, repo.TeamID); admin == false {
			RenderNotFound(w)
			return
		}
	}

	if err = h(w, r, user, repo); err != nil {
		log.Print(err)
		RenderError(w, err, http.StatusBadRequest)
	}
}
Example #2
0
// helper function that retrieves the repository based
// on the URL parameters
func readRepo(r *http.Request) (*Repo, error) {
	// get the repo data from the URL parameters
	hostParam := r.FormValue(":host")
	userParam := r.FormValue(":owner")
	nameParam := r.FormValue(":slug")
	repoSlug := fmt.Sprintf("%s/%s/%s", hostParam, userParam, nameParam)

	// get the repo from the database
	return database.GetRepoSlug(repoSlug)
}
Example #3
0
// Display a static badge (svg format) for a specific
// repository and an optional branch.
// TODO this needs to implement basic caching
func Badge(w http.ResponseWriter, r *http.Request) error {
	successParam := r.FormValue("success")
	failureParam := r.FormValue("failure")
	branchParam := r.FormValue("branch")
	hostParam := r.FormValue(":host")
	ownerParam := r.FormValue(":owner")
	nameParam := r.FormValue(":name")
	repoSlug := fmt.Sprintf("%s/%s/%s", hostParam, ownerParam, nameParam)

	// get the repo from the database
	repo, err := database.GetRepoSlug(repoSlug)
	if err != nil {
		http.NotFound(w, r)
		return nil
	}

	// get the default branch for the repository
	// if no branch is provided.
	if len(branchParam) == 0 {
		branchParam = repo.DefaultBranch()
	}

	var badge string

	// get the latest commit from the database
	// for the requested branch
	commit, err := database.GetBranch(repo.ID, branchParam)
	if err != nil {
		http.NotFound(w, r)
		return nil
	}

	switch {
	case commit.Status == "Success" && len(successParam) == 0:
		// if no success image is provided, we serve a
		// badge using the shields.io service
		badge = badgeSuccess
	case commit.Status == "Success" && len(successParam) != 0:
		// otherwise we serve the user defined success badge
		badge = successParam
	case commit.Status == "Failure" && len(failureParam) == 0:
		// if no failure image is provided, we serve a
		// badge using the shields.io service
		badge = badgeFailure
	case commit.Status == "Failure" && len(failureParam) != 0:
		// otherwise we serve the user defined failure badge
		badge = failureParam
	default:
		// otherwise load unknown image
		badge = badgeUnknown
	}

	http.Redirect(w, r, badge, http.StatusSeeOther)
	return nil
}
Example #4
0
func (h PublicHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// repository name from the URL parameters
	hostParam := r.FormValue(":host")
	userParam := r.FormValue(":owner")
	nameParam := r.FormValue(":name")
	repoName := fmt.Sprintf("%s/%s/%s", hostParam, userParam, nameParam)

	repo, err := database.GetRepoSlug(repoName)
	if err != nil || repo == nil {
		RenderNotFound(w)
		return
	}

	h(w, r, repo)
	return
}
Example #5
0
func (h RepoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	// repository name from the URL parameters
	hostParam := r.FormValue(":host")
	userParam := r.FormValue(":owner")
	nameParam := r.FormValue(":name")
	repoName := fmt.Sprintf("%s/%s/%s", hostParam, userParam, nameParam)

	repo, err := database.GetRepoSlug(repoName)
	if err != nil || repo == nil {
		RenderNotFound(w)
		return
	}

	// retrieve the user from the database
	user, err := readUser(r)

	// if the user is not found, we can still
	// serve the page assuming the repository
	// is public.
	switch {
	case err != nil && repo.Private == true:
		redirectLogin(w, r)
		return
	case err != nil && repo.Private == false:
		h(w, r, nil, repo)
		return
	}

	// The User must own the repository OR be a member
	// of the Team that owns the repository OR the repo
	// must not be private.
	if repo.Private && user.ID != repo.UserID {
		if member, _ := database.IsMember(user.ID, repo.TeamID); !member {
			RenderNotFound(w)
			return
		}
	}

	if err = h(w, r, user, repo); err != nil {
		log.Print(err)
		RenderError(w, err, http.StatusBadRequest)
	}
}
Example #6
0
func setupRepo(urlParts []string, payload *Payload) (*Repo, error) {
	println("urlParts: ", urlParts)
	repo, err := database.GetRepoSlug(fmt.Sprintf("%s/%s/%s", urlParts[2], urlParts[3], urlParts[4]))
	if err != nil {
		if err != sql.ErrNoRows {
			return nil, fmt.Errorf("error fetching repo: %s", err)
		}
		fmt.Errorf("Repo does not exist in database. %s", err)

		// urlParts[2] will stay as-is (git.interior.vesseler as it used in url)
		// need to modify payload.Repo.Url so that git clone works
		repo_url := payload.Repo.Url
		if os.Getenv("GOGS_URL") != "" {
			repo_url = fmt.Sprintf("http://%s/%s/%s", os.Getenv("GOGS_URL"), urlParts[3], urlParts[4])
		}

		repo, err = NewRepo(urlParts[2], urlParts[3], urlParts[4], ScmGit, repo_url)
		if err != nil {
			println(err.Error())
			return nil, fmt.Errorf("Repo object could not be created %s", err)
		}
		fmt.Printf("repo struct created\n")
		user, err := database.GetUserEmail(payload.Repo.Owner.Email)
		if err != nil {
			return repo, fmt.Errorf("Repo could not find user with email %s, err= %s", payload.Repo.Owner.Email, err)
		}
		repo.UserID = user.ID
		repo.Private = payload.Repo.Private

		err = database.SaveRepo(repo)
		if err != nil {
			return repo, fmt.Errorf("Repo could not be saved to database. %s", err)
		} else {
			fmt.Printf("repo saved in database\n")
			return repo, nil
		}
	}
	fmt.Printf("repo exists in database\n")
	return repo, nil
}
Example #7
0
// Display a static badge (png format) for a specific
// repository and an optional branch.
// TODO this needs to implement basic caching
func Badge(w http.ResponseWriter, r *http.Request) error {
	branchParam := r.FormValue("branch")
	hostParam := r.FormValue(":host")
	ownerParam := r.FormValue(":owner")
	nameParam := r.FormValue(":name")
	repoSlug := fmt.Sprintf("%s/%s/%s", hostParam, ownerParam, nameParam)

	// get the repo from the database
	repo, err := database.GetRepoSlug(repoSlug)
	if err != nil {
		http.NotFound(w, r)
		return nil
	}

	// get the default branch for the repository
	// if no branch is provided.
	if len(branchParam) == 0 {
		branchParam = repo.DefaultBranch()
	}

	// default badge of "unknown"
	badge := "/img/build_unknown.png"

	// get the latest commit from the database
	// for the requested branch
	commit, err := database.GetBranch(repo.ID, branchParam)
	if err == nil {
		switch commit.Status {
		case "Success":
			badge = "/img/build_success.png"
		case "Failing", "Failure":
			badge = "/img/build_failing.png"
		}
	}

	http.Redirect(w, r, badge, http.StatusSeeOther)
	return nil
}
Example #8
0
// Processes a generic POST-RECEIVE hook and
// attempts to trigger a build.
func Hook(w http.ResponseWriter, r *http.Request) error {

	// if this is a pull request route
	// to a different handler
	if r.Header.Get("X-Github-Event") == "pull_request" {
		PullRequestHook(w, r)
		return nil
	}

	// get the payload of the message
	// this should contain a json representation of the
	// repository and commit details
	payload := r.FormValue("payload")

	// parse the github Hook payload
	hook, err := github.ParseHook([]byte(payload))
	if err != nil {
		println("could not parse hook")
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// make sure this is being triggered because of a commit
	// and not something like a tag deletion or whatever
	if hook.IsTag() || hook.IsGithubPages() ||
		hook.IsHead() == false || hook.IsDeleted() {
		return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
	}

	// get the repo from the URL
	repoId := r.FormValue("id")

	// get the repo from the database, return error if not found
	repo, err := database.GetRepoSlug(repoId)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	// Get the user that owns the repository
	user, err := database.GetUser(repo.UserID)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// Verify that the commit doesn't already exist.
	// We should never build the same commit twice.
	_, err = database.GetCommitHash(hook.Head.Id, repo.ID)
	if err != nil && err != sql.ErrNoRows {
		println("commit already exists")
		return RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
	}

	// we really only need:
	//  * repo owner
	//  * repo name
	//  * repo host (github)
	//  * commit hash
	//  * commit timestamp
	//  * commit branch
	//  * commit message
	//  * commit author
	//  * pull request

	// once we have this data we could just send directly to the queue
	// and let it handle everything else

	commit := &Commit{}
	commit.RepoID = repo.ID
	commit.Branch = hook.Branch()
	commit.Hash = hook.Head.Id
	commit.Status = "Pending"
	commit.Created = time.Now().UTC()

	// extract the author and message from the commit
	// this is kind of experimental, since I don't know
	// what I'm doing here.
	if hook.Head != nil && hook.Head.Author != nil {
		commit.Message = hook.Head.Message
		commit.Timestamp = hook.Head.Timestamp
		commit.SetAuthor(hook.Head.Author.Email)
	} else if hook.Commits != nil && len(hook.Commits) > 0 && hook.Commits[0].Author != nil {
		commit.Message = hook.Commits[0].Message
		commit.Timestamp = hook.Commits[0].Timestamp
		commit.SetAuthor(hook.Commits[0].Author.Email)
	}

	// get the drone.yml file from GitHub
	client := github.New(user.GithubToken)
	content, err := client.Contents.FindRef(repo.Owner, repo.Name, ".drone.yml", commit.Hash)
	if err != nil {
		msg := "No .drone.yml was found in this repository.  You need to add one.\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// decode the content.  Note: Not sure this will ever happen...it basically means a GitHub API issue
	raw, err := content.DecodeContent()
	if err != nil {
		msg := "Could not decode the yaml from GitHub.  Check that your .drone.yml is a valid yaml file.\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// parse the build script
	buildscript, err := script.ParseBuild(raw)
	if err != nil {
		msg := "Could not parse your .drone.yml file.  It needs to be a valid drone yaml file.\n\n" + err.Error() + "\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// save the commit to the database
	if err := database.SaveCommit(commit); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// save the build to the database
	build := &Build{}
	build.Slug = "1" // TODO
	build.CommitID = commit.ID
	build.Created = time.Now().UTC()
	build.Status = "Pending"
	if err := database.SaveBuild(build); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// notify websocket that a new build is pending
	//realtime.CommitPending(repo.UserID, repo.TeamID, repo.ID, commit.ID, repo.Private)
	//realtime.BuildPending(repo.UserID, repo.TeamID, repo.ID, commit.ID, build.ID, repo.Private)

	queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build, Script: buildscript}) //Push(repo, commit, build, buildscript)

	// OK!
	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Example #9
0
func PullRequestHook(w http.ResponseWriter, r *http.Request) {

	// get the payload of the message
	// this should contain a json representation of the
	// repository and commit details
	payload := r.FormValue("payload")

	println("GOT PR HOOK")
	println(payload)

	hook, err := github.ParsePullRequestHook([]byte(payload))
	if err != nil {
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// ignore these
	if hook.Action != "opened" && hook.Action != "synchronize" {
		RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
		return
	}

	// get the repo from the URL
	repoId := r.FormValue("id")

	// get the repo from the database, return error if not found
	repo, err := database.GetRepoSlug(repoId)
	if err != nil {
		RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}

	// Get the user that owns the repository
	user, err := database.GetUser(repo.UserID)
	if err != nil {
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// Verify that the commit doesn't already exist.
	// We should enver build the same commit twice.
	_, err = database.GetCommitHash(hook.PullRequest.Head.Sha, repo.ID)
	if err != nil && err != sql.ErrNoRows {
		RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
		return
	}

	///////////////////////////////////////////////////////

	commit := &Commit{}
	commit.RepoID = repo.ID
	commit.Branch = hook.PullRequest.Head.Ref
	commit.Hash = hook.PullRequest.Head.Sha
	commit.Status = "Pending"
	commit.Created = time.Now().UTC()
	commit.Gravatar = hook.PullRequest.User.GravatarId
	commit.PullRequest = strconv.Itoa(hook.Number)
	commit.Message = hook.PullRequest.Title
	// label := p.PullRequest.Head.Labe

	// get the drone.yml file from GitHub
	client := github.New(user.GithubToken)
	content, err := client.Contents.FindRef(repo.Owner, repo.Name, ".drone.yml", commit.Hash) // TODO should this really be the hash??
	if err != nil {
		println(err.Error())
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// decode the content
	raw, err := content.DecodeContent()
	if err != nil {
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// parse the build script
	buildscript, err := script.ParseBuild(raw)
	if err != nil {
		// TODO if the YAML is invalid we should create a commit record
		// with an ERROR status so that the user knows why a build wasn't
		// triggered in the system
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// save the commit to the database
	if err := database.SaveCommit(commit); err != nil {
		RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}

	// save the build to the database
	build := &Build{}
	build.Slug = "1" // TODO
	build.CommitID = commit.ID
	build.Created = time.Now().UTC()
	build.Status = "Pending"
	if err := database.SaveBuild(build); err != nil {
		RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}

	// notify websocket that a new build is pending
	// TODO we should, for consistency, just put this inside Queue.Add()
	queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build, Script: buildscript})

	// OK!
	RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Example #10
0
// Processes a generic POST-RECEIVE Bitbucket hook and
// attempts to trigger a build.
func (h *BitbucketHandler) Hook(w http.ResponseWriter, r *http.Request) error {
	// get the payload from the request
	payload := r.FormValue("payload")

	// parse the post-commit hook
	hook, err := bitbucket.ParseHook([]byte(payload))
	if err != nil {
		return err
	}

	// get the repo from the URL
	repoId := r.FormValue("id")

	// get the repo from the database, return error if not found
	repo, err := database.GetRepoSlug(repoId)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	// Get the user that owns the repository
	user, err := database.GetUser(repo.UserID)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// Verify that the commit doesn't already exist.
	// We should never build the same commit twice.
	_, err = database.GetCommitHash(hook.Commits[len(hook.Commits)-1].Hash, repo.ID)
	if err != nil && err != sql.ErrNoRows {
		return RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
	}

	commit := &Commit{}
	commit.RepoID = repo.ID
	commit.Branch = hook.Commits[len(hook.Commits)-1].Branch
	commit.Hash = hook.Commits[len(hook.Commits)-1].Hash
	commit.Status = "Pending"
	commit.Created = time.Now().UTC()
	commit.Message = hook.Commits[len(hook.Commits)-1].Message
	commit.Timestamp = time.Now().UTC().String()
	commit.SetAuthor(hook.Commits[len(hook.Commits)-1].Author)

	// get the github settings from the database
	settings := database.SettingsMust()

	// create the Bitbucket client
	client := bitbucket.New(
		settings.BitbucketKey,
		settings.BitbucketSecret,
		user.BitbucketToken,
		user.BitbucketSecret,
	)

	// get the yaml from the database
	raw, err := client.Sources.Find(repo.Owner, repo.Name, commit.Hash, ".drone.yml")
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	// parse the build script
	buildscript, err := script.ParseBuild([]byte(raw.Data), repo.Params)
	if err != nil {
		msg := "Could not parse your .drone.yml file.  It needs to be a valid drone yaml file.\n\n" + err.Error() + "\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// save the commit to the database
	if err := database.SaveCommit(commit); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// save the build to the database
	build := &Build{}
	build.Slug = "1" // TODO
	build.CommitID = commit.ID
	build.Created = time.Now().UTC()
	build.Status = "Pending"
	if err := database.SaveBuild(build); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// send the build to the queue
	h.queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build, Script: buildscript})

	// OK!
	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Example #11
0
func (g *GitlabHandler) Hook(w http.ResponseWriter, r *http.Request) error {
	rID := r.FormValue("id")
	repo, err := database.GetRepoSlug(rID)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	user, err := database.GetUser(repo.UserID)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	payload, _ := ioutil.ReadAll(r.Body)
	parsed, err := gogitlab.ParseHook(payload)
	if err != nil {
		return err
	}
	if parsed.ObjectKind == "merge_request" {
		fmt.Println(string(payload))
		if err := g.PullRequestHook(parsed, repo, user); err != nil {
			return err
		}
		return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
	}

	if len(parsed.After) == 0 {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	_, err = database.GetCommitHash(parsed.After, repo.ID)
	if err != nil && err != sql.ErrNoRows {
		fmt.Println("commit already exists")
		return RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
	}

	commit := &Commit{}
	commit.RepoID = repo.ID
	commit.Branch = parsed.Branch()
	commit.Hash = parsed.After
	commit.Status = "Pending"
	commit.Created = time.Now().UTC()

	head := parsed.Head()
	commit.Message = head.Message
	commit.Timestamp = head.Timestamp
	if head.Author != nil {
		commit.SetAuthor(head.Author.Email)
	} else {
		commit.SetAuthor(parsed.UserName)
	}

	// get the github settings from the database
	settings := database.SettingsMust()

	// get the drone.yml file from GitHub
	client := gogitlab.NewGitlab(settings.GitlabApiUrl, g.apiPath, user.GitlabToken)

	buildscript, err := client.RepoRawFile(ns(repo.Owner, repo.Name), commit.Hash, ".drone.yml")
	if err != nil {
		msg := "No .drone.yml was found in this repository.  You need to add one.\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// save the commit to the database
	if err := database.SaveCommit(commit); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// save the build to the database
	build := &Build{}
	build.Slug = "1" // TODO
	build.CommitID = commit.ID
	build.Created = time.Now().UTC()
	build.Status = "Pending"
	build.BuildScript = string(buildscript)
	if err := database.SaveBuild(build); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	g.queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build})

	// OK!
	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)

}
Example #12
0
// TestGetRepoSlug tests the ability to retrieve a Repo
// from the database by it's Canonical Name.
func TestGetRepoSlug(t *testing.T) {
	Setup()
	defer Teardown()

	repo, err := database.GetRepoSlug("github.com/drone/drone")
	if err != nil {
		t.Error(err)
	}

	if repo.ID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.ID)
	}

	if repo.Slug != "github.com/drone/drone" {
		t.Errorf("Exepected Slug %s, got %s", "github.com/drone/drone", repo.Slug)
	}

	if repo.Host != "github.com" {
		t.Errorf("Exepected Host %s, got %s", "github.com", repo.Host)
	}

	if repo.Owner != "drone" {
		t.Errorf("Exepected Owner %s, got %s", "drone", repo.Owner)
	}

	if repo.Name != "drone" {
		t.Errorf("Exepected Name %s, got %s", "drone", repo.Name)
	}

	if repo.Private != true {
		t.Errorf("Exepected Private %v, got %v", true, repo.Private)
	}

	if repo.Disabled != false {
		t.Errorf("Exepected Private %v, got %v", false, repo.Disabled)
	}

	if repo.SCM != "git" {
		t.Errorf("Exepected Type %s, got %s", "git", repo.SCM)
	}

	if repo.URL != "[email protected]:drone/drone.git" {
		t.Errorf("Exepected URL %s, got %s", "[email protected]:drone/drone.git", repo.URL)
	}

	if repo.Username != "no username" {
		t.Errorf("Exepected Username %s, got %s", "no username", repo.Username)
	}

	if repo.Password != "no password" {
		t.Errorf("Exepected Password %s, got %s", "no password", repo.Password)
	}

	if repo.PublicKey != pubkey {
		t.Errorf("Exepected PublicKey %s, got %s", "public key", repo.PublicKey)
	}

	if repo.PrivateKey != privkey {
		t.Errorf("Exepected PrivateKey %s, got %s", "private key", repo.PrivateKey)
	}

	if repo.UserID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.UserID)
	}

	if repo.TeamID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.TeamID)
	}
}
Example #13
0
// Tests the ability to create GitHub repositories.
func Test_GitHubCreate(t *testing.T) {
	// seed the database with values
	SetupFixtures()
	defer TeardownFixtures()

	// mock request
	req := http.Request{}
	req.Form = url.Values{}

	// get user that will add repositories
	user, _ := database.GetUser(1)
	settings := database.SettingsMust()

	Convey("Given request to setup github repo", t, func() {

		Convey("When repository is public", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "public")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)
			repo, _ := database.GetRepoSlug(settings.GitHubDomain + "/example/public")

			Convey("The repository is created", func() {
				So(err, ShouldBeNil)
				So(repo, ShouldNotBeNil)
				So(repo.ID, ShouldNotEqual, 0)
				So(repo.Owner, ShouldEqual, "example")
				So(repo.Name, ShouldEqual, "public")
				So(repo.Host, ShouldEqual, settings.GitHubDomain)
				So(repo.TeamID, ShouldEqual, 0)
				So(repo.UserID, ShouldEqual, user.ID)
				So(repo.Private, ShouldEqual, false)
				So(repo.SCM, ShouldEqual, "git")
			})
			Convey("The repository is public", func() {
				So(repo.Private, ShouldEqual, false)
			})
		})

		Convey("When repository is private", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "private")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)
			repo, _ := database.GetRepoSlug(settings.GitHubDomain + "/example/private")

			Convey("The repository is created", func() {
				So(err, ShouldBeNil)
				So(repo, ShouldNotBeNil)
				So(repo.ID, ShouldNotEqual, 0)
			})
			Convey("The repository is private", func() {
				So(repo.Private, ShouldEqual, true)
			})
		})

		Convey("When repository is not found", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "notfound")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Unable to find GitHub repository example/notfound.")
			})

			Convey("The repository is not created", func() {
				_, err := database.GetRepoSlug("example/notfound")
				So(err, ShouldNotBeNil)
				So(err, ShouldEqual, sql.ErrNoRows)
			})
		})

		Convey("When repository hook is not writable", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "hookerr")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Unable to add Hook to your GitHub repository.")
			})

			Convey("The repository is not created", func() {
				_, err := database.GetRepoSlug("example/hookerr")
				So(err, ShouldNotBeNil)
				So(err, ShouldEqual, sql.ErrNoRows)
			})
		})

		Convey("When repository ssh key is not writable", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "keyerr")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Unable to add Public Key to your GitHub repository.")
			})

			Convey("The repository is not created", func() {
				_, err := database.GetRepoSlug("example/keyerr")
				So(err, ShouldNotBeNil)
				So(err, ShouldEqual, sql.ErrNoRows)
			})
		})

		Convey("When a team is provided", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "team")
			req.Form.Set("team", "drone")
			res := httptest.NewRecorder()

			// invoke handler
			err := handler.RepoCreateGithub(res, &req, user)
			team, _ := database.GetTeamSlug("drone")
			repo, _ := database.GetRepoSlug(settings.GitHubDomain + "/example/team")

			Convey("The repository is created", func() {
				So(err, ShouldBeNil)
				So(repo, ShouldNotBeNil)
				So(repo.ID, ShouldNotEqual, 0)
			})

			Convey("The team should be set", func() {
				So(repo.TeamID, ShouldEqual, team.ID)
			})
		})

		Convey("When a team is not found", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "public")
			req.Form.Set("team", "faketeam")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Unable to find Team faketeam.")
			})
		})

		Convey("When a team is forbidden", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "public")
			req.Form.Set("team", "golang")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Invalid permission to access Team golang.")
			})
		})
	})
}