@ -38,7 +38,6 @@ import (
"golang.org/x/crypto/scrypt"
"golang.org/x/crypto/scrypt"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh"
"xorm.io/builder"
"xorm.io/builder"
"xorm.io/xorm"
)
)
// UserType defines the user type
// UserType defines the user type
@ -1071,8 +1070,7 @@ func deleteBeans(e Engine, beans ...interface{}) (err error) {
return nil
return nil
}
}
// FIXME: need some kind of mechanism to record failure. HINT: system notice
func deleteUser ( e Engine , u * User ) error {
func deleteUser ( e * xorm . Session , u * User ) error {
// Note: A user owns any repository or belongs to any organization
// Note: A user owns any repository or belongs to any organization
// cannot perform delete operation.
// cannot perform delete operation.
@ -1151,12 +1149,30 @@ func deleteUser(e *xorm.Session, u *User) error {
return fmt . Errorf ( "deleteBeans: %v" , err )
return fmt . Errorf ( "deleteBeans: %v" , err )
}
}
if setting . Service . UserDeleteWithCommentsMaxDays != 0 &&
if setting . Service . UserDeleteWithCommentsMaxTime != 0 &&
u . CreatedUnix . AsTime ( ) . Add ( time . Duration ( setting . Service . UserDeleteWithCommentsMaxDays ) * 24 * time . Hour ) . After ( time . Now ( ) ) {
u . CreatedUnix . AsTime ( ) . Add ( setting . Service . UserDeleteWithCommentsMaxTime ) . After ( time . Now ( ) ) {
if err = deleteBeans ( e ,
& Comment { PosterID : u . ID } ,
// Delete Comments
) ; err != nil {
const batchSize = 50
return fmt . Errorf ( "deleteBeans: %v" , err )
for start := 0 ; ; start += batchSize {
comments := make ( [ ] * Comment , 0 , batchSize )
if err = e . Where ( "type=? AND poster_id=?" , CommentTypeComment , u . ID ) . Limit ( batchSize , start ) . Find ( & comments ) ; err != nil {
return err
}
if len ( comments ) == 0 {
break
}
for _ , comment := range comments {
if err = deleteComment ( e , comment ) ; err != nil {
return err
}
}
}
// Delete Reactions
if err = deleteReaction ( e , & ReactionOptions { Doer : u } ) ; err != nil {
return err
}
}
}
}
@ -1195,18 +1211,21 @@ func deleteUser(e *xorm.Session, u *User) error {
return fmt . Errorf ( "Delete: %v" , err )
return fmt . Errorf ( "Delete: %v" , err )
}
}
// FIXME: system notice
// Note: There are something just cannot be roll back,
// Note: There are something just cannot be roll back,
// so just keep error logs of those operations.
// so just keep error logs of those operations.
path := UserPath ( u . Name )
path := UserPath ( u . Name )
if err := util . RemoveAll ( path ) ; err != nil {
if err = util . RemoveAll ( path ) ; err != nil {
return fmt . Errorf ( "Failed to RemoveAll %s: %v" , path , err )
err = fmt . Errorf ( "Failed to RemoveAll %s: %v" , path , err )
_ = createNotice ( e , NoticeTask , fmt . Sprintf ( "delete user '%s': %v" , u . Name , err ) )
return err
}
}
if len ( u . Avatar ) > 0 {
if len ( u . Avatar ) > 0 {
avatarPath := u . CustomAvatarRelativePath ( )
avatarPath := u . CustomAvatarRelativePath ( )
if err := storage . Avatars . Delete ( avatarPath ) ; err != nil {
if err = storage . Avatars . Delete ( avatarPath ) ; err != nil {
return fmt . Errorf ( "Failed to remove %s: %v" , avatarPath , err )
err = fmt . Errorf ( "Failed to remove %s: %v" , avatarPath , err )
_ = createNotice ( e , NoticeTask , fmt . Sprintf ( "delete user '%s': %v" , u . Name , err ) )
return err
}
}
}
}