mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Finish delete organization
This commit is contained in:
		| @@ -194,13 +194,14 @@ func runWeb(*cli.Context) { | |||||||
| 		r.Get("/:org", org.Organization) | 		r.Get("/:org", org.Organization) | ||||||
| 		r.Get("/:org/dashboard", org.Dashboard) | 		r.Get("/:org/dashboard", org.Dashboard) | ||||||
| 		r.Get("/:org/members", org.Members) | 		r.Get("/:org/members", org.Members) | ||||||
| 		// organization teams |  | ||||||
| 		r.Get("/:org/teams/:team/edit", org.EditTeam) | 		r.Get("/:org/teams/:team/edit", org.EditTeam) | ||||||
| 		r.Get("/:org/teams/new", org.NewTeam) | 		r.Get("/:org/teams/new", org.NewTeam) | ||||||
| 		r.Get("/:org/teams", org.Teams) | 		r.Get("/:org/teams", org.Teams) | ||||||
|  |  | ||||||
| 		r.Get("/:org/settings", org.Settings) | 		r.Get("/:org/settings", org.Settings) | ||||||
| 		r.Post("/:org/settings", bindIgnErr(auth.OrgSettingForm{}), org.SettingsPost) | 		r.Post("/:org/settings", bindIgnErr(auth.OrgSettingForm{}), org.SettingsPost) | ||||||
|  | 		r.Post("/:org/settings/delete", org.DeletePost) | ||||||
| 	}, reqSignIn) | 	}, reqSignIn) | ||||||
|  |  | ||||||
| 	m.Group("/:username/:reponame", func(r martini.Router) { | 	m.Group("/:username/:reponame", func(r martini.Router) { | ||||||
|   | |||||||
							
								
								
									
										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.4.5.0627 Alpha" | const APP_VER = "0.4.5.0628 Alpha" | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||||
|   | |||||||
| @@ -10,6 +10,16 @@ import ( | |||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // GetOwnerTeam returns owner team of organization. | ||||||
|  | func (org *User) GetOwnerTeam() (*Team, error) { | ||||||
|  | 	t := &Team{ | ||||||
|  | 		OrgId: org.Id, | ||||||
|  | 		Name:  OWNER_TEAM, | ||||||
|  | 	} | ||||||
|  | 	_, err := x.Get(t) | ||||||
|  | 	return t, err | ||||||
|  | } | ||||||
|  |  | ||||||
| // CreateOrganization creates record of a new organization. | // CreateOrganization creates record of a new organization. | ||||||
| func CreateOrganization(org, owner *User) (*User, error) { | func CreateOrganization(org, owner *User) (*User, error) { | ||||||
| 	if !IsLegalName(org.Name) { | 	if !IsLegalName(org.Name) { | ||||||
| @@ -86,6 +96,34 @@ func CreateOrganization(org, owner *User) (*User, error) { | |||||||
| 	return org, sess.Commit() | 	return org, sess.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // TODO: need some kind of mechanism to record failure. | ||||||
|  | // DeleteOrganization completely and permanently deletes everything of organization. | ||||||
|  | func DeleteOrganization(org *User) (err error) { | ||||||
|  | 	if err := DeleteUser(org); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sess := x.NewSession() | ||||||
|  | 	defer sess.Close() | ||||||
|  | 	if err = sess.Begin(); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if _, err = sess.Delete(&Team{OrgId: org.Id}); err != nil { | ||||||
|  | 		sess.Rollback() | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if _, err = sess.Delete(&OrgUser{OrgId: org.Id}); err != nil { | ||||||
|  | 		sess.Rollback() | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if _, err = sess.Delete(&TeamUser{OrgId: org.Id}); err != nil { | ||||||
|  | 		sess.Rollback() | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return sess.Commit() | ||||||
|  | } | ||||||
|  |  | ||||||
| type AuthorizeType int | type AuthorizeType int | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -158,6 +196,12 @@ func GetOrganizationCount(u *User) (int64, error) { | |||||||
| 	return x.Where("uid=?", u.Id).Count(new(OrgUser)) | 	return x.Where("uid=?", u.Id).Count(new(OrgUser)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // IsOrganizationOwner returns true if given user ID is in the owner team. | ||||||
|  | func IsOrganizationOwner(orgId, uid int64) bool { | ||||||
|  | 	has, _ := x.Where("is_owner=?", true).Get(&OrgUser{Uid: uid, OrgId: orgId}) | ||||||
|  | 	return has | ||||||
|  | } | ||||||
|  |  | ||||||
| // ___________                    ____ ___ | // ___________                    ____ ___ | ||||||
| // \__    ___/___ _____    _____ |    |   \______ ___________ | // \__    ___/___ _____    _____ |    |   \______ ___________ | ||||||
| //   |    |_/ __ \\__  \  /     \|    |   /  ___// __ \_  __ \ | //   |    |_/ __ \\__  \  /     \|    |   /  ___// __ \_  __ \ | ||||||
|   | |||||||
| @@ -733,7 +733,7 @@ func UpdateRepository(repo *Repository) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| // DeleteRepository deletes a repository for a user or orgnaztion. | // DeleteRepository deletes a repository for a user or orgnaztion. | ||||||
| func DeleteRepository(userId, repoId int64, userName string) (err error) { | func DeleteRepository(userId, repoId int64, userName string) error { | ||||||
| 	repo := &Repository{Id: repoId, OwnerId: userId} | 	repo := &Repository{Id: repoId, OwnerId: userId} | ||||||
| 	has, err := x.Get(repo) | 	has, err := x.Get(repo) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -747,6 +747,7 @@ func DeleteRepository(userId, repoId int64, userName string) (err error) { | |||||||
| 	if err = sess.Begin(); err != nil { | 	if err = sess.Begin(); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if _, err = sess.Delete(&Repository{Id: repoId}); err != nil { | 	if _, err = sess.Delete(&Repository{Id: repoId}); err != nil { | ||||||
| 		sess.Rollback() | 		sess.Rollback() | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
| @@ -105,10 +105,12 @@ func (u *User) EncodePasswd() { | |||||||
| 	u.Passwd = fmt.Sprintf("%x", newPasswd) | 	u.Passwd = fmt.Sprintf("%x", newPasswd) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // IsOrganization returns true if user is actually a organization. | ||||||
| func (u *User) IsOrganization() bool { | func (u *User) IsOrganization() bool { | ||||||
| 	return u.Type == ORGANIZATION | 	return u.Type == ORGANIZATION | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // GetOrganizations returns all organizations that user belongs to. | ||||||
| func (u *User) GetOrganizations() error { | func (u *User) GetOrganizations() error { | ||||||
| 	ous, err := GetOrgUsersByUserId(u.Id) | 	ous, err := GetOrgUsersByUserId(u.Id) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -125,16 +127,6 @@ func (u *User) GetOrganizations() error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetOwnerTeam returns owner team of organization. |  | ||||||
| func (org *User) GetOwnerTeam() (*Team, error) { |  | ||||||
| 	t := &Team{ |  | ||||||
| 		OrgId: org.Id, |  | ||||||
| 		Name:  OWNER_TEAM, |  | ||||||
| 	} |  | ||||||
| 	_, err := x.Get(t) |  | ||||||
| 	return t, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsUserExist checks if given user name exist, | // IsUserExist checks if given user name exist, | ||||||
| // the user name should be noncased unique. | // the user name should be noncased unique. | ||||||
| func IsUserExist(name string) (bool, error) { | func IsUserExist(name string) (bool, error) { | ||||||
| @@ -327,7 +319,8 @@ func UpdateUser(u *User) (err error) { | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| // DeleteUser completely deletes everything of the user. | // TODO: need some kind of mechanism to record failure. | ||||||
|  | // DeleteUser completely and permanently deletes everything of user. | ||||||
| func DeleteUser(u *User) error { | func DeleteUser(u *User) error { | ||||||
| 	// Check ownership of repository. | 	// Check ownership of repository. | ||||||
| 	count, err := GetRepositoryCount(u) | 	count, err := GetRepositoryCount(u) | ||||||
| @@ -346,32 +339,28 @@ func DeleteUser(u *User) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// TODO: check issues, other repos' commits | 	// TODO: check issues, other repos' commits | ||||||
|  | 	// TODO: roll backable in some point. | ||||||
|  |  | ||||||
| 	// Delete all followers. | 	// Delete all followers. | ||||||
| 	if _, err = x.Delete(&Follow{FollowId: u.Id}); err != nil { | 	if _, err = x.Delete(&Follow{FollowId: u.Id}); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Delete oauth2. | 	// Delete oauth2. | ||||||
| 	if _, err = x.Delete(&Oauth2{Uid: u.Id}); err != nil { | 	if _, err = x.Delete(&Oauth2{Uid: u.Id}); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Delete all feeds. | 	// Delete all feeds. | ||||||
| 	if _, err = x.Delete(&Action{UserId: u.Id}); err != nil { | 	if _, err = x.Delete(&Action{UserId: u.Id}); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Delete all watches. | 	// Delete all watches. | ||||||
| 	if _, err = x.Delete(&Watch{UserId: u.Id}); err != nil { | 	if _, err = x.Delete(&Watch{UserId: u.Id}); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Delete all accesses. | 	// Delete all accesses. | ||||||
| 	if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil { | 	if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Delete all SSH keys. | 	// Delete all SSH keys. | ||||||
| 	keys := make([]*PublicKey, 0, 10) | 	keys := make([]*PublicKey, 0, 10) | ||||||
| 	if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil { | 	if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil { | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { | |||||||
| 		repoName := params["reponame"] | 		repoName := params["reponame"] | ||||||
| 		refName := params["branchname"] | 		refName := params["branchname"] | ||||||
|  |  | ||||||
|  | 		// TODO: need more advanced onwership and access level check. | ||||||
| 		// Collaborators who have write access can be seen as owners. | 		// Collaborators who have write access can be seen as owners. | ||||||
| 		if ctx.IsSigned { | 		if ctx.IsSigned { | ||||||
| 			ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE) | 			ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE) | ||||||
|   | |||||||
| @@ -30,7 +30,6 @@ func Members(ctx *middleware.Context, params martini.Params) { | |||||||
| 	ctx.HTML(200, "org/members") | 	ctx.HTML(200, "org/members") | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| func New(ctx *middleware.Context) { | func New(ctx *middleware.Context) { | ||||||
| 	ctx.Data["Title"] = "Create An Organization" | 	ctx.Data["Title"] = "Create An Organization" | ||||||
| 	ctx.HTML(200, NEW) | 	ctx.HTML(200, NEW) | ||||||
| @@ -160,3 +159,47 @@ func SettingsPost(ctx *middleware.Context, params martini.Params, form auth.OrgS | |||||||
| 	ctx.Flash.Success("Organization profile has been successfully updated.") | 	ctx.Flash.Success("Organization profile has been successfully updated.") | ||||||
| 	ctx.Redirect("/org/" + org.Name + "/settings") | 	ctx.Redirect("/org/" + org.Name + "/settings") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func DeletePost(ctx *middleware.Context, params martini.Params) { | ||||||
|  | 	ctx.Data["Title"] = "Settings" | ||||||
|  |  | ||||||
|  | 	org, err := models.GetUserByName(params["org"]) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if err == models.ErrUserNotExist { | ||||||
|  | 			ctx.Handle(404, "org.DeletePost(GetUserByName)", err) | ||||||
|  | 		} else { | ||||||
|  | 			ctx.Handle(500, "org.DeletePost(GetUserByName)", err) | ||||||
|  | 		} | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	ctx.Data["Org"] = org | ||||||
|  |  | ||||||
|  | 	if !models.IsOrganizationOwner(org.Id, ctx.User.Id) { | ||||||
|  | 		ctx.Error(403) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tmpUser := models.User{ | ||||||
|  | 		Passwd: ctx.Query("password"), | ||||||
|  | 		Salt:   ctx.User.Salt, | ||||||
|  | 	} | ||||||
|  | 	tmpUser.EncodePasswd() | ||||||
|  | 	if tmpUser.Passwd != ctx.User.Passwd { | ||||||
|  | 		ctx.Flash.Error("Password is not correct. Make sure you are owner of this account.") | ||||||
|  | 	} else { | ||||||
|  | 		if err := models.DeleteOrganization(org); err != nil { | ||||||
|  | 			switch err { | ||||||
|  | 			case models.ErrUserOwnRepos: | ||||||
|  | 				ctx.Flash.Error("This organization still have ownership of repository, you have to delete or transfer them first.") | ||||||
|  | 			default: | ||||||
|  | 				ctx.Handle(500, "org.DeletePost(DeleteOrganization)", err) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			ctx.Redirect("/") | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ctx.Redirect("/org/" + org.Name + "/settings") | ||||||
|  | } | ||||||
|   | |||||||
| @@ -122,15 +122,25 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if err := models.DeleteRepository(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.LowerName); err != nil { | 		if ctx.Repo.Owner.IsOrganization() && | ||||||
| 			ctx.Handle(500, "setting.Delete", err) | 			!models.IsOrganizationOwner(ctx.Repo.Owner.Id, ctx.User.Id) { | ||||||
|  | 			ctx.Error(403) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName) |  | ||||||
|  |  | ||||||
|  | 		if err := models.DeleteRepository(ctx.Repo.Owner.Id, ctx.Repo.Repository.Id, ctx.Repo.Owner.Name); err != nil { | ||||||
|  | 			ctx.Handle(500, "setting.Delete(DeleteRepository)", err) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.Repo.Owner.LowerName, ctx.Repo.Repository.LowerName) | ||||||
|  |  | ||||||
|  | 		if ctx.Repo.Owner.IsOrganization() { | ||||||
|  | 			ctx.Redirect("/org/" + ctx.Repo.Owner.Name + "/dashboard") | ||||||
|  | 		} else { | ||||||
| 			ctx.Redirect("/") | 			ctx.Redirect("/") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func Collaboration(ctx *middleware.Context) { | func Collaboration(ctx *middleware.Context) { | ||||||
| 	repoLink := strings.TrimPrefix(ctx.Repo.RepoLink, "/") | 	repoLink := strings.TrimPrefix(ctx.Repo.RepoLink, "/") | ||||||
|   | |||||||
| @@ -296,7 +296,7 @@ func DeletePost(ctx *middleware.Context) { | |||||||
| 			case models.ErrUserOwnRepos: | 			case models.ErrUserOwnRepos: | ||||||
| 				ctx.Flash.Error("Your account still have ownership of repository, you have to delete or transfer them first.") | 				ctx.Flash.Error("Your account still have ownership of repository, you have to delete or transfer them first.") | ||||||
| 			default: | 			default: | ||||||
| 				ctx.Handle(500, "user.Delete(DeleteUser)", err) | 				ctx.Handle(500, "user.DeletePost(DeleteUser)", err) | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| 0.4.5.0627 Alpha | 0.4.5.0628 Alpha | ||||||
| @@ -76,7 +76,7 @@ | |||||||
|              |              | ||||||
|             <div class="panel-body"> |             <div class="panel-body"> | ||||||
|                 <ul class="list-group">{{range .MyRepos}} |                 <ul class="list-group">{{range .MyRepos}} | ||||||
|                     <li class="list-group-item"><a href="/{{$.SignedUserName}}/{{.Name}}"> |                     <li class="list-group-item"><a href="/{{$.ContextUser.Name}}/{{.Name}}"> | ||||||
|                         <!-- <span class="stars pull-right"><i class="fa fa-star"></i>{{.NumStars}}</span> --> |                         <!-- <span class="stars pull-right"><i class="fa fa-star"></i>{{.NumStars}}</span> --> | ||||||
|                         <i class="fa fa-book"></i>{{.Name}}{{if .IsPrivate}} <span class="label label-default">Private</span>{{end}}</a> |                         <i class="fa fa-book"></i>{{.Name}}{{if .IsPrivate}} <span class="label label-default">Private</span>{{end}}</a> | ||||||
|                     </li>{{end}} |                     </li>{{end}} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Unknown
					Unknown