|
|
@ -36,8 +36,6 @@ const ( |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
var ( |
|
|
|
ErrUserOwnRepos = errors.New("User still have ownership of repositories") |
|
|
|
|
|
|
|
ErrUserHasOrgs = errors.New("User still have membership of organization") |
|
|
|
|
|
|
|
ErrUserAlreadyExist = errors.New("User already exist") |
|
|
|
ErrUserAlreadyExist = errors.New("User already exist") |
|
|
|
ErrUserNotExist = errors.New("User does not exist") |
|
|
|
ErrUserNotExist = errors.New("User does not exist") |
|
|
|
ErrUserNotKeyOwner = errors.New("User does not the owner of public key") |
|
|
|
ErrUserNotKeyOwner = errors.New("User does not the owner of public key") |
|
|
@ -432,55 +430,75 @@ func UpdateUser(u *User) error { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// DeleteBeans deletes all given beans, beans should contain delete conditions.
|
|
|
|
|
|
|
|
func DeleteBeans(e Engine, beans ...interface{}) (err error) { |
|
|
|
|
|
|
|
for i := range beans { |
|
|
|
|
|
|
|
if _, err = e.Delete(beans[i]); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// FIXME: need some kind of mechanism to record failure. HINT: system notice
|
|
|
|
// FIXME: need some kind of mechanism to record failure. HINT: system notice
|
|
|
|
// DeleteUser completely and permanently deletes everything of user.
|
|
|
|
// 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) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return errors.New("GetRepositoryCount: " + err.Error()) |
|
|
|
return fmt.Errorf("GetRepositoryCount: %v", err) |
|
|
|
} else if count > 0 { |
|
|
|
} else if count > 0 { |
|
|
|
return ErrUserOwnRepos |
|
|
|
return ErrUserOwnRepos{UID: u.Id} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Check membership of organization.
|
|
|
|
// Check membership of organization.
|
|
|
|
count, err = u.GetOrganizationCount() |
|
|
|
count, err = u.GetOrganizationCount() |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return errors.New("GetOrganizationCount: " + err.Error()) |
|
|
|
return fmt.Errorf("GetOrganizationCount: %v", err) |
|
|
|
} else if count > 0 { |
|
|
|
} else if count > 0 { |
|
|
|
return ErrUserHasOrgs |
|
|
|
return ErrUserHasOrgs{UID: u.Id} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// FIXME: check issues, other repos' commits
|
|
|
|
// Get watches before session.
|
|
|
|
// FIXME: roll backable in some point.
|
|
|
|
watches := make([]*Watch, 0, 10) |
|
|
|
|
|
|
|
if err = x.Where("user_id=?", u.Id).Find(&watches); err != nil { |
|
|
|
// Delete all followers.
|
|
|
|
return fmt.Errorf("get all watches: %v", err) |
|
|
|
if _, err = x.Delete(&Follow{FollowId: u.Id}); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
// Delete oauth2.
|
|
|
|
repoIDs := make([]int64, 0, len(watches)) |
|
|
|
if _, err = x.Delete(&Oauth2{Uid: u.Id}); err != nil { |
|
|
|
for i := range watches { |
|
|
|
return err |
|
|
|
repoIDs = append(repoIDs, watches[i].RepoID) |
|
|
|
} |
|
|
|
} |
|
|
|
// Delete all feeds.
|
|
|
|
|
|
|
|
if _, err = x.Delete(&Action{UserId: u.Id}); err != nil { |
|
|
|
// FIXME: check issues, other repos' commits
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
sess := x.NewSession() |
|
|
|
// Delete all watches.
|
|
|
|
defer sessionRelease(sess) |
|
|
|
if _, err = x.Delete(&Watch{UserId: u.Id}); err != nil { |
|
|
|
if err = sess.Begin(); err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
// Delete all accesses.
|
|
|
|
|
|
|
|
if _, err = x.Delete(&Access{UserID: u.Id}); err != nil { |
|
|
|
if err = DeleteBeans(sess, |
|
|
|
|
|
|
|
&Follow{FollowID: u.Id}, |
|
|
|
|
|
|
|
&Oauth2{Uid: u.Id}, |
|
|
|
|
|
|
|
&Action{UserID: u.Id}, |
|
|
|
|
|
|
|
&Access{UserID: u.Id}, |
|
|
|
|
|
|
|
&Collaboration{UserID: u.Id}, |
|
|
|
|
|
|
|
&EmailAddress{Uid: u.Id}, |
|
|
|
|
|
|
|
&Watch{UserID: u.Id}, |
|
|
|
|
|
|
|
); err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
// Delete all alternative email addresses
|
|
|
|
|
|
|
|
if _, err = x.Delete(&EmailAddress{Uid: u.Id}); err != nil { |
|
|
|
// Decrease all watch numbers.
|
|
|
|
return err |
|
|
|
for i := range repoIDs { |
|
|
|
|
|
|
|
if _, err = sess.Exec("UPDATE `repository` SET num_watches=num_watches-1 WHERE id=?", repoIDs[i]); err != nil { |
|
|
|
|
|
|
|
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 = sess.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
for _, key := range keys { |
|
|
|
for _, key := range keys { |
|
|
@ -489,13 +507,16 @@ func DeleteUser(u *User) error { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if _, err = sess.Delete(u); err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Delete user directory.
|
|
|
|
// Delete user directory.
|
|
|
|
if err = os.RemoveAll(UserPath(u.Name)); err != nil { |
|
|
|
if err = os.RemoveAll(UserPath(u.Name)); err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_, err = x.Delete(u) |
|
|
|
return sess.Commit() |
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DeleteInactivateUsers deletes all inactivate users and email addresses.
|
|
|
|
// DeleteInactivateUsers deletes all inactivate users and email addresses.
|
|
|
@ -777,8 +798,8 @@ func SearchUserByName(opt SearchOption) (us []*User, err error) { |
|
|
|
// Follow is connection request for receiving user notification.
|
|
|
|
// Follow is connection request for receiving user notification.
|
|
|
|
type Follow struct { |
|
|
|
type Follow struct { |
|
|
|
Id int64 |
|
|
|
Id int64 |
|
|
|
UserId int64 `xorm:"unique(follow)"` |
|
|
|
UserID int64 `xorm:"unique(follow)"` |
|
|
|
FollowId int64 `xorm:"unique(follow)"` |
|
|
|
FollowID int64 `xorm:"unique(follow)"` |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// FollowUser marks someone be another's follower.
|
|
|
|
// FollowUser marks someone be another's follower.
|
|
|
@ -787,7 +808,7 @@ func FollowUser(userId int64, followId int64) (err error) { |
|
|
|
defer sess.Close() |
|
|
|
defer sess.Close() |
|
|
|
sess.Begin() |
|
|
|
sess.Begin() |
|
|
|
|
|
|
|
|
|
|
|
if _, err = sess.Insert(&Follow{UserId: userId, FollowId: followId}); err != nil { |
|
|
|
if _, err = sess.Insert(&Follow{UserID: userId, FollowID: followId}); err != nil { |
|
|
|
sess.Rollback() |
|
|
|
sess.Rollback() |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
@ -812,7 +833,7 @@ func UnFollowUser(userId int64, unFollowId int64) (err error) { |
|
|
|
defer session.Close() |
|
|
|
defer session.Close() |
|
|
|
session.Begin() |
|
|
|
session.Begin() |
|
|
|
|
|
|
|
|
|
|
|
if _, err = session.Delete(&Follow{UserId: userId, FollowId: unFollowId}); err != nil { |
|
|
|
if _, err = session.Delete(&Follow{UserID: userId, FollowID: unFollowId}); err != nil { |
|
|
|
session.Rollback() |
|
|
|
session.Rollback() |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|