mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-02-12 16:12:44 +00:00
fix delete orphan recipients when orphan is in active campaign
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
This commit is contained in:
@@ -434,45 +434,6 @@ func (r *Recipient) GetOrphaned(
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DeleteAllOrphaned deletes all recipients that are not in any group
|
||||
func (r *Recipient) DeleteAllOrphaned(
|
||||
ctx context.Context,
|
||||
companyID *uuid.UUID,
|
||||
) (int64, error) {
|
||||
// build optimized LEFT JOIN delete query for orphaned recipients
|
||||
var companyFilter string
|
||||
var args []interface{}
|
||||
|
||||
if companyID != nil {
|
||||
companyFilter = fmt.Sprintf("AND r.company_id = ?")
|
||||
args = append(args, companyID)
|
||||
} else {
|
||||
companyFilter = fmt.Sprintf("AND r.company_id IS NULL")
|
||||
}
|
||||
|
||||
// use raw SQL for optimized LEFT JOIN delete
|
||||
query := fmt.Sprintf(`
|
||||
DELETE FROM %s
|
||||
WHERE id IN (
|
||||
SELECT r.id FROM %s r
|
||||
LEFT JOIN %s rgr ON r.id = rgr.recipient_id
|
||||
WHERE rgr.recipient_id IS NULL %s
|
||||
)`,
|
||||
database.RECIPIENT_TABLE,
|
||||
database.RECIPIENT_TABLE,
|
||||
database.RECIPIENT_GROUP_RECIPIENT_TABLE,
|
||||
companyFilter,
|
||||
)
|
||||
|
||||
result := r.DB.Exec(query, args...)
|
||||
|
||||
if result.Error != nil {
|
||||
return 0, result.Error
|
||||
}
|
||||
|
||||
return result.RowsAffected, nil
|
||||
}
|
||||
|
||||
// GetByID gets a recipient by id
|
||||
func (r *Recipient) GetByID(
|
||||
ctx context.Context,
|
||||
|
||||
@@ -437,15 +437,30 @@ func (r *Recipient) DeleteAllOrphaned(
|
||||
r.AuditLogNotAuthorized(ae)
|
||||
return 0, errs.ErrAuthorizationFailed
|
||||
}
|
||||
// delete orphaned recipients
|
||||
count, err := r.RecipientRepository.DeleteAllOrphaned(
|
||||
|
||||
// get all orphaned recipients
|
||||
orphanedRecipients, err := r.RecipientRepository.GetOrphaned(
|
||||
ctx,
|
||||
companyID,
|
||||
&repository.RecipientOption{}, // no pagination, get all
|
||||
)
|
||||
if err != nil {
|
||||
r.Logger.Errorw("failed to delete orphaned recipients - failed to delete orphaned recipients", "error", err)
|
||||
r.Logger.Errorw("failed to get orphaned recipients", "error", err)
|
||||
return 0, errs.Wrap(err)
|
||||
}
|
||||
|
||||
// delete each orphaned recipient using core deletion logic
|
||||
var count int64
|
||||
for _, recipient := range orphanedRecipients.Rows {
|
||||
recipientID := recipient.ID.MustGet()
|
||||
err = r.deleteRecipientByID(ctx, &recipientID)
|
||||
if err != nil {
|
||||
r.Logger.Errorw("failed to delete orphaned recipient", "error", err, "recipientID", recipientID.String())
|
||||
return count, errs.Wrap(err)
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
ae.Details["count"] = count
|
||||
r.AuditLogAuthorized(ae)
|
||||
return count, nil
|
||||
@@ -686,26 +701,13 @@ func getStringFromOptional(field nullable.Nullable[vo.OptionalString127]) string
|
||||
return ""
|
||||
}
|
||||
|
||||
// Delete deletes a recipient
|
||||
func (r *Recipient) DeleteByID(
|
||||
// deleteRecipientByID is the core deletion logic without permission checks or audit logging
|
||||
func (r *Recipient) deleteRecipientByID(
|
||||
ctx context.Context,
|
||||
session *model.Session,
|
||||
id *uuid.UUID,
|
||||
) error {
|
||||
ae := NewAuditEvent("Recipient.DeleteByID", session)
|
||||
ae.Details["id"] = id.String()
|
||||
// check permissions
|
||||
isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
|
||||
if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
|
||||
r.LogAuthError(err)
|
||||
return err
|
||||
}
|
||||
if !isAuthorized {
|
||||
r.AuditLogNotAuthorized(ae)
|
||||
return errs.ErrAuthorizationFailed
|
||||
}
|
||||
// remove recipient from all groups
|
||||
err = r.RecipientGroupRepository.RemoveRecipientByIDFromAllGroups(ctx, id)
|
||||
err := r.RecipientGroupRepository.RemoveRecipientByIDFromAllGroups(ctx, id)
|
||||
if err != nil {
|
||||
r.Logger.Errorw("failed to delete recipient - failed to remove recipient from all groups",
|
||||
"error", err,
|
||||
@@ -758,7 +760,34 @@ func (r *Recipient) DeleteByID(
|
||||
r.Logger.Errorw("failed to delete recipient - failed to delete recipient", "error", err)
|
||||
return err
|
||||
}
|
||||
r.AuditLogAuthorized(ae)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteByID deletes a recipient
|
||||
func (r *Recipient) DeleteByID(
|
||||
ctx context.Context,
|
||||
session *model.Session,
|
||||
id *uuid.UUID,
|
||||
) error {
|
||||
ae := NewAuditEvent("Recipient.DeleteByID", session)
|
||||
ae.Details["id"] = id.String()
|
||||
// check permissions
|
||||
isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
|
||||
if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
|
||||
r.LogAuthError(err)
|
||||
return err
|
||||
}
|
||||
if !isAuthorized {
|
||||
r.AuditLogNotAuthorized(ae)
|
||||
return errs.ErrAuthorizationFailed
|
||||
}
|
||||
|
||||
err = r.deleteRecipientByID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.AuditLogAuthorized(ae)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user