func GetLogin(c *gin.Context) { remote := remote.FromContext(c) tmpUser, err := remote.Login(c.Writer, c.Request) if err != nil { log.Errorf("failed to authenticate user. %s", err) c.Redirect(http.StatusSeeOther, "/login?error=oauth_error") return } if tmpUser == nil { return } u, err := store.GetUserLogin(c, tmpUser.Login) if err != nil { count, err := store.CountUsers(c) if err != nil { log.Errorf("cannot register %s. %s", tmpUser.Login, err) c.Redirect(http.StatusSeeOther, "/login?error=internal_error") return } // if self-registration is disabled we should // return a notAuthorized error. the only exception // is if no users exist yet in the system we'll proceed. if count != 0 { log.Errorf("failed to register %s.", tmpUser.Login) c.Redirect(http.StatusSeeOther, "/login?error=access_denied") return } // create the user account u = &model.User{} u.Login = tmpUser.Login u.Hash = base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32), ) // insert the user into the database if err := store.CreateUser(c, u); err != nil { log.Errorf("failed to insert %s. %s", u.Login, err) c.Redirect(http.StatusSeeOther, "/login?error=internal_error") return } // if this is the first user, they // should be an admin. if count == 0 { u.Admin = true } } // update the user meta data and authorization // data and cache in the datastore. u.Token = tmpUser.Token if err := store.UpdateUser(c, u); err != nil { log.Errorf("failed to update %s. %s", u.Login, err) c.Redirect(http.StatusSeeOther, "/login?error=internal_error") return } exp := time.Now().Add(time.Hour * 72).Unix() token := token.New(token.SessToken, u.Login) tokenstr, err := token.SignExpires(u.Hash, exp) if err != nil { log.Errorf("failed to create token for %s. %s", u.Login, err) c.Redirect(http.StatusSeeOther, "/login?error=internal_error") return } httputil.SetCookie(c.Writer, c.Request, "user_sess", tokenstr) redirect := httputil.GetCookie(c.Request, "user_last") if len(redirect) == 0 { redirect = "/" } c.Redirect(http.StatusSeeOther, redirect) }
func PostRepo(c *gin.Context) { remote := remote.FromContext(c) user := session.User(c) owner := c.Param("owner") name := c.Param("name") if !repo.ValidRepoName(name) { c.AbortWithStatus(http.StatusBadRequest) return } if owner != user.Login { c.AbortWithStatus(http.StatusUnauthorized) return } in := struct { SourceRepo *string `json:"source_repo" binding:"required"` SourceBranch *string `json:"source_branch,omitempty"` BuildBranch *string `json:"build_branch,omitempty"` Archs *[]string `json:"archs,omitempty"` Private *bool `json:"private,omitempty"` }{} err := c.BindJSON(&in) if err != nil { log.Errorf("failed to parse request body: %s", err) c.AbortWithStatus(http.StatusBadRequest) return } if in.Private == nil { private := false in.Private = &private } if in.Archs == nil || len(*in.Archs) == 0 { defArch := []string{"x86_64"} in.Archs = &defArch } if !repo.ValidArchs(*in.Archs) { c.AbortWithStatus(http.StatusBadRequest) return } sourceOwner, sourceName, err := splitRepoName(*in.SourceRepo) if err != nil { log.Error(err) c.AbortWithStatus(http.StatusBadRequest) return } if in.SourceBranch == nil { sourceBranch := "master" in.SourceBranch = &sourceBranch } if in.BuildBranch == nil { buildBranch := "build" in.BuildBranch = &buildBranch } // error if the repository already exists _r, err := store.GetRepoByOwnerName(c, owner, name) if _r != nil { log.Errorf("unable to add repo: %s/%s, already exists", owner, name) c.AbortWithStatus(http.StatusConflict) return } // Fetch source repo r, err := remote.Repo(user, sourceOwner, sourceName) if err != nil { log.Errorf("unable to get repo: %s/%s: %s", sourceOwner, sourceName, err) c.AbortWithStatus(http.StatusNotFound) return } p, err := remote.Perm(user, sourceOwner, sourceName) if err != nil { log.Errorf("unable to get repo permission for: %s/%s: %s", sourceOwner, sourceName, err) c.AbortWithStatus(http.StatusNotFound) return } if !(p.Admin || (p.Read && p.Write)) { log.Errorf("pull/push access required") c.AbortWithStatus(http.StatusUnauthorized) return } err = remote.SetupBranch(user, sourceOwner, sourceName, *in.SourceBranch, *in.BuildBranch) if err != nil { log.Errorf("failed to setup build branch: %s", err) c.AbortWithStatus(http.StatusInternalServerError) return } r.UserID = user.ID r.Owner = owner r.Name = name r.Private = *in.Private r.SourceBranch = *in.SourceBranch r.BuildBranch = *in.BuildBranch r.LastCheck = time.Now().UTC().Add(-1 * time.Hour) r.Hash = base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32), ) fsRepo := repo.NewRepo(r, repo.RepoStorage) err = fsRepo.InitDir() if err != nil { log.Errorf("failed to create repo storage path '%s' on disk: %s", fsRepo.Path(), err) c.AbortWithStatus(http.StatusInternalServerError) return } err = fsRepo.InitEmptyDBs() if err != nil { log.Errorf("failed to initialize empty dbs: %s", err) c.AbortWithStatus(http.StatusInternalServerError) return } err = store.CreateRepo(c, r) if err != nil { log.Errorf("failed to add repo: %s", err) err = fsRepo.ClearPath() if err != nil { log.Errorf("failed to cleanup repo path '%s': %s", fsRepo.Path(), err) } c.AbortWithStatus(http.StatusInternalServerError) return } c.JSON(http.StatusOK, r) }