Finish delete organization
This commit is contained in:
parent
ee9b7f322f
commit
6e448b0714
11 changed files with 116 additions and 27 deletions
|
@ -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,13 +122,23 @@ 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)
|
|
||||||
|
|
||||||
ctx.Redirect("/")
|
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("/")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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}}
|
||||||
|
|
Loading…
Reference in a new issue