Merge pull request #61 from RafaySystems/soft-delete

Switch to using soft delete for resources
This commit is contained in:
abin-rafay
2022-03-16 17:09:59 +05:30
committed by GitHub
6 changed files with 39 additions and 32 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ func (dao *roleDAO) Close() error {
}
func (dao *roleDAO) GetRolePermissions(ctx context.Context, id uuid.UUID) ([]models.ResourcePermission, error) {
// Could possibily union them later for some speedup
// Could possibly union them later for some speedup
var r = []models.ResourcePermission{}
err := dao.db.NewSelect().Table("authsrv_resourcepermission").
ColumnExpr("authsrv_resourcepermission.name as name").
+18 -11
View File
@@ -39,7 +39,7 @@ type EntityDAO interface {
// delete entity
Delete(context.Context, uuid.UUID, interface{}) error
// delete all items in table (for script)
DeleteAll(context.Context, interface{}) error
HardDeleteAll(context.Context, interface{}) error
// get list of entities
List(context.Context, uuid.NullUUID, uuid.NullUUID, interface{}) (interface{}, error)
// get list of entities
@@ -135,7 +135,8 @@ func (dao *entityDAO) GetByNamePartnerOrg(ctx context.Context, name string, pid
if pid.Valid {
sq = sq.Where("partner_id = ?", pid)
}
sq = sq.Where("name = ?", name)
sq = sq.Where("name = ?", name).
Where("trash = ?", false)
err := sq.Scan(ctx)
if err != nil {
@@ -145,10 +146,10 @@ func (dao *entityDAO) GetByNamePartnerOrg(ctx context.Context, name string, pid
return entity, nil
}
func (dao *entityDAO) GetIdByName(ctx context.Context, name string, entity interface{}) (interface{}, error) {
err := dao.db.NewSelect().Column("id").Model(entity).
Where("name = ?", name).
Where("trash = ?", false).
Scan(ctx)
if err != nil {
return nil, err
@@ -165,7 +166,8 @@ func (dao *entityDAO) GetIdByNamePartnerOrg(ctx context.Context, name string, pi
if pid.Valid {
sq = sq.Where("partner_id = ?", pid)
}
sq = sq.Where("name = ?", name)
sq = sq.Where("name = ?", name).
Where("trash = ?", false)
err := sq.Scan(ctx)
if err != nil {
@@ -178,6 +180,7 @@ func (dao *entityDAO) GetIdByNamePartnerOrg(ctx context.Context, name string, pi
func (dao *entityDAO) GetNameById(ctx context.Context, id uuid.UUID, entity interface{}) (interface{}, error) {
err := dao.db.NewSelect().Column("name").Model(entity).
Where("id = ?", id).
Where("trash = ?", false).
Scan(ctx)
if err != nil {
return nil, err
@@ -201,22 +204,27 @@ func (dao *entityDAO) UpdateX(ctx context.Context, field string, value interface
}
func (dao *entityDAO) Delete(ctx context.Context, id uuid.UUID, entity interface{}) error {
_, err := dao.db.NewDelete().
_, err := dao.db.NewUpdate().
Model(entity).
Column("trash").
Where("id = ?", id).
Set("trash = ?", true).
Exec(ctx)
return err
}
func (dao *entityDAO) DeleteX(ctx context.Context, field string, value interface{}, entity interface{}) error {
_, err := dao.db.NewDelete().Model(entity).
_, err := dao.db.NewUpdate().
Model(entity).
Column("trash").
Where("? = ?", bun.Ident(field), value).
Set("trash = ?", true).
Exec(ctx)
return err
}
func (dao *entityDAO) DeleteAll(ctx context.Context, entity interface{}) error {
// HardDeleteAll deletes all records in a table (primarily for use in scripts)
func (dao *entityDAO) HardDeleteAll(ctx context.Context, entity interface{}) error {
_, err := dao.db.NewDelete().
Model(entity).
Where("1 = 1"). // TODO: see how to remove this
@@ -237,7 +245,6 @@ func (dao *entityDAO) List(ctx context.Context, partnerId uuid.NullUUID, organiz
return entities, err
}
func (dao *entityDAO) ListByProject(ctx context.Context, partnerId uuid.NullUUID, organizationId uuid.NullUUID, projectId uuid.NullUUID, entities interface{}) error {
sq := dao.db.NewSelect().Model(entities)
if partnerId.Valid {
@@ -260,7 +267,7 @@ func (dao *entityDAO) ListAll(ctx context.Context, entities interface{}) (interf
}
func (dao *entityDAO) GetByTraits(ctx context.Context, name string, entity interface{}) (interface{}, error) {
// TODO: better name and possibily pass in trait name
// TODO: better name and possibly pass in trait name
err := dao.db.NewSelect().Model(entity).
Where("traits ->> 'email' = ?", name).
Scan(ctx)
@@ -272,7 +279,7 @@ func (dao *entityDAO) GetByTraits(ctx context.Context, name string, entity inter
}
func (dao *entityDAO) GetIdByTraits(ctx context.Context, name string, entity interface{}) (interface{}, error) {
// TODO: better name and possibily pass in trait name
// TODO: better name and possibly pass in trait name
err := dao.db.NewSelect().Column("id").Model(entity).
Where("traits ->> 'email' = ?", name).
Scan(ctx)
+9 -9
View File
@@ -400,7 +400,7 @@ func TestUpdateGroupWithUsersWithRoles(t *testing.T) {
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(guuid, "group-"+guuid))
// TODO: more precise checks
mock.ExpectExec(`DELETE FROM "authsrv_groupaccount" AS "groupaccount" WHERE ."group_id" = '` + guuid).
mock.ExpectExec(`UPDATE "authsrv_groupaccount" AS "groupaccount" SET trash = TRUE WHERE ."group_id" = '` + guuid).
WillReturnResult(sqlmock.NewResult(1, 1))
for _, u := range tc.users {
mock.ExpectQuery(`SELECT "identities"."id" FROM "identities" WHERE .*traits ->> 'email' = '` + u + `'`).
@@ -408,11 +408,11 @@ func TestUpdateGroupWithUsersWithRoles(t *testing.T) {
}
mock.ExpectQuery(`INSERT INTO "authsrv_groupaccount"`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uuid.New().String()))
mock.ExpectExec(`DELETE FROM "authsrv_grouprole" AS "grouprole" WHERE ."group_id" = '` + guuid).
mock.ExpectExec(`UPDATE "authsrv_grouprole" AS "grouprole" SET trash = TRUE WHERE ."group_id" = '` + guuid).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_projectgrouprole" AS "projectgrouprole" WHERE ."group_id" = '` + guuid).
mock.ExpectExec(`UPDATE "authsrv_projectgrouprole" AS "projectgrouprole" SET trash = TRUE WHERE ."group_id" = '` + guuid).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_projectgroupnamespacerole" AS "projectgroupnamespacerole" WHERE ."group_id" = '` + guuid).
mock.ExpectExec(`UPDATE "authsrv_projectgroupnamespacerole" AS "projectgroupnamespacerole" SET trash = TRUE WHERE ."group_id" = '` + guuid).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectQuery(`SELECT "resourcerole"."id" FROM "authsrv_resourcerole" AS "resourcerole"`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(pruuid))
@@ -470,15 +470,15 @@ func TestGroupDelete(t *testing.T) {
mock.ExpectQuery(`SELECT "group"."id", "group"."name", .* FROM "authsrv_group" AS "group" WHERE`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(guuid, "group-"+guuid))
mock.ExpectExec(`DELETE FROM "authsrv_grouprole" AS "grouprole" WHERE ."group_id" = '` + guuid).
mock.ExpectExec(`UPDATE "authsrv_grouprole" AS "grouprole" SET trash = TRUE WHERE ."group_id" = '` + guuid).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_projectgrouprole" AS "projectgrouprole" WHERE ."group_id" = '` + guuid).
mock.ExpectExec(`UPDATE "authsrv_projectgrouprole" AS "projectgrouprole" SET trash = TRUE WHERE ."group_id" = '` + guuid).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_projectgroupnamespacerole" AS "projectgroupnamespacerole" WHERE ."group_id" = '` + guuid).
mock.ExpectExec(`UPDATE "authsrv_projectgroupnamespacerole" AS "projectgroupnamespacerole" SET trash = TRUE WHERE ."group_id" = '` + guuid).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_groupaccount" AS "groupaccount" WHERE ."group_id" = '` + guuid).
mock.ExpectExec(`UPDATE "authsrv_groupaccount" AS "groupaccount" SET trash = TRUE WHERE ."group_id" = '` + guuid).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_group" AS "group" WHERE .id = '` + guuid).
mock.ExpectExec(`UPDATE "authsrv_group" AS "group" SET trash = TRUE WHERE .id = '` + guuid).
WillReturnResult(sqlmock.NewResult(1, 1))
group := &userv3.Group{
+1 -1
View File
@@ -79,7 +79,7 @@ func TestMetroDelete(t *testing.T) {
mock.ExpectQuery(`SELECT "metro"."id", "metro"."name", .* FROM "cluster_metro" AS "metro" WHERE`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(puuid, "metro-"+puuid))
mock.ExpectExec(`DELETE FROM "cluster_metro"`).
mock.ExpectExec(`UPDATE "cluster_metro" AS "metro" SET trash = TRUE WHERE`).
WillReturnResult(sqlmock.NewResult(1, 1))
metro := &infrav3.Location{
+3 -3
View File
@@ -170,7 +170,7 @@ func TestUpdateRole(t *testing.T) {
mock.ExpectExec(`UPDATE "authsrv_resourcerole" AS "resourcerole" SET "name" = 'role-` + ruuid + `', .*"organization_id" = '` + ouuid + `', "partner_id" = '` + puuid + `', "is_global" = TRUE, "scope" = 'system' WHERE .id = '` + ruuid + `'.`).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_resourcerolepermission" AS "resourcerolepermission" WHERE ."resource_role_id" = '` + ruuid + `'.`).
mock.ExpectExec(`UPDATE "authsrv_resourcerolepermission" AS "resourcerolepermission" SET trash = TRUE WHERE ."resource_role_id" = '` + ruuid + `'.`).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectQuery(`SELECT "resourcepermission"."id" FROM "authsrv_resourcepermission" AS "resourcepermission" WHERE .name = 'ops_star.all'.`).
@@ -207,9 +207,9 @@ func TestRoleDelete(t *testing.T) {
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid))
mock.ExpectQuery(`SELECT "resourcerole"."id", "resourcerole"."name", .* FROM "authsrv_resourcerole" AS "resourcerole" WHERE`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(ruuid, "role-"+ruuid))
mock.ExpectExec(`DELETE FROM "authsrv_resourcerolepermission" AS "resourcerolepermission" WHERE ."resource_role_id" = '` + ruuid + `'.`).
mock.ExpectExec(`UPDATE "authsrv_resourcerolepermission" AS "resourcerolepermission" SET trash = TRUE WHERE ."resource_role_id" = '` + ruuid + `'.`).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_resourcerole" AS "resourcerole" WHERE .id = '` + ruuid + `'.`).
mock.ExpectExec(`UPDATE "authsrv_resourcerole" AS "resourcerole" SET trash = TRUE WHERE .id = '` + ruuid + `'.`).
WillReturnResult(sqlmock.NewResult(1, 1))
role := &rolev3.Role{
+7 -7
View File
@@ -187,11 +187,11 @@ func TestUpdateUser(t *testing.T) {
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid))
mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid))
mock.ExpectExec(`DELETE FROM "authsrv_accountresourcerole" AS "accountresourcerole" WHERE`).
mock.ExpectExec(`UPDATE "authsrv_accountresourcerole" AS "accountresourcerole" SET trash = TRUE WHERE`).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_projectaccountresourcerole" AS "projectaccountresourcerole" WHERE`).
mock.ExpectExec(`UPDATE "authsrv_projectaccountresourcerole" AS "projectaccountresourcerole" SET trash = TRUE WHERE`).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_projectaccountnamespacerole" AS "projectaccountnamespacerole" WHERE`).
mock.ExpectExec(`UPDATE "authsrv_projectaccountnamespacerole" AS "projectaccountnamespacerole" SET trash = TRUE WHERE`).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectQuery(`SELECT "resourcerole"."id" FROM "authsrv_resourcerole" AS "resourcerole"`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(pruuid))
@@ -399,14 +399,14 @@ func TestUserDelete(t *testing.T) {
mock.ExpectQuery(`SELECT "identities"."id" FROM "identities" WHERE .*traits ->> 'email' = 'user-` + uuuid + `'`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "traits"}).AddRow(uuuid, []byte(`{"email":"johndoe@provider.com"}`)))
mock.ExpectExec(`DELETE FROM "authsrv_accountresourcerole" AS "accountresourcerole" WHERE`).
mock.ExpectExec(`UPDATE "authsrv_accountresourcerole" AS "accountresourcerole" SET trash = TRUE WHERE`).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_projectaccountresourcerole" AS "projectaccountresourcerole" WHERE`).
mock.ExpectExec(`UPDATE "authsrv_projectaccountresourcerole" AS "projectaccountresourcerole" SET trash = TRUE WHERE`).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec(`DELETE FROM "authsrv_projectaccountnamespacerole" AS "projectaccountnamespacerole" WHERE`).
mock.ExpectExec(`UPDATE "authsrv_projectaccountnamespacerole" AS "projectaccountnamespacerole" SET trash = TRUE WHERE`).
WillReturnResult(sqlmock.NewResult(1, 1))
// User delete is via kratos
mock.ExpectExec(`DELETE FROM "authsrv_groupaccount" AS "groupaccount" WHERE`).
mock.ExpectExec(`UPDATE "authsrv_groupaccount" AS "groupaccount" SET trash = TRUE WHERE`).
WillReturnResult(sqlmock.NewResult(1, 1))
user := &userv3.User{