Example #1
0
File: users.go Project: Keleir/gogs
func DeleteUser(ctx *middleware.Context) {
	uid := com.StrTo(ctx.Params(":userid")).MustInt64()
	if uid == 0 {
		ctx.Handle(404, "DeleteUser", nil)
		return
	}

	u, err := models.GetUserByID(uid)
	if err != nil {
		ctx.Handle(500, "GetUserByID", err)
		return
	}

	if err = models.DeleteUser(u); err != nil {
		switch {
		case models.IsErrUserOwnRepos(err):
			ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo"))
			ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
		case models.IsErrUserHasOrgs(err):
			ctx.Flash.Error(ctx.Tr("admin.users.still_has_org"))
			ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
		default:
			ctx.Handle(500, "DeleteUser", err)
		}
		return
	}
	log.Trace("Account deleted by admin(%s): %s", ctx.User.Name, u.Name)
	ctx.Redirect(setting.AppSubUrl + "/admin/users")
}
Example #2
0
File: users.go Project: Keleir/gogs
func EditUser(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
	ctx.Data["PageIsAdmin"] = true
	ctx.Data["PageIsAdminUsers"] = true

	uid := com.StrTo(ctx.Params(":userid")).MustInt64()
	if uid == 0 {
		ctx.Handle(404, "EditUser", nil)
		return
	}

	u, err := models.GetUserByID(uid)
	if err != nil {
		ctx.Handle(500, "GetUserByID", err)
		return
	}

	ctx.Data["User"] = u
	auths, err := models.GetAuths()
	if err != nil {
		ctx.Handle(500, "GetAuths", err)
		return
	}
	ctx.Data["LoginSources"] = auths
	ctx.HTML(200, USER_EDIT)
}
Example #3
0
func TriggerTask(ctx *context.Context) {
	pusherID := ctx.QueryInt64("pusher")
	branch := ctx.Query("branch")
	secret := ctx.Query("secret")
	if len(branch) == 0 || len(secret) == 0 || pusherID <= 0 {
		ctx.Error(404)
		log.Trace("TriggerTask: branch or secret is empty, or pusher ID is not valid")
		return
	}
	owner, repo := parseOwnerAndRepo(ctx)
	if ctx.Written() {
		return
	}
	if secret != base.EncodeMD5(owner.Salt) {
		ctx.Error(404)
		log.Trace("TriggerTask [%s/%s]: invalid secret", owner.Name, repo.Name)
		return
	}

	pusher, err := models.GetUserByID(pusherID)
	if err != nil {
		if models.IsErrUserNotExist(err) {
			ctx.Error(404)
		} else {
			ctx.Handle(500, "GetUserByID", err)
		}
		return
	}

	log.Trace("TriggerTask '%s/%s' by %s", repo.Name, branch, pusher.Name)

	go models.HookQueue.Add(repo.ID)
	go models.AddTestPullRequestTask(pusher, repo.ID, branch, true)
	ctx.Status(202)
}
Example #4
0
func prepareUserInfo(ctx *context.Context) *models.User {
	u, err := models.GetUserByID(ctx.ParamsInt64(":userid"))
	if err != nil {
		ctx.Handle(500, "GetUserByID", err)
		return nil
	}
	ctx.Data["User"] = u

	if u.LoginSource > 0 {
		ctx.Data["LoginSource"], err = models.GetLoginSourceByID(u.LoginSource)
		if err != nil {
			ctx.Handle(500, "GetLoginSourceByID", err)
			return nil
		}
	} else {
		ctx.Data["LoginSource"] = &models.LoginSource{}
	}

	sources, err := models.LoginSources()
	if err != nil {
		ctx.Handle(500, "LoginSources", err)
		return nil
	}
	ctx.Data["Sources"] = sources

	return u
}
Example #5
0
func checkContextUser(ctx *context.Context, uid int64) *models.User {
	orgs, err := models.GetOwnedOrgsByUserIDDesc(ctx.User.ID, "updated_unix")
	if err != nil {
		ctx.Handle(500, "GetOwnedOrgsByUserIDDesc", err)
		return nil
	}
	ctx.Data["Orgs"] = orgs

	// Not equal means current user is an organization.
	if uid == ctx.User.ID || uid == 0 {
		return ctx.User
	}

	org, err := models.GetUserByID(uid)
	if models.IsErrUserNotExist(err) {
		return ctx.User
	}

	if err != nil {
		ctx.Handle(500, "GetUserByID", fmt.Errorf("[%d]: %v", uid, err))
		return nil
	}

	// Check ownership of organization.
	if !org.IsOrganization() || !(ctx.User.IsAdmin || org.IsOwnedBy(ctx.User.ID)) {
		ctx.Error(403)
		return nil
	}
	return org
}
Example #6
0
File: mail.go Project: noikiy/gogs
// SendIssueNotifyMail sends mail notification of all watchers of repository.
func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *models.Issue) ([]string, error) {
	ws, err := models.GetWatchers(repo.ID)
	if err != nil {
		return nil, errors.New("mail.NotifyWatchers(GetWatchers): " + err.Error())
	}

	tos := make([]string, 0, len(ws))
	for i := range ws {
		uid := ws[i].UserID
		if u.Id == uid {
			continue
		}
		u, err := models.GetUserByID(uid)
		if err != nil {
			return nil, errors.New("mail.NotifyWatchers(GetUserById): " + err.Error())
		}
		tos = append(tos, u.Email)
	}

	if len(tos) == 0 {
		return tos, nil
	}

	subject := fmt.Sprintf("[%s] %s(#%d)", repo.Name, issue.Name, issue.Index)
	content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.",
		base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name),
		setting.AppUrl, owner.Name, repo.Name, issue.Index)
	msg := NewMailMessageFrom(tos, u.Email, subject, content)
	msg.Info = fmt.Sprintf("Subject: %s, send issue notify emails", subject)
	SendAsync(&msg)
	return tos, nil
}
Example #7
0
func DeleteUser(ctx *context.Context) {
	u, err := models.GetUserByID(ctx.ParamsInt64(":userid"))
	if err != nil {
		ctx.Handle(500, "GetUserByID", err)
		return
	}

	if err = models.DeleteUser(u); err != nil {
		switch {
		case models.IsErrUserOwnRepos(err):
			ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo"))
			ctx.JSON(200, map[string]interface{}{
				"redirect": setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"),
			})
		case models.IsErrUserHasOrgs(err):
			ctx.Flash.Error(ctx.Tr("admin.users.still_has_org"))
			ctx.JSON(200, map[string]interface{}{
				"redirect": setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"),
			})
		default:
			ctx.Handle(500, "DeleteUser", err)
		}
		return
	}
	log.Trace("Account deleted by admin (%s): %s", ctx.User.Name, u.Name)

	ctx.Flash.Success(ctx.Tr("admin.users.deletion_success"))
	ctx.JSON(200, map[string]interface{}{
		"redirect": setting.AppSubUrl + "/admin/users",
	})
}
Example #8
0
func checkContextUser(ctx *middleware.Context, uid int64) *models.User {
	if err := ctx.User.GetOrganizations(); err != nil {
		ctx.Handle(500, "GetOrganizations", err)
		return nil
	}
	ctx.Data["Orgs"] = ctx.User.Orgs

	// Not equal means current user is an organization.
	if uid == ctx.User.Id || uid == 0 {
		return ctx.User
	}

	org, err := models.GetUserByID(uid)
	if models.IsErrUserNotExist(err) {
		return ctx.User
	}

	if err != nil {
		ctx.Handle(500, "checkContextUser", fmt.Errorf("GetUserById(%d): %v", uid, err))
		return nil
	}

	// Check ownership of organization.
	if !org.IsOrganization() || !org.IsOwnedBy(ctx.User.Id) {
		ctx.Error(403)
		return nil
	}
	return org
}
Example #9
0
// https://github.com/gogits/go-gogs-client/wiki/Repositories#search-repositories
func Search(ctx *context.APIContext) {
	opts := &models.SearchRepoOptions{
		Keyword:  path.Base(ctx.Query("q")),
		OwnerID:  com.StrTo(ctx.Query("uid")).MustInt64(),
		PageSize: com.StrTo(ctx.Query("limit")).MustInt(),
	}
	if opts.PageSize == 0 {
		opts.PageSize = 10
	}

	// Check visibility.
	if ctx.IsSigned && opts.OwnerID > 0 {
		if ctx.User.Id == opts.OwnerID {
			opts.Private = true
		} else {
			u, err := models.GetUserByID(opts.OwnerID)
			if err != nil {
				ctx.JSON(500, map[string]interface{}{
					"ok":    false,
					"error": err.Error(),
				})
				return
			}
			if u.IsOrganization() && u.IsOwnedBy(ctx.User.Id) {
				opts.Private = true
			}
			// FIXME: how about collaborators?
		}
	}

	repos, _, err := models.SearchRepositoryByName(opts)
	if err != nil {
		ctx.JSON(500, map[string]interface{}{
			"ok":    false,
			"error": err.Error(),
		})
		return
	}

	results := make([]*api.Repository, len(repos))
	for i := range repos {
		if err = repos[i].GetOwner(); err != nil {
			ctx.JSON(500, map[string]interface{}{
				"ok":    false,
				"error": err.Error(),
			})
			return
		}
		results[i] = &api.Repository{
			ID:       repos[i].ID,
			FullName: path.Join(repos[i].Owner.Name, repos[i].Name),
		}
	}

	ctx.JSON(200, map[string]interface{}{
		"ok":   true,
		"data": results,
	})
}
Example #10
0
File: users.go Project: Keleir/gogs
func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
	ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
	ctx.Data["PageIsAdmin"] = true
	ctx.Data["PageIsAdminUsers"] = true

	uid := com.StrTo(ctx.Params(":userid")).MustInt64()
	if uid == 0 {
		ctx.Handle(404, "EditUser", nil)
		return
	}

	u, err := models.GetUserByID(uid)
	if err != nil {
		ctx.Handle(500, "GetUserById", err)
		return
	}
	ctx.Data["User"] = u

	if ctx.HasError() {
		ctx.HTML(200, USER_EDIT)
		return
	}

	// FIXME: need password length check
	if len(form.Password) > 0 {
		u.Passwd = form.Password
		u.Salt = models.GetUserSalt()
		u.EncodePasswd()
	}

	u.FullName = form.FullName
	u.Email = form.Email
	u.Website = form.Website
	u.Location = form.Location
	if len(form.Avatar) == 0 {
		form.Avatar = form.Email
	}
	u.Avatar = base.EncodeMd5(form.Avatar)
	u.AvatarEmail = form.Avatar
	u.IsActive = form.Active
	u.IsAdmin = form.Admin
	u.AllowGitHook = form.AllowGitHook

	if err := models.UpdateUser(u); err != nil {
		if models.IsErrEmailAlreadyUsed(err) {
			ctx.Data["Err_Email"] = true
			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), USER_EDIT, &form)
		} else {
			ctx.Handle(500, "UpdateUser", err)
		}
		return
	}
	log.Trace("Account profile updated by admin(%s): %s", ctx.User.Name, u.Name)
	ctx.Flash.Success(ctx.Tr("admin.users.update_profile_success"))
	ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
}
Example #11
0
// SignedInID returns the id of signed in user.
func SignedInID(ctx *macaron.Context, sess session.Store) int64 {
	if !models.HasEngine {
		return 0
	}

	// Check access token.
	if IsAPIPath(ctx.Req.URL.Path) {
		tokenSHA := ctx.Query("token")
		if len(tokenSHA) == 0 {
			// Well, check with header again.
			auHead := ctx.Req.Header.Get("Authorization")
			if len(auHead) > 0 {
				auths := strings.Fields(auHead)
				if len(auths) == 2 && auths[0] == "token" {
					tokenSHA = auths[1]
				}
			}
		}

		// Let's see if token is valid.
		if len(tokenSHA) > 0 {
			t, err := models.GetAccessTokenBySHA(tokenSHA)
			if err != nil {
				if models.IsErrAccessTokenNotExist(err) {
					log.Error(4, "GetAccessTokenBySHA: %v", err)
				}
				return 0
			}
			t.Updated = time.Now()
			if err = models.UpdateAccessToekn(t); err != nil {
				log.Error(4, "UpdateAccessToekn: %v", err)
			}
			return t.UID
		}
	}

	uid := sess.Get("uid")
	if uid == nil {
		return 0
	}
	if id, ok := uid.(int64); ok {
		if _, err := models.GetUserByID(id); err != nil {
			if !models.IsErrUserNotExist(err) {
				log.Error(4, "GetUserById: %v", err)
			}
			return 0
		}
		return id
	}
	return 0
}
Example #12
0
// SignedInId returns the id of signed in user.
func SignedInId(req *http.Request, sess session.Store) int64 {
	if !models.HasEngine {
		return 0
	}

	// API calls need to check access token.
	if IsAPIPath(req.URL.Path) {
		auHead := req.Header.Get("Authorization")
		if len(auHead) > 0 {
			auths := strings.Fields(auHead)
			if len(auths) == 2 && auths[0] == "token" {
				t, err := models.GetAccessTokenBySHA(auths[1])
				if err != nil {
					if err != models.ErrAccessTokenNotExist {
						log.Error(4, "GetAccessTokenBySHA: %v", err)
					}
					return 0
				}
				t.Updated = time.Now()
				if err = models.UpdateAccessToekn(t); err != nil {
					log.Error(4, "UpdateAccessToekn: %v", err)
				}
				return t.UID
			}
		}
	}

	uid := sess.Get("uid")
	if uid == nil {
		return 0
	}
	if id, ok := uid.(int64); ok {
		if _, err := models.GetUserByID(id); err != nil {
			if !models.IsErrUserNotExist(err) {
				log.Error(4, "GetUserById: %v", err)
			}
			return 0
		}
		return id
	}
	return 0
}
Example #13
0
File: repo.go Project: noikiy/gogs
func checkContextUser(ctx *middleware.Context, uid int64) *models.User {
	// Not equal means current user is an organization.
	if uid == ctx.User.Id || uid == 0 {
		return ctx.User
	}

	org, err := models.GetUserByID(uid)
	if models.IsErrUserNotExist(err) {
		return ctx.User
	}

	if err != nil {
		ctx.Handle(500, "checkContextUser", fmt.Errorf("GetUserById(%d): %v", uid, err))
		return nil
	} else if !org.IsOrganization() {
		ctx.Error(403)
		return nil
	}
	return org
}
Example #14
0
func ReleaseByName(ctx *middleware.Context) {
	rel, err := models.GetRelease(ctx.Repo.Repository.ID, ctx.Params(":release"))
	if err != nil {
		log.Error(4, "GetRelease: %v", err)
		ctx.Status(500)
		return
	}

	publisher, err := models.GetUserByID(rel.PublisherID)
	if err != nil {
		if models.IsErrUserNotExist(err) {
			publisher = models.NewFakeUser()
		} else {
			ctx.Handle(422, "GetUserByID", err)
			return
		}
	}
	rel.Publisher = publisher

	ctx.JSON(200, ToApiRelease(rel))
}
Example #15
0
// SendIssueNotifyMail sends mail notification of all watchers of repository.
func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *models.Issue) ([]string, error) {
	ws, err := models.GetWatchers(repo.ID)
	if err != nil {
		return nil, fmt.Errorf("GetWatchers[%d]: %v", repo.ID, err)
	}

	tos := make([]string, 0, len(ws))
	for i := range ws {
		uid := ws[i].UserID
		if u.Id == uid {
			continue
		}
		to, err := models.GetUserByID(uid)
		if err != nil {
			return nil, fmt.Errorf("GetUserByID: %v", err)
		}
		if to.IsOrganization() {
			continue
		}

		tos = append(tos, to.Email)
	}

	if len(tos) == 0 {
		return tos, nil
	}

	subject := fmt.Sprintf("[%s] %s (#%d)", repo.Name, issue.Name, issue.Index)
	content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.",
		base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name, repo.ComposeMetas()),
		setting.AppUrl, owner.Name, repo.Name, issue.Index)
	msg := NewMessage(tos, subject, content)
	msg.Info = fmt.Sprintf("Subject: %s, issue notify", subject)

	SendAsync(msg)
	return tos, nil
}
Example #16
0
func ViewIssue(ctx *middleware.Context) {
	ctx.Data["AttachmentsEnabled"] = setting.AttachmentEnabled

	idx := com.StrTo(ctx.Params(":index")).MustInt64()
	if idx == 0 {
		ctx.Handle(404, "issue.ViewIssue", nil)
		return
	}

	issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, idx)
	if err != nil {
		if err == models.ErrIssueNotExist {
			ctx.Handle(404, "GetIssueByIndex", err)
		} else {
			ctx.Handle(500, "GetIssueByIndex", err)
		}
		return
	}

	// Get labels.
	if err = issue.GetLabels(); err != nil {
		ctx.Handle(500, "GetLabels", err)
		return
	}
	labels, err := models.GetLabelsByRepoID(ctx.Repo.Repository.ID)
	if err != nil {
		ctx.Handle(500, "GetLabels.2", err)
		return
	}
	checkLabels(issue.Labels, labels)
	ctx.Data["Labels"] = labels

	// Get assigned milestone.
	if issue.MilestoneID > 0 {
		ctx.Data["Milestone"], err = models.GetMilestoneByID(issue.MilestoneID)
		if err != nil {
			if models.IsErrMilestoneNotExist(err) {
				log.Warn("GetMilestoneById: %v", err)
			} else {
				ctx.Handle(500, "GetMilestoneById", err)
				return
			}
		}
	}

	// Get all milestones.
	ctx.Data["OpenMilestones"], err = models.GetMilestones(ctx.Repo.Repository.ID, -1, false)
	if err != nil {
		ctx.Handle(500, "GetMilestones.1: %v", err)
		return
	}
	ctx.Data["ClosedMilestones"], err = models.GetMilestones(ctx.Repo.Repository.ID, -1, true)
	if err != nil {
		ctx.Handle(500, "GetMilestones.2: %v", err)
		return
	}

	// Get all collaborators.
	ctx.Data["Collaborators"], err = ctx.Repo.Repository.GetCollaborators()
	if err != nil {
		ctx.Handle(500, "GetCollaborators", err)
		return
	}

	if ctx.IsSigned {
		// Update issue-user.
		if err = models.UpdateIssueUserPairByRead(ctx.User.Id, issue.ID); err != nil {
			ctx.Handle(500, "UpdateIssueUserPairByRead: %v", err)
			return
		}
	}

	// Get poster and Assignee.
	if err = issue.GetPoster(); err != nil {
		ctx.Handle(500, "GetPoster: %v", err)
		return
	} else if err = issue.GetAssignee(); err != nil {
		ctx.Handle(500, "GetAssignee: %v", err)
		return
	}
	issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink))

	// Get comments.
	comments, err := models.GetIssueComments(issue.ID)
	if err != nil {
		ctx.Handle(500, "GetIssueComments: %v", err)
		return
	}

	// Get posters.
	for i := range comments {
		u, err := models.GetUserByID(comments[i].PosterId)
		if err != nil {
			ctx.Handle(500, "GetUserById.2: %v", err)
			return
		}
		comments[i].Poster = u

		if comments[i].Type == models.COMMENT_TYPE_COMMENT {
			comments[i].Content = string(base.RenderMarkdown([]byte(comments[i].Content), ctx.Repo.RepoLink))
		}
	}

	ctx.Data["AllowedTypes"] = setting.AttachmentAllowedTypes

	ctx.Data["Title"] = issue.Name
	ctx.Data["Issue"] = issue
	ctx.Data["Comments"] = comments
	ctx.Data["IsIssueOwner"] = ctx.Repo.IsOwner() || (ctx.IsSigned && issue.PosterID == ctx.User.Id)
	ctx.Data["IsRepoToolbarIssues"] = true
	ctx.Data["IsRepoToolbarIssuesList"] = false
	ctx.HTML(200, ISSUE_VIEW)
}
Example #17
0
File: auth.go Project: cem/gogs
// SignedInUser returns the user object of signed user.
// It returns a bool value to indicate whether user uses basic auth or not.
func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool) {
	if !models.HasEngine {
		return nil, false
	}

	uid := SignedInID(ctx, sess)

	if uid <= 0 {
		if setting.Service.EnableReverseProxyAuth {
			sandstormId := ctx.Req.Header.Get(setting.ReverseProxyAuthUser)
			if len(sandstormId) > 0 {
				u, err := models.GetUserBySandstormID(sandstormId)
				if err != nil {
					if !models.IsErrSandstormUserNotExist(err) {
						log.Error(4, "GetUserBySandstormID: %v", err)
						return nil, false
					}

					// Check if enabled auto-registration.
					if setting.Service.EnableReverseProxyAutoRegister {
						randomDigit := func() string {
							return string(rune('0' + rand.Intn(10)))
						}

						password := ""
						for i := 0; i < 16; i++ {
							password += randomDigit()
						}

						handle := ctx.Req.Header.Get("X-Sandstorm-Preferred-Handle")
						if len(handle) == 0 {
							handle = "gogsuser"
						}

						avatarLink := ctx.Req.Header.Get("X-Sandstorm-User-Picture")
						if len(avatarLink) == 0 {
							avatarLink = "mailto:" + sandstormId
						}

						for suffix := ""; len(suffix) < 5; suffix += randomDigit() {
							u := &models.User{
								SandstormId:     sandstormId,
								SandstormAvatar: avatarLink,
								Name:            handle + suffix,
								Email:           gouuid.NewV4().String() + "@localhost",
								Passwd:          password,
								IsActive:        true,
							}
							err = models.CreateUser(u)
							if err == nil {
								return u, false
							}
						}

						// FIXME: should I create a system notice?
						log.Error(4, "CreateUser: %v", err)
						return nil, false
					}
				}

				newAvatar := ctx.Req.Header.Get("X-Sandstorm-User-Picture")
				if len(newAvatar) == 0 {
					newAvatar = "mailto:" + sandstormId
				}
				if u.SandstormAvatar != newAvatar {
					u.SandstormAvatar = newAvatar
					models.UpdateUser(u)
				}
				return u, false
			}
		}

		// Check with basic auth.
		baHead := ctx.Req.Header.Get("Authorization")
		if len(baHead) > 0 {
			auths := strings.Fields(baHead)
			if len(auths) == 2 && auths[0] == "Basic" {
				uname, passwd, _ := base.BasicAuthDecode(auths[1])

				u, err := models.UserSignIn(uname, passwd)
				if err != nil {
					if !models.IsErrUserNotExist(err) {
						log.Error(4, "UserSignIn: %v", err)
					}
					return nil, false
				}

				return u, true
			}
		}
		return nil, false
	}

	u, err := models.GetUserByID(uid)
	if err != nil {
		log.Error(4, "GetUserById: %v", err)
		return nil, false
	}
	return u, false
}
Example #18
0
func Http(ctx *middleware.Context) {
	username := ctx.Params(":username")
	reponame := ctx.Params(":reponame")
	if strings.HasSuffix(reponame, ".git") {
		reponame = reponame[:len(reponame)-4]
	}

	var isPull bool
	service := ctx.Query("service")
	if service == "git-receive-pack" ||
		strings.HasSuffix(ctx.Req.URL.Path, "git-receive-pack") {
		isPull = false
	} else if service == "git-upload-pack" ||
		strings.HasSuffix(ctx.Req.URL.Path, "git-upload-pack") {
		isPull = true
	} else {
		isPull = (ctx.Req.Method == "GET")
	}

	repoUser, err := models.GetUserByName(username)
	if err != nil {
		if models.IsErrUserNotExist(err) {
			ctx.Handle(404, "GetUserByName", nil)
		} else {
			ctx.Handle(500, "GetUserByName", err)
		}
		return
	}

	repo, err := models.GetRepositoryByName(repoUser.Id, reponame)
	if err != nil {
		if models.IsErrRepoNotExist(err) {
			ctx.Handle(404, "GetRepositoryByName", nil)
		} else {
			ctx.Handle(500, "GetRepositoryByName", err)
		}
		return
	}

	// Only public pull don't need auth.
	isPublicPull := !repo.IsPrivate && isPull
	var (
		askAuth      = !isPublicPull || setting.Service.RequireSignInView
		authUser     *models.User
		authUsername string
		authPasswd   string
	)

	// check access
	if askAuth {
		baHead := ctx.Req.Header.Get("Authorization")
		if baHead == "" {
			authRequired(ctx)
			return
		}

		auths := strings.Fields(baHead)
		// currently check basic auth
		// TODO: support digit auth
		// FIXME: middlewares/context.go did basic auth check already,
		// maybe could use that one.
		if len(auths) != 2 || auths[0] != "Basic" {
			ctx.HandleText(401, "no basic auth and digit auth")
			return
		}
		authUsername, authPasswd, err = base.BasicAuthDecode(auths[1])
		if err != nil {
			ctx.HandleText(401, "no basic auth and digit auth")
			return
		}

		authUser, err = models.UserSignIn(authUsername, authPasswd)
		if err != nil {
			if !models.IsErrUserNotExist(err) {
				ctx.Handle(500, "UserSignIn error: %v", err)
				return
			}

			// Assume username now is a token.
			token, err := models.GetAccessTokenBySha(authUsername)
			if err != nil {
				if err == models.ErrAccessTokenNotExist {
					ctx.HandleText(401, "invalid token")
				} else {
					ctx.Handle(500, "GetAccessTokenBySha", err)
				}
				return
			}
			authUser, err = models.GetUserByID(token.UID)
			if err != nil {
				ctx.Handle(500, "GetUserById", err)
				return
			}
			authUsername = authUser.Name
		}

		if !isPublicPull {
			var tp = models.ACCESS_MODE_WRITE
			if isPull {
				tp = models.ACCESS_MODE_READ
			}

			has, err := models.HasAccess(authUser, repo, tp)
			if err != nil {
				ctx.HandleText(401, "no basic auth and digit auth")
				return
			} else if !has {
				if tp == models.ACCESS_MODE_READ {
					has, err = models.HasAccess(authUser, repo, models.ACCESS_MODE_WRITE)
					if err != nil || !has {
						ctx.HandleText(401, "no basic auth and digit auth")
						return
					}
				} else {
					ctx.HandleText(401, "no basic auth and digit auth")
					return
				}
			}

			if !isPull && repo.IsMirror {
				ctx.HandleText(401, "can't push to mirror")
				return
			}
		}
	}

	callback := func(rpc string, input []byte) {
		if rpc == "receive-pack" {
			var lastLine int64 = 0

			for {
				head := input[lastLine : lastLine+2]
				if head[0] == '0' && head[1] == '0' {
					size, err := strconv.ParseInt(string(input[lastLine+2:lastLine+4]), 16, 32)
					if err != nil {
						log.Error(4, "%v", err)
						return
					}

					if size == 0 {
						//fmt.Println(string(input[lastLine:]))
						break
					}

					line := input[lastLine : lastLine+size]
					idx := bytes.IndexRune(line, '\000')
					if idx > -1 {
						line = line[:idx]
					}
					fields := strings.Fields(string(line))
					if len(fields) >= 3 {
						oldCommitId := fields[0][4:]
						newCommitId := fields[1]
						refName := fields[2]

						// FIXME: handle error.
						if err = models.Update(refName, oldCommitId, newCommitId, authUsername, username, reponame, authUser.Id); err == nil {
							models.HookQueue.AddRepoID(repo.ID)
						}

					}
					lastLine = lastLine + size
				} else {
					break
				}
			}
		}
	}

	HTTPBackend(&Config{
		RepoRootPath: setting.RepoRootPath,
		GitBinPath:   "git",
		UploadPack:   true,
		ReceivePack:  true,
		OnSucceed:    callback,
	})(ctx.Resp, ctx.Req.Request)

	runtime.GC()
}
Example #19
0
func Releases(ctx *context.Context) {
	ctx.Data["Title"] = ctx.Tr("repo.release.releases")
	ctx.Data["PageIsReleaseList"] = true

	rawTags, err := ctx.Repo.GitRepo.GetTags()
	if err != nil {
		ctx.Handle(500, "GetTags", err)
		return
	}

	releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID)
	if err != nil {
		ctx.Handle(500, "GetReleasesByRepoID", err)
		return
	}

	// Temproray cache commits count of used branches to speed up.
	countCache := make(map[string]int64)

	tags := make([]*models.Release, len(rawTags))
	for i, rawTag := range rawTags {
		for j, r := range releases {
			if r == nil || (r.IsDraft && !ctx.Repo.IsOwner()) {
				continue
			}
			if r.TagName == rawTag {
				r.Publisher, err = models.GetUserByID(r.PublisherID)
				if err != nil {
					if models.IsErrUserNotExist(err) {
						r.Publisher = models.NewGhostUser()
					} else {
						ctx.Handle(500, "GetUserByID", err)
						return
					}
				}

				if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil {
					ctx.Handle(500, "calReleaseNumCommitsBehind", err)
					return
				}

				r.Note = markdown.RenderString(r.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
				tags[i] = r
				releases[j] = nil // Mark as used.
				break
			}
		}

		if tags[i] == nil {
			commit, err := ctx.Repo.GitRepo.GetTagCommit(rawTag)
			if err != nil {
				ctx.Handle(500, "GetTagCommit", err)
				return
			}

			tags[i] = &models.Release{
				Title:   rawTag,
				TagName: rawTag,
				Sha1:    commit.ID.String(),
			}

			tags[i].NumCommits, err = commit.CommitsCount()
			if err != nil {
				ctx.Handle(500, "CommitsCount", err)
				return
			}
			tags[i].NumCommitsBehind = ctx.Repo.CommitsCount - tags[i].NumCommits
		}
	}

	for _, r := range releases {
		if r == nil {
			continue
		}

		r.Publisher, err = models.GetUserByID(r.PublisherID)
		if err != nil {
			if models.IsErrUserNotExist(err) {
				r.Publisher = models.NewGhostUser()
			} else {
				ctx.Handle(500, "GetUserByID", err)
				return
			}
		}

		if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil {
			ctx.Handle(500, "calReleaseNumCommitsBehind", err)
			return
		}

		r.Note = markdown.RenderString(r.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
		tags = append(tags, r)
	}
	models.SortReleases(tags)
	ctx.Data["Releases"] = tags
	ctx.HTML(200, RELEASES)
}
Example #20
0
func ListReleases(ctx *middleware.Context) {
	rawTags, err := ctx.Repo.GitRepo.GetTags()
	if err != nil {
		ctx.Handle(500, "GetTags", err)
		return
	}

	rels, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID)
	if err != nil {
		ctx.Handle(500, "GetReleasesByRepoId", err)
		return
	}

	// Temproray cache commits count of used branches to speed up.
	countCache := make(map[string]int)

	tags := make([]*api.Release, len(rawTags))
	for i, rawTag := range rawTags {
		for j, rel := range rels {
			if rel == nil || (rel.IsDraft && !ctx.Repo.IsOwner()) {
				continue
			}
			if rel.TagName == rawTag {
				rel.Publisher, err = models.GetUserByID(rel.PublisherID)
				if err != nil {
					ctx.Handle(500, "GetUserById", err)
					return
				}
				// FIXME: duplicated code.
				// Get corresponding target if it's not the current branch.
				if ctx.Repo.BranchName != rel.Target {
					// Get count if not exists.
					if _, ok := countCache[rel.Target]; !ok {
						commit, err := ctx.Repo.GitRepo.GetCommitOfBranch(ctx.Repo.BranchName)
						if err != nil {
							ctx.Handle(500, "GetCommitOfBranch", err)
							return
						}
						countCache[ctx.Repo.BranchName], err = commit.CommitsCount()
						if err != nil {
							ctx.Handle(500, "CommitsCount2", err)
							return
						}
					}
					rel.NumCommitsBehind = countCache[ctx.Repo.BranchName] - rel.NumCommits
				} else {
					rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
				}

				rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink)
				tags[i] = ToApiRelease(rel)
				rels[j] = nil // Mark as used.
				break
			}
		}

		if tags[i] == nil {
			commit, err := ctx.Repo.GitRepo.GetCommitOfTag(rawTag)
			if err != nil {
				ctx.Handle(500, "GetCommitOfTag2", err)
				return
			}

			tags[i] = &api.Release{
				Title:   rawTag,
				TagName: rawTag,
				Sha1:    commit.ID.String(),
			}

			tags[i].NumCommits, err = ctx.Repo.GitRepo.CommitsCount(commit.ID.String())
			if err != nil {
				ctx.Handle(500, "CommitsCount", err)
				return
			}
			tags[i].NumCommitsBehind = ctx.Repo.CommitsCount - tags[i].NumCommits
		}
	}

	for _, rel := range rels {
		if rel == nil {
			continue
		}

		rel.Publisher, err = models.GetUserByID(rel.PublisherID)
		if err != nil {
			ctx.Handle(500, "GetUserById", err)
			return
		}
		// FIXME: duplicated code.
		// Get corresponding target if it's not the current branch.
		if ctx.Repo.BranchName != rel.Target {
			// Get count if not exists.
			if _, ok := countCache[rel.Target]; !ok {
				commit, err := ctx.Repo.GitRepo.GetCommitOfBranch(ctx.Repo.BranchName)
				if err != nil {
					ctx.Handle(500, "GetCommitOfBranch", err)
					return
				}
				countCache[ctx.Repo.BranchName], err = commit.CommitsCount()
				if err != nil {
					ctx.Handle(500, "CommitsCount2", err)
					return
				}
			}
			rel.NumCommitsBehind = countCache[ctx.Repo.BranchName] - rel.NumCommits
		} else {
			rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
		}

		rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink)
		tags = append(tags, ToApiRelease(rel))
	}

	ctx.JSON(200, &tags)
}
Example #21
0
// https://github.com/gogits/go-gogs-client/wiki/Repositories#migrate
func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
	ctxUser := ctx.User
	// Not equal means context user is an organization,
	// or is another user/organization if current user is admin.
	if form.Uid != ctxUser.Id {
		org, err := models.GetUserByID(form.Uid)
		if err != nil {
			if models.IsErrUserNotExist(err) {
				ctx.Error(422, "", err)
			} else {
				ctx.Error(500, "GetUserByID", err)
			}
			return
		}
		ctxUser = org
	}

	if ctx.HasError() {
		ctx.Error(422, "", ctx.GetErrMsg())
		return
	}

	if ctxUser.IsOrganization() && !ctx.User.IsAdmin {
		// Check ownership of organization.
		if !ctxUser.IsOwnedBy(ctx.User.Id) {
			ctx.Error(403, "", "Given user is not owner of organization.")
			return
		}
	}

	remoteAddr, err := form.ParseRemoteAddr(ctx.User)
	if err != nil {
		if models.IsErrInvalidCloneAddr(err) {
			addrErr := err.(models.ErrInvalidCloneAddr)
			switch {
			case addrErr.IsURLError:
				ctx.Error(422, "", err)
			case addrErr.IsPermissionDenied:
				ctx.Error(422, "", "You are not allowed to import local repositories.")
			case addrErr.IsInvalidPath:
				ctx.Error(422, "", "Invalid local path, it does not exist or not a directory.")
			default:
				ctx.Error(500, "ParseRemoteAddr", "Unknown error type (ErrInvalidCloneAddr): "+err.Error())
			}
		} else {
			ctx.Error(500, "ParseRemoteAddr", err)
		}
		return
	}

	repo, err := models.MigrateRepository(ctxUser, models.MigrateRepoOptions{
		Name:        form.RepoName,
		Description: form.Description,
		IsPrivate:   form.Private || setting.Repository.ForcePrivate,
		IsMirror:    form.Mirror,
		RemoteAddr:  remoteAddr,
	})
	if err != nil {
		if repo != nil {
			if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID); errDelete != nil {
				log.Error(4, "DeleteRepository: %v", errDelete)
			}
		}
		ctx.Error(500, "MigrateRepository", models.HandleCloneUserCredentials(err.Error(), true))
		return
	}

	log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
	ctx.JSON(201, convert.ToRepository(ctxUser, repo, api.Permission{true, true, true}))
}
Example #22
0
func HTTP(ctx *context.Context) {
	username := ctx.Params(":username")
	reponame := strings.TrimSuffix(ctx.Params(":reponame"), ".git")

	var isPull bool
	service := ctx.Query("service")
	if service == "git-receive-pack" ||
		strings.HasSuffix(ctx.Req.URL.Path, "git-receive-pack") {
		isPull = false
	} else if service == "git-upload-pack" ||
		strings.HasSuffix(ctx.Req.URL.Path, "git-upload-pack") {
		isPull = true
	} else {
		isPull = (ctx.Req.Method == "GET")
	}

	isWiki := false
	if strings.HasSuffix(reponame, ".wiki") {
		isWiki = true
		reponame = reponame[:len(reponame)-5]
	}

	repoUser, err := models.GetUserByName(username)
	if err != nil {
		if models.IsErrUserNotExist(err) {
			ctx.Handle(http.StatusNotFound, "GetUserByName", nil)
		} else {
			ctx.Handle(http.StatusInternalServerError, "GetUserByName", err)
		}
		return
	}

	repo, err := models.GetRepositoryByName(repoUser.Id, reponame)
	if err != nil {
		if models.IsErrRepoNotExist(err) {
			ctx.Handle(http.StatusNotFound, "GetRepositoryByName", nil)
		} else {
			ctx.Handle(http.StatusInternalServerError, "GetRepositoryByName", err)
		}
		return
	}

	// Only public pull don't need auth.
	isPublicPull := !repo.IsPrivate && isPull
	var (
		askAuth      = !isPublicPull || setting.Service.RequireSignInView
		authUser     *models.User
		authUsername string
		authPasswd   string
	)

	// check access
	if askAuth {
		authHead := ctx.Req.Header.Get("Authorization")
		if len(authHead) == 0 {
			ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=\".\"")
			ctx.Error(http.StatusUnauthorized)
			return
		}

		auths := strings.Fields(authHead)
		// currently check basic auth
		// TODO: support digit auth
		// FIXME: middlewares/context.go did basic auth check already,
		// maybe could use that one.
		if len(auths) != 2 || auths[0] != "Basic" {
			ctx.HandleText(http.StatusUnauthorized, "no basic auth and digit auth")
			return
		}
		authUsername, authPasswd, err = base.BasicAuthDecode(auths[1])
		if err != nil {
			ctx.HandleText(http.StatusUnauthorized, "no basic auth and digit auth")
			return
		}

		authUser, err = models.UserSignIn(authUsername, authPasswd)
		if err != nil {
			if !models.IsErrUserNotExist(err) {
				ctx.Handle(http.StatusInternalServerError, "UserSignIn error: %v", err)
				return
			}

			// Assume username now is a token.
			token, err := models.GetAccessTokenBySHA(authUsername)
			if err != nil {
				if models.IsErrAccessTokenNotExist(err) {
					ctx.HandleText(http.StatusUnauthorized, "invalid token")
				} else {
					ctx.Handle(http.StatusInternalServerError, "GetAccessTokenBySha", err)
				}
				return
			}
			token.Updated = time.Now()
			if err = models.UpdateAccessToken(token); err != nil {
				ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err)
			}
			authUser, err = models.GetUserByID(token.UID)
			if err != nil {
				ctx.Handle(http.StatusInternalServerError, "GetUserByID", err)
				return
			}
		}

		if !isPublicPull {
			var tp = models.ACCESS_MODE_WRITE
			if isPull {
				tp = models.ACCESS_MODE_READ
			}

			has, err := models.HasAccess(authUser, repo, tp)
			if err != nil {
				ctx.Handle(http.StatusInternalServerError, "HasAccess", err)
				return
			} else if !has {
				if tp == models.ACCESS_MODE_READ {
					has, err = models.HasAccess(authUser, repo, models.ACCESS_MODE_WRITE)
					if err != nil {
						ctx.Handle(http.StatusInternalServerError, "HasAccess2", err)
						return
					} else if !has {
						ctx.HandleText(http.StatusForbidden, "User permission denied")
						return
					}
				} else {
					ctx.HandleText(http.StatusForbidden, "User permission denied")
					return
				}
			}

			if !isPull && repo.IsMirror {
				ctx.HandleText(http.StatusForbidden, "mirror repository is read-only")
				return
			}
		}
	}

	callback := func(rpc string, input []byte) {
		if rpc != "receive-pack" || isWiki {
			return
		}

		var lastLine int64 = 0
		for {
			head := input[lastLine : lastLine+2]
			if head[0] == '0' && head[1] == '0' {
				size, err := strconv.ParseInt(string(input[lastLine+2:lastLine+4]), 16, 32)
				if err != nil {
					log.Error(4, "%v", err)
					return
				}

				if size == 0 {
					//fmt.Println(string(input[lastLine:]))
					break
				}

				line := input[lastLine : lastLine+size]
				idx := bytes.IndexRune(line, '\000')
				if idx > -1 {
					line = line[:idx]
				}

				fields := strings.Fields(string(line))
				if len(fields) >= 3 {
					oldCommitId := fields[0][4:]
					newCommitId := fields[1]
					refName := fields[2]

					// FIXME: handle error.
					if err = models.PushUpdate(models.PushUpdateOptions{
						RefName:      refName,
						OldCommitID:  oldCommitId,
						NewCommitID:  newCommitId,
						PusherID:     authUser.Id,
						PusherName:   authUser.Name,
						RepoUserName: username,
						RepoName:     reponame,
					}); err == nil {
						go models.HookQueue.Add(repo.ID)
						go models.AddTestPullRequestTask(repo.ID, strings.TrimPrefix(refName, "refs/heads/"))
					}

				}
				lastLine = lastLine + size
			} else {
				break
			}
		}
	}

	HTTPBackend(ctx, &serviceConfig{
		UploadPack:  true,
		ReceivePack: true,
		OnSucceed:   callback,
	})(ctx.Resp, ctx.Req.Request)

	runtime.GC()
}
Example #23
0
func Releases(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("repo.release.releases")
	ctx.Data["PageIsReleaseList"] = true

	rawTags, err := ctx.Repo.GitRepo.GetTags()
	if err != nil {
		ctx.Handle(500, "GetTags", err)
		return
	}

	rels, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID)
	if err != nil {
		ctx.Handle(500, "GetReleasesByRepoID", err)
		return
	}

	// Temproray cache commits count of used branches to speed up.
	countCache := make(map[string]int64)

	tags := make([]*models.Release, len(rawTags))
	for i, rawTag := range rawTags {
		for j, rel := range rels {
			if rel == nil || (rel.IsDraft && !ctx.Repo.IsOwner()) {
				continue
			}
			if rel.TagName == rawTag {
				rel.Publisher, err = models.GetUserByID(rel.PublisherID)
				if err != nil {
					ctx.Handle(500, "GetUserByID", err)
					return
				}
				// FIXME: duplicated code.
				// Get corresponding target if it's not the current branch.
				if ctx.Repo.BranchName != rel.Target {
					// Get count if not exists.
					if _, ok := countCache[rel.Target]; !ok {
						commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.BranchName)
						if err != nil {
							ctx.Handle(500, "GetBranchCommit", err)
							return
						}
						countCache[ctx.Repo.BranchName], err = commit.CommitsCount()
						if err != nil {
							ctx.Handle(500, "CommitsCount", err)
							return
						}
					}
					rel.NumCommitsBehind = countCache[ctx.Repo.BranchName] - rel.NumCommits
				} else {
					rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
				}

				rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
				tags[i] = rel
				rels[j] = nil // Mark as used.
				break
			}
		}

		if tags[i] == nil {
			commit, err := ctx.Repo.GitRepo.GetTagCommit(rawTag)
			if err != nil {
				ctx.Handle(500, "GetTagCommit", err)
				return
			}

			tags[i] = &models.Release{
				Title:   rawTag,
				TagName: rawTag,
				Sha1:    commit.ID.String(),
			}

			tags[i].NumCommits, err = commit.CommitsCount()
			if err != nil {
				ctx.Handle(500, "CommitsCount", err)
				return
			}
			tags[i].NumCommitsBehind = ctx.Repo.CommitsCount - tags[i].NumCommits
		}
	}

	for _, rel := range rels {
		if rel == nil {
			continue
		}

		rel.Publisher, err = models.GetUserByID(rel.PublisherID)
		if err != nil {
			ctx.Handle(500, "GetUserByID", err)
			return
		}
		// FIXME: duplicated code.
		// Get corresponding target if it's not the current branch.
		if ctx.Repo.BranchName != rel.Target {
			// Get count if not exists.
			if _, ok := countCache[rel.Target]; !ok {
				commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.BranchName)
				if err != nil {
					ctx.Handle(500, "GetBranchCommit", err)
					return
				}
				countCache[ctx.Repo.BranchName], err = commit.CommitsCount()
				if err != nil {
					ctx.Handle(500, "CommitsCount", err)
					return
				}
			}
			rel.NumCommitsBehind = countCache[ctx.Repo.BranchName] - rel.NumCommits
		} else {
			rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
		}

		rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
		tags = append(tags, rel)
	}
	models.SortReleases(tags)
	ctx.Data["Releases"] = tags
	ctx.HTML(200, RELEASES)
}
Example #24
0
File: repo.go Project: GoNuuts/gogs
func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) {
	ctxUser := ctx.User
	// Not equal means current user is an organization.
	if form.Uid != ctxUser.Id {
		org, err := models.GetUserByID(form.Uid)
		if err != nil {
			if models.IsErrUserNotExist(err) {
				ctx.HandleAPI(422, err)
			} else {
				ctx.HandleAPI(500, err)
			}
			return
		}
		ctxUser = org
	}

	if ctx.HasError() {
		ctx.HandleAPI(422, ctx.GetErrMsg())
		return
	}

	if ctxUser.IsOrganization() {
		// Check ownership of organization.
		if !ctxUser.IsOwnedBy(ctx.User.Id) {
			ctx.HandleAPI(403, "Given user is not owner of organization.")
			return
		}
	}

	// Remote address can be HTTP/HTTPS/Git URL or local path.
	remoteAddr := form.CloneAddr
	if strings.HasPrefix(form.CloneAddr, "http://") ||
		strings.HasPrefix(form.CloneAddr, "https://") ||
		strings.HasPrefix(form.CloneAddr, "git://") {
		u, err := url.Parse(form.CloneAddr)
		if err != nil {
			ctx.HandleAPI(422, err)
			return
		}
		if len(form.AuthUsername) > 0 || len(form.AuthPassword) > 0 {
			u.User = url.UserPassword(form.AuthUsername, form.AuthPassword)
		}
		remoteAddr = u.String()
	} else if !com.IsDir(remoteAddr) {
		ctx.HandleAPI(422, "Invalid local path, it does not exist or not a directory.")
		return
	}

	repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr)
	if err != nil {
		if repo != nil {
			if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID); errDelete != nil {
				log.Error(4, "DeleteRepository: %v", errDelete)
			}
		}
		ctx.HandleAPI(500, err)
		return
	}

	log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
	ctx.JSON(201, ToApiRepository(ctxUser, repo, api.Permission{true, true, true}))
}
Example #25
0
// SignedInUser returns the user object of signed user.
// It returns a bool value to indicate whether user uses basic auth or not.
func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool) {
	if !models.HasEngine {
		return nil, false
	}

	uid := SignedInID(ctx, sess)

	if uid <= 0 {
		if setting.Service.EnableReverseProxyAuth {
			webAuthUser := ctx.Req.Header.Get(setting.ReverseProxyAuthUser)
			if len(webAuthUser) > 0 {
				u, err := models.GetUserByName(webAuthUser)
				if err != nil {
					if !models.IsErrUserNotExist(err) {
						log.Error(4, "GetUserByName: %v", err)
						return nil, false
					}

					// Check if enabled auto-registration.
					if setting.Service.EnableReverseProxyAutoRegister {
						u := &models.User{
							Name:     webAuthUser,
							Email:    uuid.NewV4().String() + "@localhost",
							Passwd:   webAuthUser,
							IsActive: true,
						}
						if err = models.CreateUser(u); err != nil {
							// FIXME: should I create a system notice?
							log.Error(4, "CreateUser: %v", err)
							return nil, false
						} else {
							return u, false
						}
					}
				}
				return u, false
			}
		}

		// Check with basic auth.
		baHead := ctx.Req.Header.Get("Authorization")
		if len(baHead) > 0 {
			auths := strings.Fields(baHead)
			if len(auths) == 2 && auths[0] == "Basic" {
				uname, passwd, _ := base.BasicAuthDecode(auths[1])

				u, err := models.UserSignIn(uname, passwd)
				if err != nil {
					if !models.IsErrUserNotExist(err) {
						log.Error(4, "UserSignIn: %v", err)
					}
					return nil, false
				}

				return u, true
			}
		}
		return nil, false
	}

	u, err := models.GetUserByID(uid)
	if err != nil {
		log.Error(4, "GetUserById: %v", err)
		return nil, false
	}
	return u, false
}