summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author=Corey Hulen <corey@hulen.com>2015-11-16 17:12:49 -0800
committer=Corey Hulen <corey@hulen.com>2015-11-16 17:12:49 -0800
commit6b2eabf6108e078bed8143e91c605dec5ccfafa6 (patch)
tree0d60cd7f3dac8092bd0bd4e39e2890a6170055c3
parent03c6dcbd865e2af2db5db150189504bfa493ae2e (diff)
downloadchat-6b2eabf6108e078bed8143e91c605dec5ccfafa6.tar.gz
chat-6b2eabf6108e078bed8143e91c605dec5ccfafa6.tar.bz2
chat-6b2eabf6108e078bed8143e91c605dec5ccfafa6.zip
Adding perm delete to cmd line
-rw-r--r--api/team.go26
-rw-r--r--api/team_test.go37
-rw-r--r--api/user.go63
-rw-r--r--api/user_test.go37
-rw-r--r--mattermost.go120
-rw-r--r--store/sql_audit_store.go2
-rw-r--r--store/sql_audit_store_test.go2
-rw-r--r--store/sql_channel_store.go2
-rw-r--r--store/sql_channel_store_test.go2
-rw-r--r--store/sql_oauth_store.go2
-rw-r--r--store/sql_oauth_store_test.go4
-rw-r--r--store/sql_post_store.go79
-rw-r--r--store/sql_post_store_test.go70
-rw-r--r--store/sql_preference_store.go2
-rw-r--r--store/sql_preference_store_test.go2
-rw-r--r--store/sql_session_store.go2
-rw-r--r--store/sql_session_store_test.go2
-rw-r--r--store/sql_team_store.go2
-rw-r--r--store/sql_team_store_test.go2
-rw-r--r--store/sql_user_store.go2
-rw-r--r--store/sql_user_store_test.go2
-rw-r--r--store/sql_webhook_store.go4
-rw-r--r--store/sql_webhook_store_test.go4
-rw-r--r--store/store.go19
-rw-r--r--utils/config.go7
25 files changed, 461 insertions, 35 deletions
diff --git a/api/team.go b/api/team.go
index 862970887..eb8b0772d 100644
--- a/api/team.go
+++ b/api/team.go
@@ -582,6 +582,32 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte(oldTeam.ToJson()))
}
+func PermanentDeleteTeam(c *Context, team *model.Team) *model.AppError {
+ l4g.Warn("Attempting to permanently delete team %v id=%v", team.Name, team.Id)
+
+ team.DeleteAt = model.GetMillis()
+ if result := <-Srv.Store.Team().Update(team); result.Err != nil {
+ return result.Err
+ }
+
+ if result := <-Srv.Store.User().GetForExport(team.Id); result.Err != nil {
+ return result.Err
+ } else {
+ users := result.Data.([]*model.User)
+ for _, user := range users {
+ PermanentDeleteUser(c, user)
+ }
+ }
+
+ if result := <-Srv.Store.Team().PermanentDelete(team.Id); result.Err != nil {
+ return result.Err
+ }
+
+ l4g.Warn("Permanently deleted team %v id=%v", team.Name, team.Id)
+
+ return nil
+}
+
func getMyTeam(c *Context, w http.ResponseWriter, r *http.Request) {
if len(c.Session.TeamId) == 0 {
diff --git a/api/team_test.go b/api/team_test.go
index 7a3b092ce..8e9b8852e 100644
--- a/api/team_test.go
+++ b/api/team_test.go
@@ -168,6 +168,43 @@ func TestGetAllTeams(t *testing.T) {
}
}
+func TestTeamPermDelete(t *testing.T) {
+ Setup()
+
+ team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
+ team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
+
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
+ user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
+ store.Must(Srv.Store.User().VerifyEmail(user1.Id))
+
+ Client.LoginByEmail(team.Name, user1.Email, "pwd")
+
+ channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
+ channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
+
+ post1 := &model.Post{ChannelId: channel1.Id, Message: "search for post1"}
+ post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
+
+ post2 := &model.Post{ChannelId: channel1.Id, Message: "search for post2"}
+ post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
+
+ post3 := &model.Post{ChannelId: channel1.Id, Message: "#hashtag search for post3"}
+ post3 = Client.Must(Client.CreatePost(post3)).Data.(*model.Post)
+
+ post4 := &model.Post{ChannelId: channel1.Id, Message: "hashtag for post4"}
+ post4 = Client.Must(Client.CreatePost(post4)).Data.(*model.Post)
+
+ c := &Context{}
+ c.RequestId = model.NewId()
+ c.IpAddress = "test"
+
+ err := PermanentDeleteTeam(c, team)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
/*
XXXXXX investigate and fix failing test
diff --git a/api/user.go b/api/user.go
index 0f868a678..c9aa897ed 100644
--- a/api/user.go
+++ b/api/user.go
@@ -1196,6 +1196,14 @@ func updateActive(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
+ ruser := UpdateActive(c, user, active)
+
+ if c.Err == nil {
+ w.Write([]byte(ruser.ToJson()))
+ }
+}
+
+func UpdateActive(c *Context, user *model.User, active bool) *model.User {
if active {
user.DeleteAt = 0
} else {
@@ -1204,7 +1212,7 @@ func updateActive(c *Context, w http.ResponseWriter, r *http.Request) {
if result := <-Srv.Store.User().Update(user, true); result.Err != nil {
c.Err = result.Err
- return
+ return nil
} else {
c.LogAuditWithUserId(user.Id, fmt.Sprintf("active=%v", active))
@@ -1216,8 +1224,59 @@ func updateActive(c *Context, w http.ResponseWriter, r *http.Request) {
options := utils.SanitizeOptions
options["passwordupdate"] = false
ruser.Sanitize(options)
- w.Write([]byte(ruser.ToJson()))
+ return ruser
+ }
+}
+
+func PermanentDeleteUser(c *Context, user *model.User) *model.AppError {
+ l4g.Warn("Attempting to permanently delete account %v id=%v", user.Email, user.Id)
+ c.Path = "/user/permanent_delete"
+ c.LogAuditWithUserId(user.Id, fmt.Sprintf("attempt"))
+ if user.IsInRole(model.ROLE_SYSTEM_ADMIN) {
+ l4g.Warn("You are deleting %v that is a system administrator. You may need to set another account as the system administrator using the command line tools.", user.Email)
+ }
+
+ UpdateActive(c, user, false)
+
+ if result := <-Srv.Store.Session().PermanentDeleteSessionsByUser(user.Id); result.Err != nil {
+ return result.Err
+ }
+
+ if result := <-Srv.Store.OAuth().PermanentDeleteAuthDataByUser(user.Id); result.Err != nil {
+ return result.Err
}
+
+ if result := <-Srv.Store.Webhook().PermanentDeleteIncomingByUser(user.Id); result.Err != nil {
+ return result.Err
+ }
+
+ if result := <-Srv.Store.Webhook().PermanentDeleteOutgoingByUser(user.Id); result.Err != nil {
+ return result.Err
+ }
+
+ if result := <-Srv.Store.Preference().PermanentDeleteByUser(user.Id); result.Err != nil {
+ return result.Err
+ }
+
+ if result := <-Srv.Store.Channel().PermanentDeleteMembersByUser(user.Id); result.Err != nil {
+ return result.Err
+ }
+
+ if result := <-Srv.Store.Post().PermanentDeleteByUser(user.Id); result.Err != nil {
+ return result.Err
+ }
+
+ if result := <-Srv.Store.User().PermanentDelete(user.Id); result.Err != nil {
+ return result.Err
+ }
+
+ if result := <-Srv.Store.Audit().PermanentDeleteByUser(user.Id); result.Err != nil {
+ return result.Err
+ }
+
+ l4g.Warn("Permanently deleted account %v id=%v", user.Email, user.Id)
+
+ return nil
}
func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
diff --git a/api/user_test.go b/api/user_test.go
index f067182cb..b6d549a9c 100644
--- a/api/user_test.go
+++ b/api/user_test.go
@@ -767,6 +767,43 @@ func TestUserUpdateActive(t *testing.T) {
}
}
+func TestUserPermDelete(t *testing.T) {
+ Setup()
+
+ team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
+ team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
+
+ user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "corey@test.com", Nickname: "Corey Hulen", Password: "pwd"}
+ user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
+ store.Must(Srv.Store.User().VerifyEmail(user1.Id))
+
+ Client.LoginByEmail(team.Name, user1.Email, "pwd")
+
+ channel1 := &model.Channel{DisplayName: "TestGetPosts", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
+ channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
+
+ post1 := &model.Post{ChannelId: channel1.Id, Message: "search for post1"}
+ post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
+
+ post2 := &model.Post{ChannelId: channel1.Id, Message: "search for post2"}
+ post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post)
+
+ post3 := &model.Post{ChannelId: channel1.Id, Message: "#hashtag search for post3"}
+ post3 = Client.Must(Client.CreatePost(post3)).Data.(*model.Post)
+
+ post4 := &model.Post{ChannelId: channel1.Id, Message: "hashtag for post4"}
+ post4 = Client.Must(Client.CreatePost(post4)).Data.(*model.Post)
+
+ c := &Context{}
+ c.RequestId = model.NewId()
+ c.IpAddress = "test"
+
+ err := PermanentDeleteUser(c, user1)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
func TestSendPasswordReset(t *testing.T) {
Setup()
diff --git a/mattermost.go b/mattermost.go
index e1ae58904..37b4c4c06 100644
--- a/mattermost.go
+++ b/mattermost.go
@@ -30,6 +30,8 @@ var flagCmdCreateUser bool
var flagCmdAssignRole bool
var flagCmdVersion bool
var flagCmdResetPassword bool
+var flagCmdResetPermanentDeleteUser bool
+var flagCmdResetPermanentDeleteTeam bool
var flagConfigFile string
var flagEmail string
var flagPassword string
@@ -191,10 +193,12 @@ func parseCmds() {
flag.BoolVar(&flagCmdAssignRole, "assign_role", false, "")
flag.BoolVar(&flagCmdVersion, "version", false, "")
flag.BoolVar(&flagCmdResetPassword, "reset_password", false, "")
+ flag.BoolVar(&flagCmdResetPermanentDeleteUser, "permanent_delete_user", false, "")
+ flag.BoolVar(&flagCmdResetPermanentDeleteTeam, "permanent_delete_team", false, "")
flag.Parse()
- flagRunCmds = flagCmdCreateTeam || flagCmdCreateUser || flagCmdAssignRole || flagCmdResetPassword || flagCmdVersion
+ flagRunCmds = flagCmdCreateTeam || flagCmdCreateUser || flagCmdAssignRole || flagCmdResetPassword || flagCmdVersion || flagCmdResetPermanentDeleteUser || flagCmdResetPermanentDeleteTeam
}
func runCmds() {
@@ -203,6 +207,8 @@ func runCmds() {
cmdCreateUser()
cmdAssignRole()
cmdResetPassword()
+ cmdPermDeleteUser()
+ cmdPermDeleteTeam()
}
func cmdCreateTeam() {
@@ -406,6 +412,106 @@ func cmdResetPassword() {
}
}
+func cmdPermDeleteUser() {
+ if flagCmdResetPermanentDeleteUser {
+ if len(flagTeamName) == 0 {
+ fmt.Fprintln(os.Stderr, "flag needs an argument: -team_name")
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ if len(flagEmail) == 0 {
+ fmt.Fprintln(os.Stderr, "flag needs an argument: -email")
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ c := &api.Context{}
+ c.RequestId = model.NewId()
+ c.IpAddress = "cmd_line"
+
+ var team *model.Team
+ if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
+ l4g.Error("%v", result.Err)
+ flushLogAndExit(1)
+ } else {
+ team = result.Data.(*model.Team)
+ }
+
+ var user *model.User
+ if result := <-api.Srv.Store.User().GetByEmail(team.Id, flagEmail); result.Err != nil {
+ l4g.Error("%v", result.Err)
+ flushLogAndExit(1)
+ } else {
+ user = result.Data.(*model.User)
+ }
+
+ var confirmBackup string
+ fmt.Print("Have you performed a database backup? (YES/NO): ")
+ fmt.Scanln(&confirmBackup)
+ if confirmBackup != "YES" {
+ flushLogAndExit(1)
+ }
+
+ var confirm string
+ fmt.Printf("Are you sure you want to delete the user %v? All data will be permanently deleted? (YES/NO): ", user.Email)
+ fmt.Scanln(&confirm)
+ if confirm != "YES" {
+ flushLogAndExit(1)
+ }
+
+ if err := api.PermanentDeleteUser(c, user); err != nil {
+ l4g.Error("%v", err)
+ flushLogAndExit(1)
+ } else {
+ flushLogAndExit(0)
+ }
+ }
+}
+
+func cmdPermDeleteTeam() {
+ if flagCmdResetPermanentDeleteTeam {
+ if len(flagTeamName) == 0 {
+ fmt.Fprintln(os.Stderr, "flag needs an argument: -team_name")
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ c := &api.Context{}
+ c.RequestId = model.NewId()
+ c.IpAddress = "cmd_line"
+
+ var team *model.Team
+ if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
+ l4g.Error("%v", result.Err)
+ flushLogAndExit(1)
+ } else {
+ team = result.Data.(*model.Team)
+ }
+
+ var confirmBackup string
+ fmt.Print("Have you performed a database backup? (YES/NO): ")
+ fmt.Scanln(&confirmBackup)
+ if confirmBackup != "YES" {
+ flushLogAndExit(1)
+ }
+
+ var confirm string
+ fmt.Printf("Are you sure you want to delete the team %v? All data will be permanently deleted? (YES/NO): ", team.Name)
+ fmt.Scanln(&confirm)
+ if confirm != "YES" {
+ flushLogAndExit(1)
+ }
+
+ if err := api.PermanentDeleteTeam(c, team); err != nil {
+ l4g.Error("%v", err)
+ flushLogAndExit(1)
+ } else {
+ flushLogAndExit(0)
+ }
+ }
+}
+
func flushLogAndExit(code int) {
l4g.Close()
time.Sleep(time.Second)
@@ -461,5 +567,17 @@ Usage:
Example:
platform -reset_password -team_name="name" -email="user@example.com" -password="newpassword"
+ -permanent_delete_user Permanently deletes a user and all related information
+ include posts from the database. It requires the
+ -team_name, and -email flag.
+ Example:
+ platform -permanent_delete_user -team_name="name" -email="user@example.com"
+
+ -permanent_delete_team Permanently deletes a team and all users along with
+ all related information including posts from the database.
+ It requires the -team_name flag.
+ Example:
+ platform -permanent_delete_team -team_name="name"
+
`
diff --git a/store/sql_audit_store.go b/store/sql_audit_store.go
index fd39eda8f..f4fd29aab 100644
--- a/store/sql_audit_store.go
+++ b/store/sql_audit_store.go
@@ -87,7 +87,7 @@ func (s SqlAuditStore) Get(user_id string, limit int) StoreChannel {
return storeChannel
}
-func (s SqlAuditStore) Delete(userId string) StoreChannel {
+func (s SqlAuditStore) PermanentDeleteByUser(userId string) StoreChannel {
storeChannel := make(StoreChannel)
diff --git a/store/sql_audit_store_test.go b/store/sql_audit_store_test.go
index 4dce6701f..b395631f1 100644
--- a/store/sql_audit_store_test.go
+++ b/store/sql_audit_store_test.go
@@ -45,7 +45,7 @@ func TestSqlAuditStore(t *testing.T) {
t.Fatal("Should have returned empty because user_id is missing")
}
- if r2 := <-store.Audit().Delete(audit.UserId); r2.Err != nil {
+ if r2 := <-store.Audit().PermanentDeleteByUser(audit.UserId); r2.Err != nil {
t.Fatal(r2.Err)
}
}
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go
index 65e2cc45d..cc5c86107 100644
--- a/store/sql_channel_store.go
+++ b/store/sql_channel_store.go
@@ -616,7 +616,7 @@ func (s SqlChannelStore) RemoveMember(channelId string, userId string) StoreChan
return storeChannel
}
-func (s SqlChannelStore) DeleteMember(userId string) StoreChannel {
+func (s SqlChannelStore) PermanentDeleteMembersByUser(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
diff --git a/store/sql_channel_store_test.go b/store/sql_channel_store_test.go
index 238f79be8..695991bf7 100644
--- a/store/sql_channel_store_test.go
+++ b/store/sql_channel_store_test.go
@@ -428,7 +428,7 @@ func TestChannelDeleteMemberStore(t *testing.T) {
t.Fatal("should have saved 2 members")
}
- Must(store.Channel().DeleteMember(o2.UserId))
+ Must(store.Channel().PermanentDeleteMembersByUser(o2.UserId))
count = (<-store.Channel().GetMemberCount(o1.ChannelId)).Data.(int64)
if count != 1 {
diff --git a/store/sql_oauth_store.go b/store/sql_oauth_store.go
index 688e39b09..43a5bee31 100644
--- a/store/sql_oauth_store.go
+++ b/store/sql_oauth_store.go
@@ -333,7 +333,7 @@ func (as SqlOAuthStore) RemoveAuthData(code string) StoreChannel {
return storeChannel
}
-func (as SqlOAuthStore) RemoveAuthDataByUserId(userId string) StoreChannel {
+func (as SqlOAuthStore) PermanentDeleteAuthDataByUser(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
diff --git a/store/sql_oauth_store_test.go b/store/sql_oauth_store_test.go
index 2a9aad1b3..c3f6ea7ac 100644
--- a/store/sql_oauth_store_test.go
+++ b/store/sql_oauth_store_test.go
@@ -181,7 +181,7 @@ func TestOAuthStoreRemoveAuthData(t *testing.T) {
}
}
-func TestOAuthStoreRemoveAuthDataByUserId(t *testing.T) {
+func TestOAuthStoreRemoveAuthDataByUser(t *testing.T) {
Setup()
a1 := model.AuthData{}
@@ -190,7 +190,7 @@ func TestOAuthStoreRemoveAuthDataByUserId(t *testing.T) {
a1.Code = model.NewId()
Must(store.OAuth().SaveAuthData(&a1))
- if err := (<-store.OAuth().RemoveAuthDataByUserId(a1.UserId)).Err; err != nil {
+ if err := (<-store.OAuth().PermanentDeleteAuthDataByUser(a1.UserId)).Err; err != nil {
t.Fatal(err)
}
}
diff --git a/store/sql_post_store.go b/store/sql_post_store.go
index 0bcb420bd..cc596074f 100644
--- a/store/sql_post_store.go
+++ b/store/sql_post_store.go
@@ -228,13 +228,13 @@ func (s SqlPostStore) Delete(postId string, time int64) StoreChannel {
return storeChannel
}
-func (s SqlPostStore) PermanentDelete(userId string) StoreChannel {
+func (s SqlPostStore) permanentDelete(postId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
- _, err := s.GetMaster().Exec("Update Posts SET DeleteAt = :DeleteAt, UpdateAt = :UpdateAt WHERE Id = :Id OR ParentId = :ParentId OR RootId = :RootId", map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": postId, "ParentId": postId, "RootId": postId})
+ _, err := s.GetMaster().Exec("DELETE FROM Posts WHERE Id = :Id OR ParentId = :ParentId OR RootId = :RootId", map[string]interface{}{"Id": postId, "ParentId": postId, "RootId": postId})
if err != nil {
result.Err = model.NewAppError("SqlPostStore.Delete", "We couldn't delete the post", "id="+postId+", err="+err.Error())
}
@@ -246,6 +246,81 @@ func (s SqlPostStore) PermanentDelete(userId string) StoreChannel {
return storeChannel
}
+func (s SqlPostStore) permanentDeleteAllCommentByUser(userId string) StoreChannel {
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ _, err := s.GetMaster().Exec("DELETE FROM Posts WHERE UserId = :UserId AND RootId != ''", map[string]interface{}{"UserId": userId})
+ if err != nil {
+ result.Err = model.NewAppError("SqlPostStore.permanentDeleteAllCommentByUser", "We couldn't delete the comments for user", "userId="+userId+", err="+err.Error())
+ }
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
+
+func (s SqlPostStore) PermanentDeleteByUser(userId string) StoreChannel {
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ // First attempt to delete all the comments for a user
+ if r := <-s.permanentDeleteAllCommentByUser(userId); r.Err != nil {
+ result.Err = r.Err
+ storeChannel <- result
+ close(storeChannel)
+ return
+ }
+
+ // Now attempt to delete all the root posts for a user. This will also
+ // delete all the comments for each post.
+ found := true
+ count := 0
+
+ for found {
+ var ids []string
+ _, err := s.GetMaster().Select(&ids, "SELECT Id FROM Posts WHERE UserId = :UserId LIMIT 1000", map[string]interface{}{"UserId": userId})
+ if err != nil {
+ result.Err = model.NewAppError("SqlPostStore.PermanentDeleteByUser.select", "We couldn't select the posts to delete for the user", "userId="+userId+", err="+err.Error())
+ storeChannel <- result
+ close(storeChannel)
+ return
+ } else {
+ found = false
+ for _, id := range ids {
+ found = true
+ if r := <-s.permanentDelete(id); r.Err != nil {
+ result.Err = r.Err
+ storeChannel <- result
+ close(storeChannel)
+ return
+ }
+ }
+ }
+
+ // This is a fail safe, give up if more than 10K messages
+ count = count + 1
+ if count >= 10 {
+ result.Err = model.NewAppError("SqlPostStore.PermanentDeleteByUser.toolarge", "We couldn't select the posts to delete for the user (too many), please re-run", "userId="+userId)
+ storeChannel <- result
+ close(storeChannel)
+ return
+ }
+ }
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
+
func (s SqlPostStore) GetPosts(channelId string, offset int, limit int) StoreChannel {
storeChannel := make(StoreChannel)
diff --git a/store/sql_post_store_test.go b/store/sql_post_store_test.go
index fe7195a54..d9b087ea7 100644
--- a/store/sql_post_store_test.go
+++ b/store/sql_post_store_test.go
@@ -247,6 +247,76 @@ func TestPostStoreDelete2Level(t *testing.T) {
}
}
+func TestPostStorePermDelete1Level(t *testing.T) {
+ Setup()
+
+ o1 := &model.Post{}
+ o1.ChannelId = model.NewId()
+ o1.UserId = model.NewId()
+ o1.Message = "a" + model.NewId() + "b"
+ o1 = (<-store.Post().Save(o1)).Data.(*model.Post)
+
+ o2 := &model.Post{}
+ o2.ChannelId = o1.ChannelId
+ o2.UserId = model.NewId()
+ o2.Message = "a" + model.NewId() + "b"
+ o2.ParentId = o1.Id
+ o2.RootId = o1.Id
+ o2 = (<-store.Post().Save(o2)).Data.(*model.Post)
+
+ if r2 := <-store.Post().PermanentDeleteByUser(o2.UserId); r2.Err != nil {
+ t.Fatal(r2.Err)
+ }
+
+ if r3 := (<-store.Post().Get(o1.Id)); r3.Err != nil {
+ t.Fatal("Deleted id shouldn't have failed")
+ }
+
+ if r4 := (<-store.Post().Get(o2.Id)); r4.Err == nil {
+ t.Fatal("Deleted id should have failed")
+ }
+}
+
+func TestPostStorePermDelete1Level2(t *testing.T) {
+ Setup()
+
+ o1 := &model.Post{}
+ o1.ChannelId = model.NewId()
+ o1.UserId = model.NewId()
+ o1.Message = "a" + model.NewId() + "b"
+ o1 = (<-store.Post().Save(o1)).Data.(*model.Post)
+
+ o2 := &model.Post{}
+ o2.ChannelId = o1.ChannelId
+ o2.UserId = model.NewId()
+ o2.Message = "a" + model.NewId() + "b"
+ o2.ParentId = o1.Id
+ o2.RootId = o1.Id
+ o2 = (<-store.Post().Save(o2)).Data.(*model.Post)
+
+ o3 := &model.Post{}
+ o3.ChannelId = model.NewId()
+ o3.UserId = model.NewId()
+ o3.Message = "a" + model.NewId() + "b"
+ o3 = (<-store.Post().Save(o3)).Data.(*model.Post)
+
+ if r2 := <-store.Post().PermanentDeleteByUser(o1.UserId); r2.Err != nil {
+ t.Fatal(r2.Err)
+ }
+
+ if r3 := (<-store.Post().Get(o1.Id)); r3.Err == nil {
+ t.Fatal("Deleted id should have failed")
+ }
+
+ if r4 := (<-store.Post().Get(o2.Id)); r4.Err == nil {
+ t.Fatal("Deleted id should have failed")
+ }
+
+ if r5 := (<-store.Post().Get(o3.Id)); r5.Err != nil {
+ t.Fatal("Deleted id shouldn't have failed")
+ }
+}
+
func TestPostStoreGetWithChildren(t *testing.T) {
Setup()
diff --git a/store/sql_preference_store.go b/store/sql_preference_store.go
index 6fa30ba7a..8454abcbd 100644
--- a/store/sql_preference_store.go
+++ b/store/sql_preference_store.go
@@ -240,7 +240,7 @@ func (s SqlPreferenceStore) GetAll(userId string) StoreChannel {
return storeChannel
}
-func (s SqlPreferenceStore) Delete(userId string) StoreChannel {
+func (s SqlPreferenceStore) PermanentDeleteByUser(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
diff --git a/store/sql_preference_store_test.go b/store/sql_preference_store_test.go
index 8d850e22c..77da71fd6 100644
--- a/store/sql_preference_store_test.go
+++ b/store/sql_preference_store_test.go
@@ -228,7 +228,7 @@ func TestPreferenceDelete(t *testing.T) {
Must(store.Preference().Save(&preferences))
- if result := <-store.Preference().Delete(userId); result.Err != nil {
+ if result := <-store.Preference().PermanentDeleteByUser(userId); result.Err != nil {
t.Fatal(result.Err)
}
}
diff --git a/store/sql_session_store.go b/store/sql_session_store.go
index 8237d8200..86604b4fe 100644
--- a/store/sql_session_store.go
+++ b/store/sql_session_store.go
@@ -158,7 +158,7 @@ func (me SqlSessionStore) RemoveAllSessionsForTeam(teamId string) StoreChannel {
return storeChannel
}
-func (me SqlSessionStore) RemoveAllSessionsForUser(userId string) StoreChannel {
+func (me SqlSessionStore) PermanentDeleteSessionsByUser(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
diff --git a/store/sql_session_store_test.go b/store/sql_session_store_test.go
index a06a2bdff..cec8e93b0 100644
--- a/store/sql_session_store_test.go
+++ b/store/sql_session_store_test.go
@@ -119,7 +119,7 @@ func TestSessionRemoveByUser(t *testing.T) {
}
}
- Must(store.Session().RemoveAllSessionsForUser(s1.UserId))
+ Must(store.Session().PermanentDeleteSessionsByUser(s1.UserId))
if rs2 := (<-store.Session().Get(s1.Id)); rs2.Err == nil {
t.Fatal("should have been removed")
diff --git a/store/sql_team_store.go b/store/sql_team_store.go
index 7bcdc7349..9578549ca 100644
--- a/store/sql_team_store.go
+++ b/store/sql_team_store.go
@@ -301,7 +301,7 @@ func (s SqlTeamStore) GetAllTeamListing() StoreChannel {
return storeChannel
}
-func (s SqlTeamStore) Delete(teamId string) StoreChannel {
+func (s SqlTeamStore) PermanentDelete(teamId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
diff --git a/store/sql_team_store_test.go b/store/sql_team_store_test.go
index 6547b0c8f..7dc31cbe2 100644
--- a/store/sql_team_store_test.go
+++ b/store/sql_team_store_test.go
@@ -257,7 +257,7 @@ func TestDelete(t *testing.T) {
o2.Type = model.TEAM_OPEN
Must(store.Team().Save(&o2))
- if r1 := <-store.Team().Delete(o1.Id); r1.Err != nil {
+ if r1 := <-store.Team().PermanentDelete(o1.Id); r1.Err != nil {
t.Fatal(r1.Err)
}
}
diff --git a/store/sql_user_store.go b/store/sql_user_store.go
index 90efc00f1..d19135b64 100644
--- a/store/sql_user_store.go
+++ b/store/sql_user_store.go
@@ -555,7 +555,7 @@ func (us SqlUserStore) GetTotalActiveUsersCount() StoreChannel {
return storeChannel
}
-func (us SqlUserStore) Delete(userId string) StoreChannel {
+func (us SqlUserStore) PermanentDelete(userId string) StoreChannel {
storeChannel := make(StoreChannel)
diff --git a/store/sql_user_store_test.go b/store/sql_user_store_test.go
index 25f4a3475..dd08438f1 100644
--- a/store/sql_user_store_test.go
+++ b/store/sql_user_store_test.go
@@ -386,7 +386,7 @@ func TestUserStoreDelete(t *testing.T) {
u1.Email = model.NewId()
Must(store.User().Save(&u1))
- if err := (<-store.User().Delete(u1.Id)).Err; err != nil {
+ if err := (<-store.User().PermanentDelete(u1.Id)).Err; err != nil {
t.Fatal(err)
}
}
diff --git a/store/sql_webhook_store.go b/store/sql_webhook_store.go
index 11b9f6e52..b7bf0615f 100644
--- a/store/sql_webhook_store.go
+++ b/store/sql_webhook_store.go
@@ -116,7 +116,7 @@ func (s SqlWebhookStore) DeleteIncoming(webhookId string, time int64) StoreChann
return storeChannel
}
-func (s SqlWebhookStore) DeleteIncomingByUser(userId string) StoreChannel {
+func (s SqlWebhookStore) PermanentDeleteIncomingByUser(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
@@ -312,7 +312,7 @@ func (s SqlWebhookStore) DeleteOutgoing(webhookId string, time int64) StoreChann
return storeChannel
}
-func (s SqlWebhookStore) DeleteOutgoingByUser(userId string) StoreChannel {
+func (s SqlWebhookStore) PermanentDeleteOutgoingByUser(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
diff --git a/store/sql_webhook_store_test.go b/store/sql_webhook_store_test.go
index 1b770c6d4..1a9d5be3b 100644
--- a/store/sql_webhook_store_test.go
+++ b/store/sql_webhook_store_test.go
@@ -121,7 +121,7 @@ func TestWebhookStoreDeleteIncomingByUser(t *testing.T) {
}
}
- if r2 := <-store.Webhook().DeleteIncomingByUser(o1.UserId); r2.Err != nil {
+ if r2 := <-store.Webhook().PermanentDeleteIncomingByUser(o1.UserId); r2.Err != nil {
t.Fatal(r2.Err)
}
@@ -305,7 +305,7 @@ func TestWebhookStoreDeleteOutgoingByUser(t *testing.T) {
}
}
- if r2 := <-store.Webhook().DeleteOutgoingByUser(o1.CreatorId); r2.Err != nil {
+ if r2 := <-store.Webhook().PermanentDeleteOutgoingByUser(o1.CreatorId); r2.Err != nil {
t.Fatal(r2.Err)
}
diff --git a/store/store.go b/store/store.go
index 13434e7b0..a8b57dcdd 100644
--- a/store/store.go
+++ b/store/store.go
@@ -52,7 +52,7 @@ type TeamStore interface {
GetAll() StoreChannel
GetAllTeamListing() StoreChannel
GetByInviteId(inviteId string) StoreChannel
- Delete(teamId string) StoreChannel
+ PermanentDelete(teamId string) StoreChannel
}
type ChannelStore interface {
@@ -73,7 +73,7 @@ type ChannelStore interface {
GetMember(channelId string, userId string) StoreChannel
GetMemberCount(channelId string) StoreChannel
RemoveMember(channelId string, userId string) StoreChannel
- DeleteMember(userId string) StoreChannel
+ PermanentDeleteMembersByUser(userId string) StoreChannel
GetExtraMembers(channelId string, limit int) StoreChannel
CheckPermissionsTo(teamId string, channelId string, userId string) StoreChannel
CheckOpenChannelPermissions(teamId string, channelId string) StoreChannel
@@ -88,6 +88,7 @@ type PostStore interface {
Update(post *model.Post, newMessage string, newHashtags string) StoreChannel
Get(id string) StoreChannel
Delete(postId string, time int64) StoreChannel
+ PermanentDeleteByUser(userId string) StoreChannel
GetPosts(channelId string, offset int, limit int) StoreChannel
GetPostsBefore(channelId string, postId string, numPosts int, offset int) StoreChannel
GetPostsAfter(channelId string, postId string, numPosts int, offset int) StoreChannel
@@ -120,7 +121,7 @@ type UserStore interface {
GetTotalUsersCount() StoreChannel
GetTotalActiveUsersCount() StoreChannel
GetSystemAdminProfiles() StoreChannel
- Delete(userId string) StoreChannel
+ PermanentDelete(userId string) StoreChannel
}
type SessionStore interface {
@@ -129,7 +130,7 @@ type SessionStore interface {
GetSessions(userId string) StoreChannel
Remove(sessionIdOrToken string) StoreChannel
RemoveAllSessionsForTeam(teamId string) StoreChannel
- RemoveAllSessionsForUser(teamId string) StoreChannel
+ PermanentDeleteSessionsByUser(teamId string) StoreChannel
UpdateLastActivityAt(sessionId string, time int64) StoreChannel
UpdateRoles(userId string, roles string) StoreChannel
}
@@ -137,7 +138,7 @@ type SessionStore interface {
type AuditStore interface {
Save(audit *model.Audit) StoreChannel
Get(user_id string, limit int) StoreChannel
- Delete(userId string) StoreChannel
+ PermanentDeleteByUser(userId string) StoreChannel
}
type OAuthStore interface {
@@ -148,7 +149,7 @@ type OAuthStore interface {
SaveAuthData(authData *model.AuthData) StoreChannel
GetAuthData(code string) StoreChannel
RemoveAuthData(code string) StoreChannel
- RemoveAuthDataByUserId(userId string) StoreChannel
+ PermanentDeleteAuthDataByUser(userId string) StoreChannel
SaveAccessData(accessData *model.AccessData) StoreChannel
GetAccessData(token string) StoreChannel
GetAccessDataByAuthCode(authCode string) StoreChannel
@@ -167,14 +168,14 @@ type WebhookStore interface {
GetIncomingByUser(userId string) StoreChannel
GetIncomingByChannel(channelId string) StoreChannel
DeleteIncoming(webhookId string, time int64) StoreChannel
- DeleteIncomingByUser(userId string) StoreChannel
+ PermanentDeleteIncomingByUser(userId string) StoreChannel
SaveOutgoing(webhook *model.OutgoingWebhook) StoreChannel
GetOutgoing(id string) StoreChannel
GetOutgoingByCreator(userId string) StoreChannel
GetOutgoingByChannel(channelId string) StoreChannel
GetOutgoingByTeam(teamId string) StoreChannel
DeleteOutgoing(webhookId string, time int64) StoreChannel
- DeleteOutgoingByUser(userId string) StoreChannel
+ PermanentDeleteOutgoingByUser(userId string) StoreChannel
UpdateOutgoing(hook *model.OutgoingWebhook) StoreChannel
}
@@ -183,5 +184,5 @@ type PreferenceStore interface {
Get(userId string, category string, name string) StoreChannel
GetCategory(userId string, category string) StoreChannel
GetAll(userId string) StoreChannel
- Delete(userId string) StoreChannel
+ PermanentDeleteByUser(userId string) StoreChannel
}
diff --git a/utils/config.go b/utils/config.go
index 13b7b6b64..2fd799cd1 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -59,8 +59,7 @@ func FindDir(dir string) string {
func ConfigureCmdLineLog() {
ls := model.LogSettings{}
ls.EnableConsole = true
- ls.ConsoleLevel = "ERROR"
- ls.EnableFile = false
+ ls.ConsoleLevel = "WARN"
configureLog(&ls)
}
@@ -72,6 +71,8 @@ func configureLog(s *model.LogSettings) {
level := l4g.DEBUG
if s.ConsoleLevel == "INFO" {
level = l4g.INFO
+ } else if s.ConsoleLevel == "WARN" {
+ level = l4g.WARNING
} else if s.ConsoleLevel == "ERROR" {
level = l4g.ERROR
}
@@ -90,6 +91,8 @@ func configureLog(s *model.LogSettings) {
level := l4g.DEBUG
if s.FileLevel == "INFO" {
level = l4g.INFO
+ } else if s.FileLevel == "WARN" {
+ level = l4g.WARNING
} else if s.FileLevel == "ERROR" {
level = l4g.ERROR
}