mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Restrict creating organisations by user (#193)
* restrict creating organizations based on right on user * revert bindata.go * reverse vendor lib * revert goimports change * set AllowCreateOrganization default value to true * revert locale * added default value for AllowCreateOrganization * fix typo in migration-comment * fix comment * add coments in migration
This commit is contained in:
		| @@ -123,6 +123,20 @@ func (err ErrUserHasOrgs) Error() string { | ||||
| 	return fmt.Sprintf("user still has membership of organizations [uid: %d]", err.UID) | ||||
| } | ||||
|  | ||||
| // ErrUserNotAllowedCreateOrg represents a "UserNotAllowedCreateOrg" kind of error. | ||||
| type ErrUserNotAllowedCreateOrg struct { | ||||
| } | ||||
|  | ||||
| // IsErrUserNotAllowedCreateOrg checks if an error is an ErrUserNotAllowedCreateOrg. | ||||
| func IsErrUserNotAllowedCreateOrg(err error) bool { | ||||
| 	_, ok := err.(ErrUserNotAllowedCreateOrg) | ||||
| 	return ok | ||||
| } | ||||
|  | ||||
| func (err ErrUserNotAllowedCreateOrg) Error() string { | ||||
| 	return fmt.Sprintf("user is not allowed to create organizations") | ||||
| } | ||||
|  | ||||
| // ErrReachLimitOfRepo represents a "ReachLimitOfRepo" kind of error. | ||||
| type ErrReachLimitOfRepo struct { | ||||
| 	Limit int | ||||
|   | ||||
| @@ -76,8 +76,10 @@ var migrations = []Migration{ | ||||
|  | ||||
| 	// v13 -> v14:v0.9.87 | ||||
| 	NewMigration("set comment updated with created", setCommentUpdatedWithCreated), | ||||
|  | ||||
| 	// v14 | ||||
| 	NewMigration("create user column diff view style", createUserColumnDiffViewStyle), | ||||
| 	// v15 | ||||
| 	NewMigration("create user column allow create organization", createAllowCreateOrganizationColumn), | ||||
| } | ||||
|  | ||||
| // Migrate database to current version | ||||
|   | ||||
							
								
								
									
										30
									
								
								models/migrations/v15.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								models/migrations/v15.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| // Copyright 2016 Gitea. All rights reserved. | ||||
| // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package migrations | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/go-xorm/xorm" | ||||
| ) | ||||
|  | ||||
| // UserV15 describes the added field for User | ||||
| type UserV15 struct { | ||||
| 	AllowCreateOrganization bool | ||||
| } | ||||
|  | ||||
| // TableName will be invoked by XORM to customrize the table name | ||||
| func (*UserV15) TableName() string { | ||||
| 	return "user" | ||||
| } | ||||
|  | ||||
| func createAllowCreateOrganizationColumn(x *xorm.Engine) error { | ||||
| 	if err := x.Sync2(new(UserV15)); err != nil { | ||||
| 		return fmt.Errorf("Sync2: %v", err) | ||||
| 	} else if _, err = x.Where("type=0").Cols("allow_create_organization").Update(&UserV15{AllowCreateOrganization: true}); err != nil { | ||||
| 		return fmt.Errorf("set allow_create_organization: %v", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -97,6 +97,10 @@ func (org *User) RemoveOrgRepo(repoID int64) error { | ||||
|  | ||||
| // CreateOrganization creates record of a new organization. | ||||
| func CreateOrganization(org, owner *User) (err error) { | ||||
| 	if !owner.CanCreateOrganization() { | ||||
| 		return ErrUserNotAllowedCreateOrg{} | ||||
| 	} | ||||
|  | ||||
| 	if err = IsUsableUsername(org.Name); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|   | ||||
| @@ -106,6 +106,7 @@ type User struct { | ||||
| 	IsAdmin                 bool | ||||
| 	AllowGitHook            bool | ||||
| 	AllowImportLocal        bool // Allow migrate repository by local path | ||||
| 	AllowCreateOrganization bool `xorm:"DEFAULT true"` | ||||
| 	ProhibitLogin           bool | ||||
|  | ||||
| 	// Avatar | ||||
| @@ -210,6 +211,11 @@ func (u *User) CanCreateRepo() bool { | ||||
| 	return u.NumRepos < u.MaxRepoCreation | ||||
| } | ||||
|  | ||||
| // CanCreateOrganization returns true if user can create organisation. | ||||
| func (u *User) CanCreateOrganization() bool { | ||||
| 	return u.IsAdmin || u.AllowCreateOrganization | ||||
| } | ||||
|  | ||||
| // CanEditGitHook returns true if user can edit Git hooks. | ||||
| func (u *User) CanEditGitHook() bool { | ||||
| 	return u.IsAdmin || u.AllowGitHook | ||||
| @@ -611,6 +617,7 @@ func CreateUser(u *User) (err error) { | ||||
| 		return err | ||||
| 	} | ||||
| 	u.EncodePasswd() | ||||
| 	u.AllowCreateOrganization = true | ||||
| 	u.MaxRepoCreation = -1 | ||||
|  | ||||
| 	sess := x.NewSession() | ||||
|   | ||||
| @@ -39,6 +39,7 @@ type AdminEditUserForm struct { | ||||
| 	Admin                   bool | ||||
| 	AllowGitHook            bool | ||||
| 	AllowImportLocal        bool | ||||
| 	AllowCreateOrganization bool | ||||
| 	ProhibitLogin           bool | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -844,6 +844,7 @@ team_permission_desc = What permission level should this team have? | ||||
|  | ||||
| form.name_reserved = Organization name '%s' is reserved. | ||||
| form.name_pattern_not_allowed = Organization name pattern '%s' is not allowed. | ||||
| form.create_org_not_allowed = This user is not allowed to create an organization. | ||||
|  | ||||
| settings = Settings | ||||
| settings.options = Options | ||||
| @@ -994,6 +995,7 @@ users.prohibit_login = This account is prohibited to login | ||||
| users.is_admin = This account has administrator permissions | ||||
| users.allow_git_hook = This account has permissions to create Git hooks | ||||
| users.allow_import_local = This account has permissions to import local repositories | ||||
| users.allow_create_organization = This account has permissions to create Organizations | ||||
| users.update_profile = Update Account Profile | ||||
| users.delete_account = Delete This Account | ||||
| users.still_own_repo = This account still has ownership over at least one repository, you have to delete or transfer them first. | ||||
|   | ||||
| @@ -214,6 +214,7 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) { | ||||
| 	u.IsAdmin = form.Admin | ||||
| 	u.AllowGitHook = form.AllowGitHook | ||||
| 	u.AllowImportLocal = form.AllowImportLocal | ||||
| 	u.AllowCreateOrganization = form.AllowCreateOrganization | ||||
| 	u.ProhibitLogin = form.ProhibitLogin | ||||
|  | ||||
| 	if err := models.UpdateUser(u); err != nil { | ||||
|   | ||||
| @@ -5,6 +5,8 @@ | ||||
| package org | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
|  | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/modules/auth" | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| @@ -21,6 +23,10 @@ const ( | ||||
| // Create render the page for create organization | ||||
| func Create(ctx *context.Context) { | ||||
| 	ctx.Data["Title"] = ctx.Tr("new_org") | ||||
| 	if !ctx.User.CanCreateOrganization() { | ||||
| 		ctx.Handle(500, "Not allowed", errors.New(ctx.Tr("org.form.create_org_not_allowed"))) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.HTML(200, tplCreateOrg) | ||||
| } | ||||
|  | ||||
| @@ -48,6 +54,8 @@ func CreatePost(ctx *context.Context, form auth.CreateOrgForm) { | ||||
| 			ctx.RenderWithErr(ctx.Tr("org.form.name_reserved", err.(models.ErrNameReserved).Name), tplCreateOrg, &form) | ||||
| 		case models.IsErrNamePatternNotAllowed(err): | ||||
| 			ctx.RenderWithErr(ctx.Tr("org.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tplCreateOrg, &form) | ||||
| 		case models.IsErrUserNotAllowedCreateOrg(err): | ||||
| 			ctx.RenderWithErr(ctx.Tr("org.form.create_org_not_allowed"), tplCreateOrg, &form) | ||||
| 		default: | ||||
| 			ctx.Handle(500, "CreateOrganization", err) | ||||
| 		} | ||||
|   | ||||
| @@ -97,6 +97,12 @@ | ||||
| 								<input name="allow_import_local" type="checkbox" {{if .User.CanImportLocal}}checked{{end}}> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="inline field"> | ||||
| 							<div class="ui checkbox"> | ||||
| 								<label><strong>{{.i18n.Tr "admin.users.allow_create_organization"}}</strong></label> | ||||
| 								<input name="allow_create_organization" type="checkbox" {{if .User.CanCreateOrganization}}checked{{end}}> | ||||
| 							</div> | ||||
| 						</div> | ||||
|  | ||||
| 						<div class="ui divider"></div> | ||||
|  | ||||
|   | ||||
| @@ -94,9 +94,11 @@ | ||||
| 												<a class="item" href="{{AppSubUrl}}/repo/migrate"> | ||||
| 													<i class="octicon octicon-repo-clone"></i> {{.i18n.Tr "new_migrate"}} | ||||
| 												</a> | ||||
| 												{{if .SignedUser.CanCreateOrganization}} | ||||
| 												<a class="item" href="{{AppSubUrl}}/org/create"> | ||||
| 													<i class="octicon octicon-organization"></i> {{.i18n.Tr "new_org"}} | ||||
| 												</a> | ||||
| 												{{end}} | ||||
| 											</div><!-- end content create new menu --> | ||||
| 										</div><!-- end dropdown menu create new --> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user