Added option to disable migrations (#13114)
* Added option to disable migrations This patch introduces DISABLE_MIGRATIONS parameter in [repository] section of app.ini (by default set to false). If set to true it blocks access to repository migration feature. This mod hides also local repo import option in user editor if local repo importing or migrations is disabled. * Alter Example config DISABLE_MIGRATIONS set to false in example config to match its default value. * HTTP error 403 instead of 500 on denied access to migration * Parameter DISABLE_MIGRATIONS exposed via API Fixes: 04b04cf854bcb3ed7659442bcf79822bdebe29e9 Author-Change-Id: IB#1105130
This commit is contained in:
parent
3a500cf8c4
commit
839daa85aa
14 changed files with 52 additions and 11 deletions
|
@ -66,6 +66,8 @@ DEFAULT_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,re
|
||||||
PREFIX_ARCHIVE_FILES = true
|
PREFIX_ARCHIVE_FILES = true
|
||||||
; Disable the creation of new mirrors. Pre-existing mirrors remain valid.
|
; Disable the creation of new mirrors. Pre-existing mirrors remain valid.
|
||||||
DISABLE_MIRRORS = false
|
DISABLE_MIRRORS = false
|
||||||
|
; Disable migrating feature.
|
||||||
|
DISABLE_MIGRATIONS = false
|
||||||
; The default branch name of new repositories
|
; The default branch name of new repositories
|
||||||
DEFAULT_BRANCH = master
|
DEFAULT_BRANCH = master
|
||||||
; Allow adoption of unadopted repositories
|
; Allow adoption of unadopted repositories
|
||||||
|
|
|
@ -74,6 +74,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
- `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects**: Comma separated list of default repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list.
|
- `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects**: Comma separated list of default repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list.
|
||||||
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
||||||
- `DISABLE_MIRRORS`: **false**: Disable the creation of **new** mirrors. Pre-existing mirrors remain valid.
|
- `DISABLE_MIRRORS`: **false**: Disable the creation of **new** mirrors. Pre-existing mirrors remain valid.
|
||||||
|
- `DISABLE_MIGRATIONS`: **false**: Disable migrating feature.
|
||||||
- `DEFAULT_BRANCH`: **master**: Default branch name of all repositories.
|
- `DEFAULT_BRANCH`: **master**: Default branch name of all repositories.
|
||||||
- `ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to adopt unadopted repositories
|
- `ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to adopt unadopted repositories
|
||||||
- `ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to delete unadopted repositories
|
- `ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to delete unadopted repositories
|
||||||
|
|
|
@ -45,6 +45,7 @@ func TestAPIExposedSettings(t *testing.T) {
|
||||||
assert.EqualValues(t, &api.GeneralRepoSettings{
|
assert.EqualValues(t, &api.GeneralRepoSettings{
|
||||||
MirrorsDisabled: setting.Repository.DisableMirrors,
|
MirrorsDisabled: setting.Repository.DisableMirrors,
|
||||||
HTTPGitDisabled: setting.Repository.DisableHTTPGit,
|
HTTPGitDisabled: setting.Repository.DisableHTTPGit,
|
||||||
|
MigrationsDisabled: setting.Repository.DisableMigrations,
|
||||||
}, repo)
|
}, repo)
|
||||||
|
|
||||||
attachment := new(api.GeneralAttachmentSettings)
|
attachment := new(api.GeneralAttachmentSettings)
|
||||||
|
|
|
@ -343,6 +343,7 @@ func Contexter() macaron.Handler {
|
||||||
|
|
||||||
ctx.Data["EnableSwagger"] = setting.API.EnableSwagger
|
ctx.Data["EnableSwagger"] = setting.API.EnableSwagger
|
||||||
ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn
|
ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn
|
||||||
|
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations
|
||||||
|
|
||||||
c.Map(ctx)
|
c.Map(ctx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/migrations"
|
"code.gitea.io/gitea/modules/migrations"
|
||||||
repository_service "code.gitea.io/gitea/modules/repository"
|
repository_service "code.gitea.io/gitea/modules/repository"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
mirror_service "code.gitea.io/gitea/services/mirror"
|
mirror_service "code.gitea.io/gitea/services/mirror"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -115,5 +116,7 @@ func initBasicTasks() {
|
||||||
registerArchiveCleanup()
|
registerArchiveCleanup()
|
||||||
registerSyncExternalUsers()
|
registerSyncExternalUsers()
|
||||||
registerDeletedBranchesCleanup()
|
registerDeletedBranchesCleanup()
|
||||||
|
if !setting.Repository.DisableMigrations {
|
||||||
registerUpdateMigrationPosterID()
|
registerUpdateMigrationPosterID()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ var (
|
||||||
DefaultRepoUnits []string
|
DefaultRepoUnits []string
|
||||||
PrefixArchiveFiles bool
|
PrefixArchiveFiles bool
|
||||||
DisableMirrors bool
|
DisableMirrors bool
|
||||||
|
DisableMigrations bool
|
||||||
DefaultBranch string
|
DefaultBranch string
|
||||||
AllowAdoptionOfUnadoptedRepositories bool
|
AllowAdoptionOfUnadoptedRepositories bool
|
||||||
AllowDeleteOfUnadoptedRepositories bool
|
AllowDeleteOfUnadoptedRepositories bool
|
||||||
|
@ -152,6 +153,7 @@ var (
|
||||||
DefaultRepoUnits: []string{},
|
DefaultRepoUnits: []string{},
|
||||||
PrefixArchiveFiles: true,
|
PrefixArchiveFiles: true,
|
||||||
DisableMirrors: false,
|
DisableMirrors: false,
|
||||||
|
DisableMigrations: false,
|
||||||
DefaultBranch: "master",
|
DefaultBranch: "master",
|
||||||
|
|
||||||
// Repository editor settings
|
// Repository editor settings
|
||||||
|
|
|
@ -8,6 +8,7 @@ package structs
|
||||||
type GeneralRepoSettings struct {
|
type GeneralRepoSettings struct {
|
||||||
MirrorsDisabled bool `json:"mirrors_disabled"`
|
MirrorsDisabled bool `json:"mirrors_disabled"`
|
||||||
HTTPGitDisabled bool `json:"http_git_disabled"`
|
HTTPGitDisabled bool `json:"http_git_disabled"`
|
||||||
|
MigrationsDisabled bool `json:"migrations_disabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeneralUISettings contains global ui settings exposed by API
|
// GeneralUISettings contains global ui settings exposed by API
|
||||||
|
|
|
@ -191,6 +191,7 @@ func EditUser(ctx *context.Context) {
|
||||||
ctx.Data["PageIsAdmin"] = true
|
ctx.Data["PageIsAdmin"] = true
|
||||||
ctx.Data["PageIsAdminUsers"] = true
|
ctx.Data["PageIsAdminUsers"] = true
|
||||||
ctx.Data["DisableRegularOrgCreation"] = setting.Admin.DisableRegularOrgCreation
|
ctx.Data["DisableRegularOrgCreation"] = setting.Admin.DisableRegularOrgCreation
|
||||||
|
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations
|
||||||
|
|
||||||
prepareUserInfo(ctx)
|
prepareUserInfo(ctx)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
|
@ -205,6 +206,7 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
|
||||||
ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
|
ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
|
||||||
ctx.Data["PageIsAdmin"] = true
|
ctx.Data["PageIsAdmin"] = true
|
||||||
ctx.Data["PageIsAdminUsers"] = true
|
ctx.Data["PageIsAdminUsers"] = true
|
||||||
|
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations
|
||||||
|
|
||||||
u := prepareUserInfo(ctx)
|
u := prepareUserInfo(ctx)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
|
|
|
@ -119,6 +119,11 @@ func Migrate(ctx *context.APIContext, form api.MigrateRepoOptions) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if setting.Repository.DisableMigrations {
|
||||||
|
ctx.Error(http.StatusForbidden, "MigrationsGlobalDisabled", fmt.Errorf("the site administrator has disabled migrations"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var opts = migrations.MigrateOptions{
|
var opts = migrations.MigrateOptions{
|
||||||
CloneAddr: remoteAddr,
|
CloneAddr: remoteAddr,
|
||||||
RepoName: form.RepoName,
|
RepoName: form.RepoName,
|
||||||
|
|
|
@ -59,6 +59,7 @@ func GetGeneralRepoSettings(ctx *context.APIContext) {
|
||||||
ctx.JSON(http.StatusOK, api.GeneralRepoSettings{
|
ctx.JSON(http.StatusOK, api.GeneralRepoSettings{
|
||||||
MirrorsDisabled: setting.Repository.DisableMirrors,
|
MirrorsDisabled: setting.Repository.DisableMirrors,
|
||||||
HTTPGitDisabled: setting.Repository.DisableHTTPGit,
|
HTTPGitDisabled: setting.Repository.DisableHTTPGit,
|
||||||
|
MigrationsDisabled: setting.Repository.DisableMigrations,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
|
@ -25,6 +26,11 @@ const (
|
||||||
|
|
||||||
// Migrate render migration of repository page
|
// Migrate render migration of repository page
|
||||||
func Migrate(ctx *context.Context) {
|
func Migrate(ctx *context.Context) {
|
||||||
|
if setting.Repository.DisableMigrations {
|
||||||
|
ctx.Error(http.StatusForbidden, "Migrate: the site administrator has disabled migrations")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["Services"] = append([]structs.GitServiceType{structs.PlainGitService}, structs.SupportedFullGitService...)
|
ctx.Data["Services"] = append([]structs.GitServiceType{structs.PlainGitService}, structs.SupportedFullGitService...)
|
||||||
serviceType := ctx.QueryInt("service_type")
|
serviceType := ctx.QueryInt("service_type")
|
||||||
if serviceType == 0 {
|
if serviceType == 0 {
|
||||||
|
@ -60,6 +66,11 @@ func Migrate(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMigrateError(ctx *context.Context, owner *models.User, err error, name string, tpl base.TplName, form *auth.MigrateRepoForm) {
|
func handleMigrateError(ctx *context.Context, owner *models.User, err error, name string, tpl base.TplName, form *auth.MigrateRepoForm) {
|
||||||
|
if setting.Repository.DisableMigrations {
|
||||||
|
ctx.Error(http.StatusForbidden, "MigrateError: the site administrator has disabled migrations")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case migrations.IsRateLimitError(err):
|
case migrations.IsRateLimitError(err):
|
||||||
ctx.RenderWithErr(ctx.Tr("form.visit_rate_limit"), tpl, form)
|
ctx.RenderWithErr(ctx.Tr("form.visit_rate_limit"), tpl, form)
|
||||||
|
@ -107,6 +118,11 @@ func handleMigrateError(ctx *context.Context, owner *models.User, err error, nam
|
||||||
|
|
||||||
// MigratePost response for migrating from external git repository
|
// MigratePost response for migrating from external git repository
|
||||||
func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) {
|
func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) {
|
||||||
|
if setting.Repository.DisableMigrations {
|
||||||
|
ctx.Error(http.StatusForbidden, "MigratePost: the site administrator has disabled migrations")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["Title"] = ctx.Tr("new_migrate")
|
ctx.Data["Title"] = ctx.Tr("new_migrate")
|
||||||
// Plain git should be first
|
// Plain git should be first
|
||||||
ctx.Data["service"] = structs.GitServiceType(form.Service)
|
ctx.Data["service"] = structs.GitServiceType(form.Service)
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
<input name="allow_git_hook" type="checkbox" {{if .User.CanEditGitHook}}checked{{end}} {{if DisableGitHooks}}disabled{{end}}>
|
<input name="allow_git_hook" type="checkbox" {{if .User.CanEditGitHook}}checked{{end}} {{if DisableGitHooks}}disabled{{end}}>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline field">
|
<div class="inline field" {{if or (DisableImportLocal) (.DisableMigrations)}}hidden{{end}}>
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
<label><strong>{{.i18n.Tr "admin.users.allow_import_local"}}</strong></label>
|
<label><strong>{{.i18n.Tr "admin.users.allow_import_local"}}</strong></label>
|
||||||
<input name="allow_import_local" type="checkbox" {{if .User.CanImportLocal}}checked{{end}} {{if DisableImportLocal}}disabled{{end}}>
|
<input name="allow_import_local" type="checkbox" {{if .User.CanImportLocal}}checked{{end}} {{if DisableImportLocal}}disabled{{end}}>
|
||||||
|
|
|
@ -89,9 +89,11 @@
|
||||||
<a class="item" href="{{AppSubUrl}}/repo/create">
|
<a class="item" href="{{AppSubUrl}}/repo/create">
|
||||||
<span class="fitted">{{svg "octicon-plus"}}</span> {{.i18n.Tr "new_repo"}}
|
<span class="fitted">{{svg "octicon-plus"}}</span> {{.i18n.Tr "new_repo"}}
|
||||||
</a>
|
</a>
|
||||||
|
{{if not .DisableMigrations}}
|
||||||
<a class="item" href="{{AppSubUrl}}/repo/migrate">
|
<a class="item" href="{{AppSubUrl}}/repo/migrate">
|
||||||
<span class="fitted">{{svg "octicon-repo-push"}}</span> {{.i18n.Tr "new_migrate"}}
|
<span class="fitted">{{svg "octicon-repo-push"}}</span> {{.i18n.Tr "new_migrate"}}
|
||||||
</a>
|
</a>
|
||||||
|
{{end}}
|
||||||
{{if .SignedUser.CanCreateOrganization}}
|
{{if .SignedUser.CanCreateOrganization}}
|
||||||
<a class="item" href="{{AppSubUrl}}/org/create">
|
<a class="item" href="{{AppSubUrl}}/org/create">
|
||||||
<span class="fitted">{{svg "octicon-organization"}}</span> {{.i18n.Tr "new_org"}}
|
<span class="fitted">{{svg "octicon-organization"}}</span> {{.i18n.Tr "new_org"}}
|
||||||
|
|
|
@ -13688,6 +13688,10 @@
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"x-go-name": "HTTPGitDisabled"
|
"x-go-name": "HTTPGitDisabled"
|
||||||
},
|
},
|
||||||
|
"migrations_disabled": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-go-name": "MigrationsDisabled"
|
||||||
|
},
|
||||||
"mirrors_disabled": {
|
"mirrors_disabled": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"x-go-name": "MirrorsDisabled"
|
"x-go-name": "MirrorsDisabled"
|
||||||
|
|
Loading…
Reference in a new issue