mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	#1511 Allow local import only for admin users
This commit is contained in:
		@@ -5,7 +5,7 @@ Gogs - Go Git Service [
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##### Current version: 0.6.23 Beta
 | 
					##### Current version: 0.6.24 Beta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<table>
 | 
					<table>
 | 
				
			||||||
    <tr>
 | 
					    <tr>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -360,6 +360,7 @@ migrate_type_helper=Diese Repository wird ein <span class="text blue">Spiegel</s
 | 
				
			|||||||
migrate_repo=Repository migrieren
 | 
					migrate_repo=Repository migrieren
 | 
				
			||||||
migrate.clone_address=Adresse kopieren
 | 
					migrate.clone_address=Adresse kopieren
 | 
				
			||||||
migrate.clone_address_desc=Dies kann eine HTTP/HTTPS/GIT URL oder ein lokaler Serverpfad sein.
 | 
					migrate.clone_address_desc=Dies kann eine HTTP/HTTPS/GIT URL oder ein lokaler Serverpfad sein.
 | 
				
			||||||
 | 
					migrate.permission_denied=You are not allowed to import local repositories.
 | 
				
			||||||
migrate.invalid_local_path=Lokaler Pfad ist ungültig, er existiert nicht oder ist kein Ordner.
 | 
					migrate.invalid_local_path=Lokaler Pfad ist ungültig, er existiert nicht oder ist kein Ordner.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
forked_from=Geforkt von
 | 
					forked_from=Geforkt von
 | 
				
			||||||
@@ -651,7 +652,7 @@ release.tag_name_already_exist=Ein Release mit diesem Tag existiert bereits.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[org]
 | 
					[org]
 | 
				
			||||||
org_name_holder=Name der Organisation
 | 
					org_name_holder=Name der Organisation
 | 
				
			||||||
org_full_name_holder=Organization Full Name
 | 
					org_full_name_holder=Vollständiger Name der Organisation
 | 
				
			||||||
org_name_helper=Gute Namen von Organisationen sind kurz und einprägsam.
 | 
					org_name_helper=Gute Namen von Organisationen sind kurz und einprägsam.
 | 
				
			||||||
create_org=Organisation erstellen
 | 
					create_org=Organisation erstellen
 | 
				
			||||||
repo_updated=Aktualisiert
 | 
					repo_updated=Aktualisiert
 | 
				
			||||||
@@ -808,6 +809,7 @@ users.edit_account=Konto bearbeiten
 | 
				
			|||||||
users.is_activated=Dieses Konto ist aktiviert
 | 
					users.is_activated=Dieses Konto ist aktiviert
 | 
				
			||||||
users.is_admin=Dieses Konto hat Administratorrechte
 | 
					users.is_admin=Dieses Konto hat Administratorrechte
 | 
				
			||||||
users.allow_git_hook=Dieses Konto ist berechtigt, Git-Hooks zu erstellen
 | 
					users.allow_git_hook=Dieses Konto ist berechtigt, Git-Hooks zu erstellen
 | 
				
			||||||
 | 
					users.allow_import_local=This account has permissions to import local repositories
 | 
				
			||||||
users.update_profile=Kontoprofil aktualisieren
 | 
					users.update_profile=Kontoprofil aktualisieren
 | 
				
			||||||
users.delete_account=Dieses Konto löschen
 | 
					users.delete_account=Dieses Konto löschen
 | 
				
			||||||
users.still_own_repo=Dieses Konto besitzt noch Repositories. Diese müssen zuerst gelöscht oder übertragen werden.
 | 
					users.still_own_repo=Dieses Konto besitzt noch Repositories. Diese müssen zuerst gelöscht oder übertragen werden.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -360,6 +360,7 @@ migrate_type_helper = This repository will be a <span class="text blue">mirror</
 | 
				
			|||||||
migrate_repo = Migrate Repository
 | 
					migrate_repo = Migrate Repository
 | 
				
			||||||
migrate.clone_address = Clone Address
 | 
					migrate.clone_address = Clone Address
 | 
				
			||||||
migrate.clone_address_desc = This can be a HTTP/HTTPS/GIT URL or local server path.
 | 
					migrate.clone_address_desc = This can be a HTTP/HTTPS/GIT URL or local server path.
 | 
				
			||||||
 | 
					migrate.permission_denied = You are not allowed to import local repositories.
 | 
				
			||||||
migrate.invalid_local_path = Invalid local path, it does not exist or not a directory.
 | 
					migrate.invalid_local_path = Invalid local path, it does not exist or not a directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
forked_from = forked from
 | 
					forked_from = forked from
 | 
				
			||||||
@@ -808,6 +809,7 @@ users.edit_account = Edit Account
 | 
				
			|||||||
users.is_activated = This account is activated
 | 
					users.is_activated = This account is activated
 | 
				
			||||||
users.is_admin = This account has administrator permissions
 | 
					users.is_admin = This account has administrator permissions
 | 
				
			||||||
users.allow_git_hook = This account has permissions to create Git hooks
 | 
					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.update_profile = Update Account Profile
 | 
					users.update_profile = Update Account Profile
 | 
				
			||||||
users.delete_account = Delete This Account
 | 
					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.
 | 
					users.still_own_repo = This account still has ownership over at least one repository, you have to delete or transfer them first.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -360,6 +360,7 @@ migrate_type_helper=该仓库将是一个 <span class="text blue">镜像</span>
 | 
				
			|||||||
migrate_repo=迁移仓库
 | 
					migrate_repo=迁移仓库
 | 
				
			||||||
migrate.clone_address=克隆地址
 | 
					migrate.clone_address=克隆地址
 | 
				
			||||||
migrate.clone_address_desc=该地址可以是 HTTP/HTTPS/GIT URL 或本地服务器路径。
 | 
					migrate.clone_address_desc=该地址可以是 HTTP/HTTPS/GIT URL 或本地服务器路径。
 | 
				
			||||||
 | 
					migrate.permission_denied=您没有获得导入本地仓库的权限。
 | 
				
			||||||
migrate.invalid_local_path=无效的本地路径,不存在或不是一个目录!
 | 
					migrate.invalid_local_path=无效的本地路径,不存在或不是一个目录!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
forked_from=派生自
 | 
					forked_from=派生自
 | 
				
			||||||
@@ -807,7 +808,8 @@ users.update_profile_success=该用户信息更新成功!
 | 
				
			|||||||
users.edit_account=编辑用户信息
 | 
					users.edit_account=编辑用户信息
 | 
				
			||||||
users.is_activated=该用户已被激活
 | 
					users.is_activated=该用户已被激活
 | 
				
			||||||
users.is_admin=该用户具有管理员权限
 | 
					users.is_admin=该用户具有管理员权限
 | 
				
			||||||
users.allow_git_hook=该帐户具有创建 Git 钩子的权限
 | 
					users.allow_git_hook=该用户具有创建 Git 钩子的权限
 | 
				
			||||||
 | 
					users.allow_import_local=该用户具有导入本地仓库的权限
 | 
				
			||||||
users.update_profile=更新用户信息
 | 
					users.update_profile=更新用户信息
 | 
				
			||||||
users.delete_account=删除该用户
 | 
					users.delete_account=删除该用户
 | 
				
			||||||
users.still_own_repo=该帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作!
 | 
					users.still_own_repo=该帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作!
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -360,6 +360,7 @@ migrate_type_helper=該倉庫將是一個 <span class="text blue">鏡像</span>
 | 
				
			|||||||
migrate_repo=遷移倉庫
 | 
					migrate_repo=遷移倉庫
 | 
				
			||||||
migrate.clone_address=複製地址
 | 
					migrate.clone_address=複製地址
 | 
				
			||||||
migrate.clone_address_desc=該地址可以是 HTTP/HTTPS/GIT URL 或本地服務器路徑。
 | 
					migrate.clone_address_desc=該地址可以是 HTTP/HTTPS/GIT URL 或本地服務器路徑。
 | 
				
			||||||
 | 
					migrate.permission_denied=You are not allowed to import local repositories.
 | 
				
			||||||
migrate.invalid_local_path=無效的本地路徑,該路徑不存在或不是一個目錄!
 | 
					migrate.invalid_local_path=無效的本地路徑,該路徑不存在或不是一個目錄!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
forked_from=派生自
 | 
					forked_from=派生自
 | 
				
			||||||
@@ -808,6 +809,7 @@ users.edit_account=編輯用戶信息
 | 
				
			|||||||
users.is_activated=該用戶已被激活
 | 
					users.is_activated=該用戶已被激活
 | 
				
			||||||
users.is_admin=該用戶具有管理員權限
 | 
					users.is_admin=該用戶具有管理員權限
 | 
				
			||||||
users.allow_git_hook=該帳戶具有創建 Git 鉤子的權限
 | 
					users.allow_git_hook=該帳戶具有創建 Git 鉤子的權限
 | 
				
			||||||
 | 
					users.allow_import_local=This account has permissions to import local repositories
 | 
				
			||||||
users.update_profile=更新用戶信息
 | 
					users.update_profile=更新用戶信息
 | 
				
			||||||
users.delete_account=刪除該用戶
 | 
					users.delete_account=刪除該用戶
 | 
				
			||||||
users.still_own_repo=該帳戶仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除帳戶操作!
 | 
					users.still_own_repo=該帳戶仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除帳戶操作!
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							@@ -17,7 +17,7 @@ import (
 | 
				
			|||||||
	"github.com/gogits/gogs/modules/setting"
 | 
						"github.com/gogits/gogs/modules/setting"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const APP_VER = "0.6.23.1103 Beta"
 | 
					const APP_VER = "0.6.24.1103 Beta"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
						runtime.GOMAXPROCS(runtime.NumCPU())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@ func IsErrNameReserved(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrNameReserved) Error() string {
 | 
					func (err ErrNameReserved) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("name is reserved: [name: %s]", err.Name)
 | 
						return fmt.Sprintf("name is reserved [name: %s]", err.Name)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrNamePatternNotAllowed struct {
 | 
					type ErrNamePatternNotAllowed struct {
 | 
				
			||||||
@@ -31,7 +31,7 @@ func IsErrNamePatternNotAllowed(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrNamePatternNotAllowed) Error() string {
 | 
					func (err ErrNamePatternNotAllowed) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("name pattern is not allowed: [pattern: %s]", err.Pattern)
 | 
						return fmt.Sprintf("name pattern is not allowed [pattern: %s]", err.Pattern)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//  ____ ___
 | 
					//  ____ ___
 | 
				
			||||||
@@ -51,7 +51,7 @@ func IsErrUserAlreadyExist(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrUserAlreadyExist) Error() string {
 | 
					func (err ErrUserAlreadyExist) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("user already exists: [name: %s]", err.Name)
 | 
						return fmt.Sprintf("user already exists [name: %s]", err.Name)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrUserNotExist struct {
 | 
					type ErrUserNotExist struct {
 | 
				
			||||||
@@ -65,7 +65,7 @@ func IsErrUserNotExist(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrUserNotExist) Error() string {
 | 
					func (err ErrUserNotExist) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("user does not exist: [uid: %d, name: %s]", err.UID, err.Name)
 | 
						return fmt.Sprintf("user does not exist [uid: %d, name: %s]", err.UID, err.Name)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrEmailAlreadyUsed struct {
 | 
					type ErrEmailAlreadyUsed struct {
 | 
				
			||||||
@@ -78,7 +78,7 @@ func IsErrEmailAlreadyUsed(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrEmailAlreadyUsed) Error() string {
 | 
					func (err ErrEmailAlreadyUsed) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("e-mail has been used: [email: %s]", err.Email)
 | 
						return fmt.Sprintf("e-mail has been used [email: %s]", err.Email)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrUserOwnRepos struct {
 | 
					type ErrUserOwnRepos struct {
 | 
				
			||||||
@@ -91,7 +91,7 @@ func IsErrUserOwnRepos(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrUserOwnRepos) Error() string {
 | 
					func (err ErrUserOwnRepos) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("user still has ownership of repositories: [uid: %d]", err.UID)
 | 
						return fmt.Sprintf("user still has ownership of repositories [uid: %d]", err.UID)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrUserHasOrgs struct {
 | 
					type ErrUserHasOrgs struct {
 | 
				
			||||||
@@ -104,7 +104,7 @@ func IsErrUserHasOrgs(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrUserHasOrgs) Error() string {
 | 
					func (err ErrUserHasOrgs) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("user still has membership of organizations: [uid: %d]", err.UID)
 | 
						return fmt.Sprintf("user still has membership of organizations [uid: %d]", err.UID)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// __________     ___.   .__  .__          ____  __.
 | 
					// __________     ___.   .__  .__          ____  __.
 | 
				
			||||||
@@ -124,7 +124,7 @@ func IsErrKeyNotExist(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrKeyNotExist) Error() string {
 | 
					func (err ErrKeyNotExist) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("public key does not exist: [id: %d]", err.ID)
 | 
						return fmt.Sprintf("public key does not exist [id: %d]", err.ID)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrKeyAlreadyExist struct {
 | 
					type ErrKeyAlreadyExist struct {
 | 
				
			||||||
@@ -138,7 +138,7 @@ func IsErrKeyAlreadyExist(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrKeyAlreadyExist) Error() string {
 | 
					func (err ErrKeyAlreadyExist) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("public key already exists: [owner_id: %d, content: %s]", err.OwnerID, err.Content)
 | 
						return fmt.Sprintf("public key already exists [owner_id: %d, content: %s]", err.OwnerID, err.Content)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrKeyNameAlreadyUsed struct {
 | 
					type ErrKeyNameAlreadyUsed struct {
 | 
				
			||||||
@@ -152,7 +152,7 @@ func IsErrKeyNameAlreadyUsed(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrKeyNameAlreadyUsed) Error() string {
 | 
					func (err ErrKeyNameAlreadyUsed) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("public key already exists: [owner_id: %d, name: %s]", err.OwnerID, err.Name)
 | 
						return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrDeployKeyAlreadyExist struct {
 | 
					type ErrDeployKeyAlreadyExist struct {
 | 
				
			||||||
@@ -166,7 +166,7 @@ func IsErrDeployKeyAlreadyExist(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrDeployKeyAlreadyExist) Error() string {
 | 
					func (err ErrDeployKeyAlreadyExist) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("public key already exists: [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
 | 
						return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrDeployKeyNameAlreadyUsed struct {
 | 
					type ErrDeployKeyNameAlreadyUsed struct {
 | 
				
			||||||
@@ -180,7 +180,7 @@ func IsErrDeployKeyNameAlreadyUsed(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrDeployKeyNameAlreadyUsed) Error() string {
 | 
					func (err ErrDeployKeyNameAlreadyUsed) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("public key already exists: [repo_id: %d, name: %s]", err.RepoID, err.Name)
 | 
						return fmt.Sprintf("public key already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//    _____                                   ___________     __
 | 
					//    _____                                   ___________     __
 | 
				
			||||||
@@ -200,7 +200,7 @@ func IsErrAccessTokenNotExist(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrAccessTokenNotExist) Error() string {
 | 
					func (err ErrAccessTokenNotExist) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("access token does not exist: [sha: %s]", err.SHA)
 | 
						return fmt.Sprintf("access token does not exist [sha: %s]", err.SHA)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ________                            .__                __  .__
 | 
					// ________                            .__                __  .__
 | 
				
			||||||
@@ -220,7 +220,7 @@ func IsErrLastOrgOwner(err error) bool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (err ErrLastOrgOwner) Error() string {
 | 
					func (err ErrLastOrgOwner) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("user is the last member of owner team: [uid: %d]", err.UID)
 | 
						return fmt.Sprintf("user is the last member of owner team [uid: %d]", err.UID)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// __________                           .__  __
 | 
					// __________                           .__  __
 | 
				
			||||||
@@ -259,6 +259,22 @@ func (err ErrRepoAlreadyExist) Error() string {
 | 
				
			|||||||
	return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name)
 | 
						return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ErrInvalidCloneAddr struct {
 | 
				
			||||||
 | 
						IsURLError         bool
 | 
				
			||||||
 | 
						IsInvalidPath      bool
 | 
				
			||||||
 | 
						IsPermissionDenied bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func IsErrInvalidCloneAddr(err error) bool {
 | 
				
			||||||
 | 
						_, ok := err.(ErrInvalidCloneAddr)
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err ErrInvalidCloneAddr) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("invalid clone address [is_url_error: %v, is_invalid_path: %v, is_permission_denied: %v]",
 | 
				
			||||||
 | 
							err.IsURLError, err.IsInvalidPath, err.IsPermissionDenied)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//  __      __      ___.   .__                   __
 | 
					//  __      __      ___.   .__                   __
 | 
				
			||||||
// /  \    /  \ ____\_ |__ |  |__   ____   ____ |  | __
 | 
					// /  \    /  \ ____\_ |__ |  |__   ____   ____ |  | __
 | 
				
			||||||
// \   \/\/   // __ \| __ \|  |  \ /  _ \ /  _ \|  |/ /
 | 
					// \   \/\/   // __ \| __ \|  |  \ /  _ \ /  _ \|  |/ /
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,9 +75,10 @@ type User struct {
 | 
				
			|||||||
	LastRepoVisibility bool
 | 
						LastRepoVisibility bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Permissions.
 | 
						// Permissions.
 | 
				
			||||||
	IsActive     bool
 | 
						IsActive         bool
 | 
				
			||||||
	IsAdmin      bool
 | 
						IsAdmin          bool
 | 
				
			||||||
	AllowGitHook bool
 | 
						AllowGitHook     bool
 | 
				
			||||||
 | 
						AllowImportLocal bool // Allow migrate repository by local path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Avatar.
 | 
						// Avatar.
 | 
				
			||||||
	Avatar          string `xorm:"VARCHAR(2048) NOT NULL"`
 | 
						Avatar          string `xorm:"VARCHAR(2048) NOT NULL"`
 | 
				
			||||||
@@ -107,6 +108,16 @@ func (u *User) AfterSet(colName string, _ xorm.Cell) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CanEditGitHook returns true if user can edit Git hooks.
 | 
				
			||||||
 | 
					func (u *User) CanEditGitHook() bool {
 | 
				
			||||||
 | 
						return u.IsAdmin || u.AllowGitHook
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CanImportLocal returns true if user can migrate repository by local path.
 | 
				
			||||||
 | 
					func (u *User) CanImportLocal() bool {
 | 
				
			||||||
 | 
						return u.IsAdmin || u.AllowImportLocal
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EmailAdresses is the list of all email addresses of a user. Can contain the
 | 
					// EmailAdresses is the list of all email addresses of a user. Can contain the
 | 
				
			||||||
// primary email address, but is not obligatory
 | 
					// primary email address, but is not obligatory
 | 
				
			||||||
type EmailAddress struct {
 | 
					type EmailAddress struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,16 +24,17 @@ func (f *AdminCrateUserForm) Validate(ctx *macaron.Context, errs binding.Errors)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AdminEditUserForm struct {
 | 
					type AdminEditUserForm struct {
 | 
				
			||||||
	LoginType    string `binding:"Required"`
 | 
						LoginType        string `binding:"Required"`
 | 
				
			||||||
	LoginName    string
 | 
						LoginName        string
 | 
				
			||||||
	FullName     string `binding:"MaxSize(100)"`
 | 
						FullName         string `binding:"MaxSize(100)"`
 | 
				
			||||||
	Email        string `binding:"Required;Email;MaxSize(254)"`
 | 
						Email            string `binding:"Required;Email;MaxSize(254)"`
 | 
				
			||||||
	Password     string `binding:"MaxSize(255)"`
 | 
						Password         string `binding:"MaxSize(255)"`
 | 
				
			||||||
	Website      string `binding:"MaxSize(50)"`
 | 
						Website          string `binding:"MaxSize(50)"`
 | 
				
			||||||
	Location     string `binding:"MaxSize(50)"`
 | 
						Location         string `binding:"MaxSize(50)"`
 | 
				
			||||||
	Active       bool
 | 
						Active           bool
 | 
				
			||||||
	Admin        bool
 | 
						Admin            bool
 | 
				
			||||||
	AllowGitHook bool
 | 
						AllowGitHook     bool
 | 
				
			||||||
 | 
						AllowImportLocal bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *AdminEditUserForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
 | 
					func (f *AdminEditUserForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,8 +5,14 @@
 | 
				
			|||||||
package auth
 | 
					package auth
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/Unknwon/com"
 | 
				
			||||||
	"github.com/go-macaron/binding"
 | 
						"github.com/go-macaron/binding"
 | 
				
			||||||
	"gopkg.in/macaron.v1"
 | 
						"gopkg.in/macaron.v1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gogits/gogs/models"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// _______________________________________    _________.______________________ _______________.___.
 | 
					// _______________________________________    _________.______________________ _______________.___.
 | 
				
			||||||
@@ -46,6 +52,34 @@ func (f *MigrateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) bi
 | 
				
			|||||||
	return validate(errs, ctx.Data, f, ctx.Locale)
 | 
						return validate(errs, ctx.Data, f, ctx.Locale)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ParseRemoteAddr checks if given remote address is valid,
 | 
				
			||||||
 | 
					// and returns composed URL with needed username and passowrd.
 | 
				
			||||||
 | 
					// It also checks if given user has permission when remote address
 | 
				
			||||||
 | 
					// is actually a local path.
 | 
				
			||||||
 | 
					func (f MigrateRepoForm) ParseRemoteAddr(user *models.User) (string, error) {
 | 
				
			||||||
 | 
						remoteAddr := f.CloneAddr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Remote address can be HTTP/HTTPS/Git URL or local path.
 | 
				
			||||||
 | 
						if strings.HasPrefix(remoteAddr, "http://") ||
 | 
				
			||||||
 | 
							strings.HasPrefix(remoteAddr, "https://") ||
 | 
				
			||||||
 | 
							strings.HasPrefix(remoteAddr, "git://") {
 | 
				
			||||||
 | 
							u, err := url.Parse(remoteAddr)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return "", models.ErrInvalidCloneAddr{IsURLError: true}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(f.AuthUsername)+len(f.AuthPassword) > 0 {
 | 
				
			||||||
 | 
								u.User = url.UserPassword(f.AuthUsername, f.AuthPassword)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							remoteAddr = u.String()
 | 
				
			||||||
 | 
						} else if !user.CanImportLocal() {
 | 
				
			||||||
 | 
							return "", models.ErrInvalidCloneAddr{IsPermissionDenied: true}
 | 
				
			||||||
 | 
						} else if !com.IsDir(remoteAddr) {
 | 
				
			||||||
 | 
							return "", models.ErrInvalidCloneAddr{IsInvalidPath: true}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return remoteAddr, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RepoSettingForm struct {
 | 
					type RepoSettingForm struct {
 | 
				
			||||||
	RepoName    string `binding:"Required;AlphaDashDot;MaxSize(100)"`
 | 
						RepoName    string `binding:"Required;AlphaDashDot;MaxSize(100)"`
 | 
				
			||||||
	Description string `binding:"MaxSize(255)"`
 | 
						Description string `binding:"MaxSize(255)"`
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -420,7 +420,7 @@ func RequireRepoAdmin() macaron.Handler {
 | 
				
			|||||||
// GitHookService checks if repository Git hooks service has been enabled.
 | 
					// GitHookService checks if repository Git hooks service has been enabled.
 | 
				
			||||||
func GitHookService() macaron.Handler {
 | 
					func GitHookService() macaron.Handler {
 | 
				
			||||||
	return func(ctx *Context) {
 | 
						return func(ctx *Context) {
 | 
				
			||||||
		if !ctx.User.AllowGitHook && !ctx.User.IsAdmin {
 | 
							if !ctx.User.CanEditGitHook() {
 | 
				
			||||||
			ctx.Handle(404, "GitHookService", nil)
 | 
								ctx.Handle(404, "GitHookService", nil)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -213,6 +213,7 @@ func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
 | 
				
			|||||||
	u.IsActive = form.Active
 | 
						u.IsActive = form.Active
 | 
				
			||||||
	u.IsAdmin = form.Admin
 | 
						u.IsAdmin = form.Admin
 | 
				
			||||||
	u.AllowGitHook = form.AllowGitHook
 | 
						u.AllowGitHook = form.AllowGitHook
 | 
				
			||||||
 | 
						u.AllowImportLocal = form.AllowImportLocal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := models.UpdateUser(u); err != nil {
 | 
						if err := models.UpdateUser(u); err != nil {
 | 
				
			||||||
		if models.IsErrEmailAlreadyUsed(err) {
 | 
							if models.IsErrEmailAlreadyUsed(err) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,9 +5,7 @@
 | 
				
			|||||||
package v1
 | 
					package v1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/Unknwon/com"
 | 
						"github.com/Unknwon/com"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -218,22 +216,23 @@ func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Remote address can be HTTP/HTTPS/Git URL or local path.
 | 
						remoteAddr, err := form.ParseRemoteAddr(ctx.User)
 | 
				
			||||||
	remoteAddr := form.CloneAddr
 | 
						if err != nil {
 | 
				
			||||||
	if strings.HasPrefix(form.CloneAddr, "http://") ||
 | 
							if models.IsErrInvalidCloneAddr(err) {
 | 
				
			||||||
		strings.HasPrefix(form.CloneAddr, "https://") ||
 | 
								addrErr := err.(models.ErrInvalidCloneAddr)
 | 
				
			||||||
		strings.HasPrefix(form.CloneAddr, "git://") {
 | 
								switch {
 | 
				
			||||||
		u, err := url.Parse(form.CloneAddr)
 | 
								case addrErr.IsURLError:
 | 
				
			||||||
		if err != nil {
 | 
									ctx.APIError(422, "", err)
 | 
				
			||||||
			ctx.APIError(422, "", err)
 | 
								case addrErr.IsPermissionDenied:
 | 
				
			||||||
			return
 | 
									ctx.APIError(422, "", "You are not allowed to import local repositories.")
 | 
				
			||||||
 | 
								case addrErr.IsInvalidPath:
 | 
				
			||||||
 | 
									ctx.APIError(422, "", "Invalid local path, it does not exist or not a directory.")
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									ctx.APIError(500, "ParseRemoteAddr", "Unknown error type (ErrInvalidCloneAddr): "+err.Error())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ctx.APIError(500, "ParseRemoteAddr", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		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.APIError(422, "", "Invalid local path, it does not exist or not a directory.")
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,6 @@ package repo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
@@ -164,26 +163,24 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Remote address can be HTTP/HTTPS/Git URL or local path.
 | 
						remoteAddr, err := form.ParseRemoteAddr(ctx.User)
 | 
				
			||||||
	// Note: remember to change api/v1/repo.go: MigrateRepo
 | 
						if err != nil {
 | 
				
			||||||
	// FIXME: merge these two functions with better error handling
 | 
							if models.IsErrInvalidCloneAddr(err) {
 | 
				
			||||||
	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.Data["Err_CloneAddr"] = true
 | 
								ctx.Data["Err_CloneAddr"] = true
 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("form.url_error"), MIGRATE, &form)
 | 
								addrErr := err.(models.ErrInvalidCloneAddr)
 | 
				
			||||||
			return
 | 
								switch {
 | 
				
			||||||
 | 
								case addrErr.IsURLError:
 | 
				
			||||||
 | 
									ctx.RenderWithErr(ctx.Tr("form.url_error"), MIGRATE, &form)
 | 
				
			||||||
 | 
								case addrErr.IsPermissionDenied:
 | 
				
			||||||
 | 
									ctx.RenderWithErr(ctx.Tr("repo.migrate.permission_denied"), MIGRATE, &form)
 | 
				
			||||||
 | 
								case addrErr.IsInvalidPath:
 | 
				
			||||||
 | 
									ctx.RenderWithErr(ctx.Tr("repo.migrate.invalid_local_path"), MIGRATE, &form)
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									ctx.Handle(500, "Unknown error", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ctx.Handle(500, "ParseRemoteAddr", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		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.Data["Err_CloneAddr"] = true
 | 
					 | 
				
			||||||
		ctx.RenderWithErr(ctx.Tr("repo.migrate.invalid_local_path"), MIGRATE, &form)
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
0.6.23.1103 Beta
 | 
					0.6.24.1103 Beta
 | 
				
			||||||
@@ -72,7 +72,13 @@
 | 
				
			|||||||
            <div class="inline field">
 | 
					            <div class="inline field">
 | 
				
			||||||
              <div class="ui checkbox">
 | 
					              <div class="ui checkbox">
 | 
				
			||||||
                <label><strong>{{.i18n.Tr "admin.users.allow_git_hook"}}</strong></label>
 | 
					                <label><strong>{{.i18n.Tr "admin.users.allow_git_hook"}}</strong></label>
 | 
				
			||||||
                <input name="allow_git_hook" type="checkbox" {{if or .User.IsAdmin .User.AllowGitHook}}checked{{end}}>
 | 
					                <input name="allow_git_hook" type="checkbox" {{if .User.CanEditGitHook}}checked{{end}}>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="inline field">
 | 
				
			||||||
 | 
					              <div class="ui checkbox">
 | 
				
			||||||
 | 
					                <label><strong>{{.i18n.Tr "admin.users.allow_import_local"}}</strong></label>
 | 
				
			||||||
 | 
					                <input name="allow_import_local" type="checkbox" {{if .User.CanImportLocal}}checked{{end}}>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
	  <a class="{{if .PageIsSettingsHooks}}active{{end}} item" href="{{.RepoLink}}/settings/hooks">
 | 
						  <a class="{{if .PageIsSettingsHooks}}active{{end}} item" href="{{.RepoLink}}/settings/hooks">
 | 
				
			||||||
	    {{.i18n.Tr "repo.settings.hooks"}}
 | 
						    {{.i18n.Tr "repo.settings.hooks"}}
 | 
				
			||||||
	  </a>
 | 
						  </a>
 | 
				
			||||||
	  {{if or .SignedUser.AllowGitHook .SignedUser.IsAdmin}}
 | 
						  {{if .SignedUser.CanEditGitHook}}
 | 
				
			||||||
	  <a class="{{if .PageIsSettingsGitHooks}}active{{end}} item" href="{{.RepoLink}}/settings/hooks/git">
 | 
						  <a class="{{if .PageIsSettingsGitHooks}}active{{end}} item" href="{{.RepoLink}}/settings/hooks/git">
 | 
				
			||||||
	    {{.i18n.Tr "repo.settings.githooks"}}
 | 
						    {{.i18n.Tr "repo.settings.githooks"}}
 | 
				
			||||||
	  </a>
 | 
						  </a>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user