Example #1
0
func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenForm) {
	ctx.Data["Title"] = ctx.Tr("settings")
	ctx.Data["PageIsSettingsApplications"] = true

	if ctx.HasError() {
		tokens, err := models.ListAccessTokens(ctx.User.Id)
		if err != nil {
			ctx.Handle(500, "ListAccessTokens", err)
			return
		}
		ctx.Data["Tokens"] = tokens
		ctx.HTML(200, SETTINGS_APPLICATIONS)
		return
	}

	t := &models.AccessToken{
		UID:  ctx.User.Id,
		Name: form.Name,
	}
	if err := models.NewAccessToken(t); err != nil {
		ctx.Handle(500, "NewAccessToken", err)
		return
	}

	ctx.Flash.Success(ctx.Tr("settings.generate_token_succees"))
	ctx.Flash.Info(t.Sha1)

	ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
}
Example #2
0
func TeamsRepoAction(ctx *middleware.Context) {
	if !ctx.Org.IsOwner {
		ctx.Error(404)
		return
	}

	var err error
	switch ctx.Params(":action") {
	case "add":
		repoName := path.Base(ctx.Query("repo-name"))
		var repo *models.Repository
		repo, err = models.GetRepositoryByName(ctx.Org.Organization.Id, repoName)
		if err != nil {
			if models.IsErrRepoNotExist(err) {
				ctx.Flash.Error(ctx.Tr("org.teams.add_nonexistent_repo"))
				ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
				return
			}
			ctx.Handle(500, "GetRepositoryByName", err)
			return
		}
		err = ctx.Org.Team.AddRepository(repo)
	case "remove":
		err = ctx.Org.Team.RemoveRepository(com.StrTo(ctx.Query("repoid")).MustInt64())
	}

	if err != nil {
		log.Error(3, "Action(%s): '%s' %v", ctx.Params(":action"), ctx.Org.Team.Name, err)
		ctx.Handle(500, "TeamsRepoAction", err)
		return
	}
	ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
}
Example #3
0
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 #4
0
func Explore(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("explore")
	ctx.Data["PageIsExploreRepositories"] = true

	page := ctx.QueryInt("page")
	if page <= 1 {
		page = 1
	}

	ctx.Data["Page"] = paginater.New(int(models.CountRepositories()), setting.ExplorePagingNum, page, 5)

	repos, err := models.GetRecentUpdatedRepositories(page)
	if err != nil {
		ctx.Handle(500, "GetRecentUpdatedRepositories", err)
		return
	}
	for _, repo := range repos {
		if err = repo.GetOwner(); err != nil {
			ctx.Handle(500, "GetOwner", fmt.Errorf("%d: %v", repo.ID, err))
			return
		}
	}
	ctx.Data["Repos"] = repos

	ctx.HTML(200, EXPLORE_REPOS)
}
Example #5
0
func NewMilestone(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("repo.milestones.new")
	ctx.Data["PageIsMilestones"] = true
	ctx.Data["RequireDatetimepicker"] = true
	ctx.Data["DateLang"] = setting.DateLang(ctx.Locale.Language())
	ctx.HTML(200, MILESTONE_NEW)
}
Example #6
0
func SignIn(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("sign_in")

	if _, ok := ctx.Session.Get("socialId").(int64); ok {
		ctx.Data["IsSocialLogin"] = true
		ctx.HTML(200, SIGNIN)
		return
	}

	if setting.OauthService != nil {
		ctx.Data["OauthEnabled"] = true
		ctx.Data["OauthService"] = setting.OauthService
	}

	// Check auto-login.
	isSucceed, err := middleware.AutoSignIn(ctx)
	if err != nil {
		ctx.Handle(500, "AutoSignIn", err)
		return
	}

	if isSucceed {
		if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
			ctx.SetCookie("redirect_to", "", -1, setting.AppSubUrl)
			ctx.Redirect(redirectTo)
		}
		ctx.Redirect(setting.AppSubUrl + "/")
		return
	}

	ctx.HTML(200, SIGNIN)
}
Example #7
0
func Invitation(ctx *middleware.Context) {
	org := ctx.Org.Organization
	ctx.Data["Title"] = org.FullName
	ctx.Data["PageIsOrgMembers"] = true

	if ctx.Req.Method == "POST" {
		uname := ctx.Query("uname")
		u, err := models.GetUserByName(uname)
		if err != nil {
			if models.IsErrUserNotExist(err) {
				ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
				ctx.Redirect(ctx.Org.OrgLink + "/invitations/new")
			} else {
				ctx.Handle(500, " GetUserByName", err)
			}
			return
		}

		if err = org.AddMember(u.Id); err != nil {
			ctx.Handle(500, " AddMember", err)
			return
		}

		log.Trace("New member added(%s): %s", org.Name, u.Name)
		ctx.Redirect(ctx.Org.OrgLink + "/members")
		return
	}

	ctx.HTML(200, MEMBER_INVITE)
}
Example #8
0
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 #9
0
func Home(ctx *middleware.Context) {
	if ctx.IsSigned {
		if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
			ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
			ctx.HTML(200, user.ACTIVATE)
		} else {
			user.Dashboard(ctx)
		}
		return
	}

	// Check auto-login.
	uname := ctx.GetCookie(setting.CookieUserName)
	if len(uname) != 0 {
		ctx.Redirect(setting.AppSubUrl + "/user/login")
		return
	}

	if setting.OauthService != nil {
		ctx.Data["OauthEnabled"] = true
		ctx.Data["OauthService"] = setting.OauthService
	}

	ctx.Data["PageIsHome"] = true
	ctx.HTML(200, HOME)
}
Example #10
0
func NewAuthSource(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("admin.auths.new")
	ctx.Data["PageIsAdmin"] = true
	ctx.Data["PageIsAdminAuthentications"] = true
	ctx.Data["LoginTypes"] = models.LoginTypes
	ctx.Data["SMTPAuths"] = models.SMTPAuths
	ctx.HTML(200, AUTH_NEW)
}
Example #11
0
func Monitor(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("admin.monitor")
	ctx.Data["PageIsAdmin"] = true
	ctx.Data["PageIsAdminMonitor"] = true
	ctx.Data["Processes"] = process.Processes
	ctx.Data["Entries"] = cron.ListTasks()
	ctx.HTML(200, MONITOR)
}
Example #12
0
func DeleteTeam(ctx *middleware.Context) {
	if err := models.DeleteTeam(ctx.Org.Team); err != nil {
		ctx.Handle(500, "DeleteTeam", err)
		return
	}
	ctx.Flash.Success(ctx.Tr("org.teams.delete_team_success"))
	ctx.Redirect(ctx.Org.OrgLink + "/teams")
}
Example #13
0
func CompareAndPullRequest(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("repo.pulls.compare_changes")
	ctx.Data["PageIsComparePull"] = true

	repo := ctx.Repo.Repository

	// Get compare branch information.
	infos := strings.Split(ctx.Params("*"), "...")
	if len(infos) != 2 {
		ctx.Handle(404, "CompareAndPullRequest", nil)
		return
	}

	baseBranch := infos[0]
	ctx.Data["BaseBranch"] = baseBranch

	headInfos := strings.Split(infos[1], ":")
	if len(headInfos) != 2 {
		ctx.Handle(404, "CompareAndPullRequest", nil)
		return
	}
	headUser := headInfos[0]
	headBranch := headInfos[1]
	ctx.Data["HeadBranch"] = headBranch

	// TODO: check if branches are valid.
	fmt.Println(baseBranch, headUser, headBranch)

	// TODO: add organization support
	// Check if current user has fork of repository.
	headRepo, has := models.HasForkedRepo(ctx.User.Id, repo.ID)
	if !has {
		ctx.Handle(404, "HasForkedRepo", nil)
		return
	}

	headGitRepo, err := git.OpenRepository(models.RepoPath(ctx.User.Name, headRepo.Name))
	if err != nil {
		ctx.Handle(500, "OpenRepository", err)
		return
	}
	headBranches, err := headGitRepo.GetBranches()
	if err != nil {
		ctx.Handle(500, "GetBranches", err)
		return
	}
	ctx.Data["HeadBranches"] = headBranches

	// Setup information for new form.
	RetrieveRepoMetas(ctx, ctx.Repo.Repository)
	if ctx.Written() {
		return
	}

	// Get diff information.

	ctx.HTML(200, COMPARE_PULL)
}
Example #14
0
func SignInPost(ctx *middleware.Context, form auth.SignInForm) {
	ctx.Data["Title"] = ctx.Tr("sign_in")

	sid, isOauth := ctx.Session.Get("socialId").(int64)
	if isOauth {
		ctx.Data["IsSocialLogin"] = true
	} else if setting.OauthService != nil {
		ctx.Data["OauthEnabled"] = true
		ctx.Data["OauthService"] = setting.OauthService
	}

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

	u, err := models.UserSignIn(form.UserName, form.Password)
	if err != nil {
		if models.IsErrUserNotExist(err) {
			ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), SIGNIN, &form)
		} else {
			ctx.Handle(500, "UserSignIn", err)
		}
		return
	}

	if form.Remember {
		days := 86400 * setting.LogInRememberDays
		ctx.SetCookie(setting.CookieUserName, u.Name, days, setting.AppSubUrl)
		ctx.SetSuperSecureCookie(base.EncodeMd5(u.Rands+u.Passwd),
			setting.CookieRememberName, u.Name, days, setting.AppSubUrl)
	}

	// Bind with social account.
	if isOauth {
		if err = models.BindUserOauth2(u.Id, sid); err != nil {
			if err == models.ErrOauth2RecordNotExist {
				ctx.Handle(404, "GetOauth2ById", err)
			} else {
				ctx.Handle(500, "GetOauth2ById", err)
			}
			return
		}
		ctx.Session.Delete("socialId")
		log.Trace("%s OAuth binded: %s -> %d", ctx.Req.RequestURI, form.UserName, sid)
	}

	ctx.Session.Set("uid", u.Id)
	ctx.Session.Set("uname", u.Name)
	if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
		ctx.SetCookie("redirect_to", "", -1, setting.AppSubUrl)
		ctx.Redirect(redirectTo)
		return
	}

	ctx.Redirect(setting.AppSubUrl + "/")
}
Example #15
0
func MembersAction(ctx *middleware.Context) {
	uid := com.StrTo(ctx.Query("uid")).MustInt64()
	if uid == 0 {
		ctx.Redirect(ctx.Org.OrgLink + "/members")
		return
	}

	org := ctx.Org.Organization
	var err error
	switch ctx.Params(":action") {
	case "private":
		if ctx.User.Id != uid && !ctx.Org.IsOwner {
			ctx.Error(404)
			return
		}
		err = models.ChangeOrgUserStatus(org.Id, uid, false)
	case "public":
		if ctx.User.Id != uid {
			ctx.Error(404)
			return
		}
		err = models.ChangeOrgUserStatus(org.Id, uid, true)
	case "remove":
		if !ctx.Org.IsOwner {
			ctx.Error(404)
			return
		}
		err = org.RemoveMember(uid)
		if models.IsErrLastOrgOwner(err) {
			ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
			ctx.Redirect(ctx.Org.OrgLink + "/members")
			return
		}
	case "leave":
		err = org.RemoveMember(ctx.User.Id)
		if models.IsErrLastOrgOwner(err) {
			ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
			ctx.Redirect(ctx.Org.OrgLink + "/members")
			return
		}
	}

	if err != nil {
		log.Error(4, "Action(%s): %v", ctx.Params(":action"), err)
		ctx.JSON(200, map[string]interface{}{
			"ok":  false,
			"err": err.Error(),
		})
		return
	}

	if ctx.Params(":action") != "leave" {
		ctx.Redirect(ctx.Org.OrgLink + "/members")
	} else {
		ctx.Redirect(setting.AppSubUrl + "/")
	}
}
Example #16
0
func DeleteNotice(ctx *middleware.Context) {
	id := com.StrTo(ctx.Params(":id")).MustInt64()
	if err := models.DeleteNotice(id); err != nil {
		ctx.Handle(500, "DeleteNotice", err)
		return
	}
	log.Trace("System notice deleted by admin(%s): %d", ctx.User.Name, id)
	ctx.Flash.Success(ctx.Tr("admin.notices.delete_success"))
	ctx.Redirect("/admin/notices")
}
Example #17
0
func SettingsDeleteApplication(ctx *middleware.Context) {
	if err := models.DeleteAccessTokenByID(ctx.QueryInt64("id")); err != nil {
		ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error())
	} else {
		ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
	}

	ctx.JSON(200, map[string]interface{}{
		"redirect": setting.AppSubUrl + "/user/settings/applications",
	})
}
Example #18
0
func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) {
	ctx.Data["Title"] = ctx.Tr("org.settings")
	ctx.Data["PageIsSettingsOptions"] = true

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

	org := ctx.Org.Organization

	// Check if organization name has been changed.
	if org.Name != form.OrgUserName {
		isExist, err := models.IsUserExist(org.Id, form.OrgUserName)
		if err != nil {
			ctx.Handle(500, "IsUserExist", err)
			return
		} else if isExist {
			ctx.Data["Err_UserName"] = true
			ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), SETTINGS_OPTIONS, &form)
			return
		} else if err = models.ChangeUserName(org, form.OrgUserName); err != nil {
			if err == models.ErrUserNameIllegal {
				ctx.Data["Err_UserName"] = true
				ctx.RenderWithErr(ctx.Tr("form.illegal_username"), SETTINGS_OPTIONS, &form)
			} else {
				ctx.Handle(500, "ChangeUserName", err)
			}
			return
		}
		log.Trace("Organization name changed: %s -> %s", org.Name, form.OrgUserName)
		org.Name = form.OrgUserName
	}

	org.FullName = form.OrgFullName
	org.Email = form.Email
	org.Description = form.Description
	org.Website = form.Website
	org.Location = form.Location
	org.Avatar = base.EncodeMd5(form.Avatar)
	org.AvatarEmail = form.Avatar
	if err := models.UpdateUser(org); err != nil {
		if models.IsErrEmailAlreadyUsed(err) {
			ctx.Data["Err_Email"] = true
			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_OPTIONS, &form)
		} else {
			ctx.Handle(500, "UpdateUser", err)
		}
		return
	}
	log.Trace("Organization setting updated: %s", org.Name)
	ctx.Flash.Success(ctx.Tr("org.settings.update_setting_success"))
	ctx.Redirect(setting.AppSubUrl + "/org/" + org.Name + "/settings")
}
Example #19
0
func DeleteWebhook(ctx *middleware.Context) {
	if err := models.DeleteWebhook(ctx.QueryInt64("id")); err != nil {
		ctx.Flash.Error("DeleteWebhook: " + err.Error())
	} else {
		ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
	}

	ctx.JSON(200, map[string]interface{}{
		"redirect": ctx.Org.OrgLink + "/settings/hooks",
	})
}
Example #20
0
func DeleteSSHKey(ctx *middleware.Context) {
	if err := models.DeletePublicKey(ctx.QueryInt64("id")); err != nil {
		ctx.Flash.Error("DeletePublicKey: " + err.Error())
	} else {
		ctx.Flash.Success(ctx.Tr("settings.ssh_key_deletion_success"))
	}

	ctx.JSON(200, map[string]interface{}{
		"redirect": setting.AppSubUrl + "/user/settings/ssh",
	})
}
Example #21
0
func InstallInit(ctx *middleware.Context) {
	if setting.InstallLock {
		ctx.Handle(404, "Install", errors.New("Installation is prohibited"))
		return
	}

	ctx.Data["Title"] = ctx.Tr("install.install")
	ctx.Data["PageIsInstall"] = true

	ctx.Data["DbOptions"] = []string{"MySQL", "PostgreSQL", "SQLite3"}
}
Example #22
0
func DeleteMilestone(ctx *middleware.Context) {
	if err := models.DeleteMilestoneByID(ctx.QueryInt64("id")); err != nil {
		ctx.Flash.Error("DeleteMilestoneByID: " + err.Error())
	} else {
		ctx.Flash.Success(ctx.Tr("repo.milestones.deletion_success"))
	}

	ctx.JSON(200, map[string]interface{}{
		"redirect": ctx.Repo.RepoLink + "/milestones",
	})
}
Example #23
0
func DeleteDeployKey(ctx *middleware.Context) {
	if err := models.DeleteDeployKey(ctx.QueryInt64("id")); err != nil {
		ctx.Flash.Error("DeleteDeployKey: " + err.Error())
	} else {
		ctx.Flash.Success(ctx.Tr("repo.settings.deploy_key_deletion_success"))
	}

	ctx.JSON(200, map[string]interface{}{
		"redirect": ctx.Repo.RepoLink + "/settings/keys",
	})
}
Example #24
0
func Fork(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("new_fork")

	getForkRepository(ctx)
	if ctx.Written() {
		return
	}

	ctx.Data["ContextUser"] = ctx.User
	ctx.HTML(200, FORK)
}
Example #25
0
func Migrate(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("new_migrate")
	ctx.Data["private"] = ctx.User.LastRepoVisibility

	ctxUser := checkContextUser(ctx, ctx.QueryInt64("org"))
	if ctx.Written() {
		return
	}
	ctx.Data["ContextUser"] = ctxUser

	ctx.HTML(200, MIGRATE)
}
Example #26
0
func ResetPasswd(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("auth.reset_password")

	code := ctx.Query("code")
	if len(code) == 0 {
		ctx.Error(404)
		return
	}
	ctx.Data["Code"] = code
	ctx.Data["IsResetForm"] = true
	ctx.HTML(200, RESET_PASSWORD)
}
Example #27
0
func DeleteLabel(ctx *middleware.Context) {
	if err := models.DeleteLabel(ctx.Repo.Repository.ID, ctx.QueryInt64("id")); err != nil {
		ctx.Flash.Error("DeleteLabel: " + err.Error())
	} else {
		ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success"))
	}

	ctx.JSON(200, map[string]interface{}{
		"redirect": ctx.Repo.RepoLink + "/labels",
	})
	return
}
Example #28
0
func Config(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("admin.users")
	ctx.Data["PageIsAdmin"] = true
	ctx.Data["PageIsAdminConfig"] = true

	ctx.Data["AppUrl"] = setting.AppUrl
	ctx.Data["Domain"] = setting.Domain
	ctx.Data["OfflineMode"] = setting.OfflineMode
	ctx.Data["DisableRouterLog"] = setting.DisableRouterLog
	ctx.Data["RunUser"] = setting.RunUser
	ctx.Data["RunMode"] = strings.Title(macaron.Env)
	ctx.Data["RepoRootPath"] = setting.RepoRootPath
	ctx.Data["StaticRootPath"] = setting.StaticRootPath
	ctx.Data["LogRootPath"] = setting.LogRootPath
	ctx.Data["ScriptType"] = setting.ScriptType
	ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser

	ctx.Data["Service"] = setting.Service
	ctx.Data["DbCfg"] = models.DbCfg
	ctx.Data["Webhook"] = setting.Webhook

	ctx.Data["MailerEnabled"] = false
	if setting.MailService != nil {
		ctx.Data["MailerEnabled"] = true
		ctx.Data["Mailer"] = setting.MailService
	}

	ctx.Data["OauthEnabled"] = false
	if setting.OauthService != nil {
		ctx.Data["OauthEnabled"] = true
		ctx.Data["Oauther"] = setting.OauthService
	}

	ctx.Data["CacheAdapter"] = setting.CacheAdapter
	ctx.Data["CacheInternal"] = setting.CacheInternal
	ctx.Data["CacheConn"] = setting.CacheConn

	ctx.Data["SessionConfig"] = setting.SessionConfig

	ctx.Data["PictureService"] = setting.PictureService
	ctx.Data["DisableGravatar"] = setting.DisableGravatar

	type logger struct {
		Mode, Config string
	}
	loggers := make([]*logger, len(setting.LogModes))
	for i := range setting.LogModes {
		loggers[i] = &logger{setting.LogModes[i], setting.LogConfigs[i]}
	}
	ctx.Data["Loggers"] = loggers

	ctx.HTML(200, CONFIG)
}
Example #29
0
func ForgotPasswd(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("auth.forgot_password")

	if setting.MailService == nil {
		ctx.Data["IsResetDisable"] = true
		ctx.HTML(200, FORGOT_PASSWORD)
		return
	}

	ctx.Data["IsResetRequest"] = true
	ctx.HTML(200, FORGOT_PASSWORD)
}
Example #30
0
func NewRelease(ctx *middleware.Context) {
	if !ctx.Repo.IsOwner() {
		ctx.Handle(403, "release.ReleasesNew", nil)
		return
	}

	ctx.Data["Title"] = ctx.Tr("repo.release.new_release")
	ctx.Data["tag_target"] = ctx.Repo.Repository.DefaultBranch
	ctx.Data["IsRepoToolbarReleases"] = true
	ctx.Data["IsRepoReleaseNew"] = true
	ctx.HTML(200, RELEASE_NEW)
}