Пример #1
0
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)
}
Пример #2
0
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)
}