Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete User #787

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions actions/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,17 @@ func PutVerifyEmail(c *gin.Context) {
"message": "Your email has been verified.",
})
}

func DeleteUser(c *gin.Context) {
user := middleware.GetUser(c)

err := storage.DeleteUserByID(c, user.ID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": "Unable to delete your account. Please try again.",
})
return
}
// todo what to return when user and all stats is deleted.

}
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.14
require (
cloud.google.com/go v0.66.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef
github.com/aws/aws-sdk-go v1.34.28
github.com/aws/aws-sdk-go v1.34.29
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/didip/tollbooth v4.0.2+incompatible
github.com/didip/tollbooth_gin v0.0.0-20170928041415-5752492be505
Expand All @@ -17,6 +17,7 @@ require (
github.com/go-playground/validator/v10 v10.3.0
github.com/go-sql-driver/mysql v1.5.0
github.com/gobuffalo/genny v0.0.0-20181207164119-84844398a37d // indirect
github.com/golang/snappy v0.0.2 // indirect
github.com/google/go-github/v25 v25.1.3
github.com/google/uuid v1.1.2
github.com/gorilla/csrf v1.7.0
Expand All @@ -37,10 +38,10 @@ require (
github.com/unrolled/secure v1.0.8
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
golang.org/x/sys v0.0.0-20200918174421-af09f7315aff // indirect
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
google.golang.org/api v0.32.0
google.golang.org/genproto v0.0.0-20200918140846-d0d605568037 // indirect
google.golang.org/genproto v0.0.0-20200923140941-5646d36feee1 // indirect
google.golang.org/grpc v1.32.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ezzarghili/recaptcha-go.v3 v3.0.1
Expand Down
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ github.com/aws/aws-sdk-go v1.34.26 h1:tw4nsSfGvCDnXt2xPe8NkxIrDui+asAWinMknPLEf8
github.com/aws/aws-sdk-go v1.34.26/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk=
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/aws/aws-sdk-go v1.34.29 h1:4Yw8eC4nCXiIVmHJO5PD4oh0vI/df5o6cYTVzFV7vWA=
github.com/aws/aws-sdk-go v1.34.29/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
Expand Down Expand Up @@ -372,6 +374,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
Expand Down Expand Up @@ -560,6 +564,8 @@ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
github.com/mattn/go-sqlite3 v1.14.3 h1:j7a/xn1U6TKA/PHHxqZuzh64CdtRc7rU9M+AvkOl5bA=
github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
Expand Down Expand Up @@ -959,6 +965,8 @@ golang.org/x/sys v0.0.0-20200915084602-288bc346aa39 h1:356XA7ITklAU2//sYkjFeco+d
golang.org/x/sys v0.0.0-20200915084602-288bc346aa39/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200918174421-af09f7315aff h1:1CPUrky56AcgSpxz/KfgzQWzfG09u5YOL8MvPYBlrL8=
golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860 h1:YEu4SMq7D0cmT7CBbXfcH0NZeuChAXwsHe/9XueUO6o=
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
Expand Down Expand Up @@ -1127,6 +1135,8 @@ google.golang.org/genproto v0.0.0-20200914193844-75d14daec038 h1:SnvTpXhVDJGFxzZ
google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200918140846-d0d605568037 h1:ujwz1DPMeHwCvo36rK5shXhAzc4GMRecrqQFaMZJBKQ=
google.golang.org/genproto v0.0.0-20200918140846-d0d605568037/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200923140941-5646d36feee1 h1:TU5GbVQeo+Ze5VMgDsSsq/21Q9QPjumrK/dVlpMZsFo=
google.golang.org/genproto v0.0.0-20200923140941-5646d36feee1/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
Expand Down
1 change: 1 addition & 0 deletions routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ func New() http.Handler {
{
users.GET("", actions.GetMe)
users.POST("/password", actions.ChangePassword)
users.DELETE("", actions.DeleteUser)
}

templates := authorized.Group("/templates")
Expand Down
7 changes: 6 additions & 1 deletion storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Storage interface {
GetActiveUserByUsername(string) (*entities.User, error)
CreateUser(*entities.User) error
UpdateUser(*entities.User) error
DeleteUserByID(userID int64) error

GetSession(sessionID string) (*entities.Session, error)
CreateSession(s *entities.Session) error
Expand Down Expand Up @@ -139,6 +140,11 @@ func UpdateUser(c context.Context, user *entities.User) error {
return GetFromContext(c).UpdateUser(user)
}

// DeleteUserByID removes user and all stats
func DeleteUserByID(c context.Context, userID int64) error {
return GetFromContext(c).DeleteUserByID(userID)
}

// GetSession returns the session by the given session id.
func GetSession(c context.Context, sessionID string) (*entities.Session, error) {
return GetFromContext(c).GetSession(sessionID)
Expand Down Expand Up @@ -220,7 +226,6 @@ func GetCampaignOpens(c context.Context, campaignID, userID int64, p *Pagination
return GetFromContext(c).GetCampaignOpens(campaignID, userID, p)
}


// GetTotalSends returns total sends for specified campaign id
func GetTotalSends(c context.Context, campaignID, userID int64) (int64, error) {
return GetFromContext(c).GetTotalSends(campaignID, userID)
Expand Down
122 changes: 122 additions & 0 deletions storage/user.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package storage

import (
"context"
"database/sql"

"github.com/jinzhu/gorm"

"github.com/mailbadger/app/entities"
)

Expand Down Expand Up @@ -51,3 +55,121 @@ func BelongsToUser(userID int64) func(*gorm.DB) *gorm.DB {
return db.Where("user_id = ?", userID)
}
}

func (db *store) DeleteUserByID(userID int64) error {
tx := db.BeginTx(context.Background(), &sql.TxOptions{})

// delete * from sends
var send entities.Send
err := tx.Where("user_id = ?", userID).Delete(send).Error
if err != nil {
tx.Rollback()
return err
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap the error with a message.

return fmt.Errorf("storage user: delete sends stat: %w", err)

}
// delete * from ses_keys
var sesKeys entities.SesKeys
err = tx.Where("user_id = ?", userID).Delete(sesKeys).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from api_keys
var apiKeys entities.APIKey
err = tx.Where("user_id = ?", userID).Delete(apiKeys).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from sessions
var sessions entities.Session
err = tx.Where("user_id = ?", userID).Delete(sessions).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from campaigns
var campaigns entities.Campaign
err = tx.Where("user_id = ?", userID).Delete(campaigns).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from subscribers
var subscribers entities.Subscriber
err = tx.Where("user_id = ?", userID).Delete(subscribers).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from segments
var segments entities.Segment
err = tx.Where("user_id = ?", userID).Delete(segments).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from bounces
var bounces entities.Bounce
err = tx.Where("user_id = ?", userID).Delete(bounces).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from complaints
var complaints entities.Complaint
err = tx.Where("user_id = ?", userID).Delete(complaints).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from clicks
var clicks entities.Click
err = tx.Where("user_id = ?", userID).Delete(clicks).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from opens
var opens entities.Open
err = tx.Where("user_id = ?", userID).Delete(opens).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from deliveries
var deliveries entities.Delivery
err = tx.Where("user_id = ?", userID).Delete(deliveries).Error
if err != nil {
tx.Rollback()
return err
}

// delete * from send_bulk_logs
var sendBulkLogs entities.SendBulkLog
err = tx.Where("user_id = ?", userID).Delete(sendBulkLogs).Error
if err != nil {
tx.Rollback()
return err
}

/*// delete * from users
var user entities.User
err = tx.Where("id = ?", userID).Delete(user).Error
if err != nil {
tx.Rollback()
return err
}*/

tx.Commit()
return nil
}