// setup routes for serving dynamic content. func setupHandlers() { queueRunner := queue.NewBuildRunner(docker.New(), timeout) queue := queue.Start(workers, queueRunner) var ( github = handler.NewGithubHandler(queue) gitlab = handler.NewGitlabHandler(queue) bitbucket = handler.NewBitbucketHandler(queue) rebuild = handler.NewCommitRebuildHandler(queue) ) m := pat.New() m.Get("/login", handler.ErrorHandler(handler.Login)) m.Post("/login", handler.ErrorHandler(handler.Authorize)) m.Get("/logout", handler.ErrorHandler(handler.Logout)) m.Get("/forgot", handler.ErrorHandler(handler.Forgot)) m.Post("/forgot", handler.ErrorHandler(handler.ForgotPost)) m.Get("/reset", handler.ErrorHandler(handler.Reset)) m.Post("/reset", handler.ErrorHandler(handler.ResetPost)) m.Get("/signup", handler.ErrorHandler(handler.SignUp)) m.Post("/signup", handler.ErrorHandler(handler.SignUpPost)) m.Get("/register", handler.ErrorHandler(handler.Register)) m.Post("/register", handler.ErrorHandler(handler.RegisterPost)) m.Get("/accept", handler.UserHandler(handler.TeamMemberAccept)) // handlers for setting up your GitHub repository m.Post("/new/github.com", handler.UserHandler(handler.RepoCreateGithub)) m.Get("/new/github.com", handler.UserHandler(handler.RepoAddGithub)) // handlers for linking your GitHub account m.Get("/auth/login/github", handler.UserHandler(handler.LinkGithub)) // handlers for setting up your Bitbucket repository m.Post("/new/bitbucket.org", handler.UserHandler(handler.RepoCreateBitbucket)) m.Get("/new/bitbucket.org", handler.UserHandler(handler.RepoAddBitbucket)) // handlers for linking your Bitbucket account m.Get("/auth/login/bitbucket", handler.UserHandler(handler.LinkBitbucket)) // handlers for setting up your GitLab repository m.Post("/new/gitlab", handler.UserHandler(gitlab.Create)) m.Get("/new/gitlab", handler.UserHandler(gitlab.Add)) // handler for linking GitLab account m.Post("/link/gitlab", handler.UserHandler(gitlab.Link)) m.Get("/link/gitlab", handler.UserHandler(gitlab.ReLink)) // handlers for dashboard pages m.Get("/dashboard/team/:team", handler.UserHandler(handler.TeamShow)) m.Get("/dashboard", handler.UserHandler(handler.UserShow)) // handlers for user account management m.Get("/account/user/profile", handler.UserHandler(handler.UserEdit)) m.Post("/account/user/profile", handler.UserHandler(handler.UserUpdate)) m.Get("/account/user/delete", handler.UserHandler(handler.UserDeleteConfirm)) m.Post("/account/user/delete", handler.UserHandler(handler.UserDelete)) m.Get("/account/user/password", handler.UserHandler(handler.UserPass)) m.Post("/account/user/password", handler.UserHandler(handler.UserPassUpdate)) m.Get("/account/user/teams/add", handler.UserHandler(handler.TeamAdd)) m.Post("/account/user/teams/add", handler.UserHandler(handler.TeamCreate)) m.Get("/account/user/teams", handler.UserHandler(handler.UserTeams)) // handlers for team managements m.Get("/account/team/:team/profile", handler.UserHandler(handler.TeamEdit)) m.Post("/account/team/:team/profile", handler.UserHandler(handler.TeamUpdate)) m.Get("/account/team/:team/delete", handler.UserHandler(handler.TeamDeleteConfirm)) m.Post("/account/team/:team/delete", handler.UserHandler(handler.TeamDelete)) m.Get("/account/team/:team/members/add", handler.UserHandler(handler.TeamMemberAdd)) m.Post("/account/team/:team/members/add", handler.UserHandler(handler.TeamMemberInvite)) m.Get("/account/team/:team/members/edit", handler.UserHandler(handler.TeamMemberEdit)) m.Post("/account/team/:team/members/edit", handler.UserHandler(handler.TeamMemberUpdate)) m.Post("/account/team/:team/members/delete", handler.UserHandler(handler.TeamMemberDelete)) m.Get("/account/team/:team/members", handler.UserHandler(handler.TeamMembers)) // handlers for system administration m.Get("/account/admin/settings", handler.AdminHandler(handler.AdminSettings)) m.Post("/account/admin/settings", handler.AdminHandler(handler.AdminSettingsUpdate)) m.Get("/account/admin/users/edit", handler.AdminHandler(handler.AdminUserEdit)) m.Post("/account/admin/users/edit", handler.AdminHandler(handler.AdminUserUpdate)) m.Post("/account/admin/users/delete", handler.AdminHandler(handler.AdminUserDelete)) m.Get("/account/admin/users/add", handler.AdminHandler(handler.AdminUserAdd)) m.Post("/account/admin/users", handler.AdminHandler(handler.AdminUserInvite)) m.Get("/account/admin/users", handler.AdminHandler(handler.AdminUserList)) // handlers for GitHub post-commit hooks m.Post("/hook/github.com", handler.ErrorHandler(github.Hook)) // handlers for Bitbucket post-commit hooks m.Post("/hook/bitbucket.org", handler.ErrorHandler(bitbucket.Hook)) // handlers for GitLab post-commit hooks m.Post("/hook/gitlab", handler.ErrorHandler(gitlab.Hook)) // handlers for first-time installation m.Get("/install", handler.ErrorHandler(handler.Install)) m.Post("/install", handler.ErrorHandler(handler.InstallPost)) // handlers for repository, commits and build details m.Get("/:host/:owner/:name/commit/:commit/build/:label/out.txt", handler.RepoHandler(handler.BuildOut)) m.Post("/:host/:owner/:name/commit/:commit/build/:label/rebuild", handler.RepoAdminHandler(rebuild.CommitRebuild)) m.Get("/:host/:owner/:name/commit/:commit/build/:label", handler.RepoHandler(handler.CommitShow)) m.Post("/:host/:owner/:name/commit/:commit/rebuild", handler.RepoAdminHandler(rebuild.CommitRebuild)) m.Get("/:host/:owner/:name/commit/:commit", handler.RepoHandler(handler.CommitShow)) m.Get("/:host/:owner/:name/tree", handler.RepoHandler(handler.RepoDashboard)) m.Get("/:host/:owner/:name/status.svg", handler.ErrorHandler(handler.Badge)) m.Get("/:host/:owner/:name/settings", handler.RepoAdminHandler(handler.RepoSettingsForm)) m.Get("/:host/:owner/:name/params", handler.RepoAdminHandler(handler.RepoParamsForm)) m.Get("/:host/:owner/:name/badges", handler.RepoAdminHandler(handler.RepoBadges)) m.Get("/:host/:owner/:name/keys", handler.RepoAdminHandler(handler.RepoKeys)) m.Get("/:host/:owner/:name/delete", handler.RepoAdminHandler(handler.RepoDeleteForm)) m.Post("/:host/:owner/:name/delete", handler.RepoAdminHandler(handler.RepoDelete)) m.Get("/:host/:owner/:name", handler.RepoHandler(handler.RepoDashboard)) m.Post("/:host/:owner/:name", handler.RepoHandler(handler.RepoUpdate)) http.Handle("/feed", websocket.Handler(channel.Read)) // no routes are served at the root URL. Instead we will // redirect the user to his/her dashboard page. m.Get("/", http.RedirectHandler("/dashboard", http.StatusSeeOther)) // the first time a page is requested we should record // the scheme and hostname. http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // our multiplexer is a bit finnicky and therefore requires // us to strip any trailing slashes in order to correctly // find and match a route. if r.URL.Path != "/" && strings.HasSuffix(r.URL.Path, "/") { http.Redirect(w, r, r.URL.Path[:len(r.URL.Path)-1], http.StatusSeeOther) return } // standard header variables that should be set, for good measure. w.Header().Add("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate") w.Header().Add("X-Frame-Options", "DENY") w.Header().Add("X-Content-Type-Options", "nosniff") w.Header().Add("X-XSS-Protection", "1; mode=block") // ok, now we're ready to serve the request. m.ServeHTTP(w, r) }) }
// Tests the ability to create GitHub repositories. func Test_GitLabCreate(t *testing.T) { // seed the database with values SetupGitlabFixtures() defer TeardownGitlabFixtures() q := &queue.Queue{} gl := handler.NewGitlabHandler(q) // 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 gitlab 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 := gl.Create(res, &req, user) repo, _ := database.GetRepoSlug(settings.GitlabDomain + "/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.GitlabDomain) 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 := gl.Create(res, &req, user) repo, _ := database.GetRepoSlug(settings.GitlabDomain + "/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 := gl.Create(res, &req, user) Convey("The result is an error", func() { So(err, ShouldNotBeNil) So(err.Error(), ShouldStartWith, "*Gitlab.buildAndExecRequestRaw") }) 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 := gl.Create(res, &req, user) Convey("The result is an error", func() { So(err, ShouldNotBeNil) So(err.Error(), ShouldEqual, "Unable to add Hook to your GitLab 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 := gl.Create(res, &req, user) Convey("The result is an error", func() { So(err, ShouldNotBeNil) So(err.Error(), ShouldEqual, "Unable to add Public Key to your GitLab 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 := gl.Create(res, &req, user) team, _ := database.GetTeamSlug("drone") repo, _ := database.GetRepoSlug(settings.GitlabDomain + "/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 := gl.Create(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 := gl.Create(res, &req, user) Convey("The result is an error", func() { So(err, ShouldNotBeNil) So(err.Error(), ShouldEqual, "Invalid permission to access Team golang.") }) }) }) }