Finish delete organization

This commit is contained in:
Unknown 2014-06-28 00:40:07 -04:00
parent ee9b7f322f
commit 6e448b0714
11 changed files with 116 additions and 27 deletions

View File

@ -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) {

View File

@ -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())

View File

@ -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
}
// ___________ ____ ___ // ___________ ____ ___
// \__ ___/___ _____ _____ | | \______ ___________ // \__ ___/___ _____ _____ | | \______ ___________
// | |_/ __ \\__ \ / \| | / ___// __ \_ __ \ // | |_/ __ \\__ \ / \| | / ___// __ \_ __ \

View File

@ -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

View File

@ -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 {

View File

@ -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)

View File

@ -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")
}

View File

@ -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, "/")

View File

@ -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 {

View File

@ -1 +1 @@
0.4.5.0627 Alpha 0.4.5.0628 Alpha

View File

@ -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}}