func PatchUser(c *gin.Context) { me := session.User(c) in := &model.User{} err := c.Bind(in) if err != nil { c.AbortWithStatus(http.StatusBadRequest) return } user, err := store.GetUserLogin(c, c.Param("login")) if err != nil { c.AbortWithStatus(http.StatusNotFound) return } user.Admin = in.Admin user.Active = in.Active // cannot update self if me.ID == user.ID { c.AbortWithStatus(http.StatusForbidden) return } err = store.UpdateUser(c, user) if err != nil { c.AbortWithStatus(http.StatusConflict) return } c.IndentedJSON(http.StatusOK, user) }
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, }) }
func GetFeed(c *gin.Context) { user := session.User(c) remote := remote.FromContext(c) var repos []*model.RepoLite // get the repository list from the cache reposv, ok := c.Get("repos") if ok { repos = reposv.([]*model.RepoLite) } else { var err error repos, err = remote.Repos(user) if err != nil { c.String(400, err.Error()) return } } feed, err := store.GetUserFeed(c, repos) if err != nil { c.String(400, err.Error()) return } c.JSON(200, feed) }
func GetRepos(c *gin.Context) { user := session.User(c) remote := remote.FromContext(c) var repos []*model.RepoLite // get the repository list from the cache reposv, ok := c.Get("repos") if ok { repos = reposv.([]*model.RepoLite) } else { var err error repos, err = remote.Repos(user) if err != nil { c.AbortWithStatus(http.StatusInternalServerError) return } } // for each repository in the remote system we get // the intersection of those repostiories in Drone repos_, err := store.GetRepoListOf(c, repos) if err != nil { c.AbortWithStatus(http.StatusInternalServerError) return } c.Set("repos", repos) c.IndentedJSON(http.StatusOK, repos_) }
func ShowRepoBadges(c *gin.Context) { user := session.User(c) repo := session.Repo(c) c.HTML(200, "repo_badge.html", gin.H{ "User": user, "Repo": repo, "Link": httputil.GetURL(c.Request), }) }
func PostToken(c *gin.Context) { user := session.User(c) token := token.New(token.UserToken, user.Login) tokenstr, err := token.Sign(user.Hash) if err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else { c.String(http.StatusOK, tokenstr) } }
func ShowUser(c *gin.Context) { user := session.User(c) token, _ := token.New( token.CsrfToken, user.Login, ).Sign(user.Hash) c.HTML(200, "user.html", gin.H{ "User": user, "Csrf": token, }) }
func DeleteRepo(c *gin.Context) { remote := remote.FromContext(c) repo := session.Repo(c) user := session.User(c) err := store.DeleteRepo(c, repo) if err != nil { c.AbortWithError(http.StatusInternalServerError, err) return } remote.Deactivate(user, repo, httputil.GetURL(c.Request)) c.Writer.WriteHeader(http.StatusOK) }
func ShowRepoEncrypt(c *gin.Context) { user := session.User(c) repo := session.Repo(c) token, _ := token.New( token.CsrfToken, user.Login, ).Sign(user.Hash) c.HTML(200, "repo_secret.html", gin.H{ "User": user, "Repo": repo, "Csrf": token, }) }
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, }) }
func PatchRepo(c *gin.Context) { repo := session.Repo(c) user := session.User(c) in := &struct { IsTrusted *bool `json:"trusted,omitempty"` Timeout *int64 `json:"timeout,omitempty"` AllowPull *bool `json:"allow_pr,omitempty"` AllowPush *bool `json:"allow_push,omitempty"` AllowDeploy *bool `json:"allow_deploy,omitempty"` AllowTag *bool `json:"allow_tag,omitempty"` }{} if err := c.Bind(in); err != nil { c.AbortWithError(http.StatusBadRequest, err) return } if in.AllowPush != nil { repo.AllowPush = *in.AllowPush } if in.AllowPull != nil { repo.AllowPull = *in.AllowPull } if in.AllowDeploy != nil { repo.AllowDeploy = *in.AllowDeploy } if in.AllowTag != nil { repo.AllowTag = *in.AllowTag } if in.IsTrusted != nil && user.Admin { repo.IsTrusted = *in.IsTrusted } if in.Timeout != nil && user.Admin { repo.Timeout = *in.Timeout } err := store.UpdateRepo(c, repo) if err != nil { c.AbortWithError(http.StatusInternalServerError, err) return } c.IndentedJSON(http.StatusOK, repo) }
func GetRemoteRepos(c *gin.Context) { user := session.User(c) remote := remote.FromContext(c) reposv, ok := c.Get("repos") if ok { c.IndentedJSON(http.StatusOK, reposv) return } repos, err := remote.Repos(user) if err != nil { c.AbortWithStatus(http.StatusInternalServerError) return } c.Set("repos", repos) c.IndentedJSON(http.StatusOK, repos) }
func ShowRepoConf(c *gin.Context) { user := session.User(c) repo := session.Repo(c) key, _ := store.GetKey(c, repo) token, _ := token.New( token.CsrfToken, user.Login, ).Sign(user.Hash) c.HTML(200, "repo_config.html", gin.H{ "User": user, "Repo": repo, "Key": key, "Csrf": token, "Link": httputil.GetURL(c.Request), }) }
func ShowUsers(c *gin.Context) { user := session.User(c) if !user.Admin { c.AbortWithStatus(http.StatusForbidden) return } users, _ := store.GetUserList(c) token, _ := token.New( token.CsrfToken, user.Login, ).Sign(user.Hash) c.HTML(200, "users.html", gin.H{ "User": user, "Users": users, "Csrf": token, }) }
func Refresh(c *gin.Context) { user := session.User(c) if user == nil { c.Next() return } // check if the remote includes the ability to // refresh the user token. remote_ := remote.FromContext(c) refresher, ok := remote_.(remote.Refresher) if !ok { c.Next() return } // check to see if the user token is expired or // will expire within the next 30 minutes (1800 seconds). // If not, there is nothing we really need to do here. if time.Now().UTC().Unix() < (user.Expiry - 1800) { c.Next() return } // attempts to refresh the access token. If the // token is refreshed, we must also persist to the // database. ok, _ = refresher.Refresh(user) if ok { err := store.UpdateUser(c, user) if err != nil { // we only log the error at this time. not sure // if we really want to fail the request, do we? log.Errorf("cannot refresh access token for %s. %s", user.Login, err) } else { log.Infof("refreshed access token for %s", user.Login) } } c.Next() }
func ShowIndex(c *gin.Context) { remote := remote.FromContext(c) user := session.User(c) if user == nil { c.Redirect(http.StatusSeeOther, "/login") return } var err error var repos []*model.RepoLite // get the repository list from the cache reposv, ok := c.Get("repos") if ok { repos = reposv.([]*model.RepoLite) } else { repos, err = remote.Repos(user) if err != nil { log.Errorf("Failure to get remote repositories for %s. %s.", user.Login, err) } else { c.Set("repos", repos) } } // for each repository in the remote system we get // the intersection of those repostiories in Drone // repos_, err := store.GetRepoListOf(c, repos) // if err != nil { // log.Errorf("Failure to get repository list for %s. %s.", // user.Login, err) // } c.HTML(200, "repos.html", gin.H{ "User": user, "Repos": repos, }) }
func DeleteUser(c *gin.Context) { me := session.User(c) user, err := store.GetUserLogin(c, c.Param("login")) if err != nil { c.AbortWithStatus(http.StatusNotFound) return } // cannot delete self if me.ID == user.ID { c.AbortWithStatus(http.StatusForbidden) return } err = store.DeleteUser(c, user) if err != nil { c.AbortWithStatus(http.StatusInternalServerError) return } c.Writer.WriteHeader(http.StatusNoContent) }
func GetRepo(c *gin.Context) { repo := session.Repo(c) user := session.User(c) if user == nil { c.IndentedJSON(http.StatusOK, repo) return } repoResp := struct { *model.Repo Token string `json:"hook_token,omitempty"` }{repo, ""} if user.Admin { t := token.New(token.HookToken, repo.FullName) sig, err := t.Sign(repo.Hash) if err != nil { log.Errorf("Error creating hook token: %s", err) } else { repoResp.Token = sig } } c.IndentedJSON(http.StatusOK, repoResp) }
func PostRepo(c *gin.Context) { remote := remote.FromContext(c) user := session.User(c) owner := c.Param("owner") name := c.Param("name") paramActivate := c.Request.FormValue("activate") if user == nil { c.AbortWithStatus(403) return } r, err := remote.Repo(user, owner, name) if err != nil { c.String(404, err.Error()) return } m, err := remote.Perm(user, owner, name) if err != nil { c.String(404, err.Error()) return } if !m.Admin { c.String(403, "Administrative access is required.") return } // error if the repository already exists _, err = store.GetRepoOwnerName(c, owner, name) if err == nil { c.String(409, "Repository already exists.") return } // set the repository owner to the // currently authenticated user. r.UserID = user.ID r.AllowPush = true r.AllowPull = true r.Timeout = 60 // 1 hour default build time r.Hash = crypto.Rand() // crates the jwt token used to verify the repository t := token.New(token.HookToken, r.FullName) sig, err := t.Sign(r.Hash) if err != nil { c.String(500, err.Error()) return } // generate an RSA key and add to the repo key, err := crypto.GeneratePrivateKey() if err != nil { c.String(500, err.Error()) return } keys := new(model.Key) keys.Public = string(crypto.MarshalPublicKey(&key.PublicKey)) keys.Private = string(crypto.MarshalPrivateKey(key)) var activate bool activate, err = strconv.ParseBool(paramActivate) if err != nil { activate = true } if activate { link := fmt.Sprintf( "%s/hook?access_token=%s", httputil.GetURL(c.Request), sig, ) // activate the repository before we make any // local changes to the database. err = remote.Activate(user, r, keys, link) if err != nil { c.String(500, err.Error()) return } } // persist the repository err = store.CreateRepo(c, r) if err != nil { c.String(500, err.Error()) return } keys.RepoID = r.ID err = store.CreateKey(c, keys) if err != nil { c.String(500, err.Error()) return } c.JSON(200, r) }
func ShowNodes(c *gin.Context) { user := session.User(c) nodes, _ := store.GetNodeList(c) token, _ := token.New(token.CsrfToken, user.Login).Sign(user.Hash) c.HTML(http.StatusOK, "nodes.html", gin.H{"User": user, "Nodes": nodes, "Csrf": token}) }
func GetSelf(c *gin.Context) { c.IndentedJSON(200, session.User(c)) }