Files
phishingclub/backend/database/campaign.go
T
Ronni Skansing c4ed8cfeeb Late scheduling
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
2026-04-02 10:55:50 +02:00

97 lines
3.4 KiB
Go

package database
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
const (
CAMPAIGN_TABLE = "campaigns"
)
// Campaign is gorm data model
type Campaign struct {
ID *uuid.UUID `gorm:"primary_key;not null;unique;type:uuid"`
CreatedAt *time.Time `gorm:"not null;index;"`
UpdatedAt *time.Time `gorm:"not null;index;"`
CloseAt *time.Time `gorm:"index;"`
ClosedAt *time.Time `gorm:"index;"`
AnonymizeAt *time.Time `gorm:"index;"`
AnonymizedAt *time.Time `gorm:"index;"`
SortField string `gorm:";"`
SortOrder string `gorm:";"` // 'asc,desc,random'
SendStartAt *time.Time `gorm:"index;"`
SendEndAt *time.Time `gorm:"index;"`
// ScheduleAt is set when the campaign uses late-scheduling.
// the task runner will call schedule() when now >= ScheduleAt.
// null means the campaign was scheduled immediately at creation.
ScheduleAt *time.Time `gorm:"index;"`
// JitterMin and JitterMax are persisted only when ScheduleAt is set (late-scheduling).
// They are cleared after the campaign is scheduled by the task runner.
// For immediately-scheduled campaigns these columns remain null.
JitterMin *int `gorm:""`
JitterMax *int `gorm:""`
// ConstraintWeekDays is a binary format.
// 0b00000001 = 1 = sunday
// 0b00000010 = 2 = monday
// 0b00000100 = 4 = tuesday
// 0b00001000 = 8 = ...
// 0b00010000 = 16 =
// 0b00100000 = 32 =
// 0b01000000 = 64 =
ConstraintWeekDays *int `gorm:";"`
// hh:mm
ConstraintStartTime *string `gorm:"index;"`
// hh:mm
ConstraintEndTime *string `gorm:"index;"`
SaveSubmittedData bool `gorm:"not null;default:false"`
SaveBrowserMetadata bool `gorm:"not null;default:false"`
IsAnonymous bool `gorm:"not null;default:false"`
IsTest bool `gorm:"not null;default:false"`
Obfuscate bool `gorm:"not null;default:false"`
// deprecated: webhook settings moved to campaign_webhooks junction table
// kept for backward compatibility during migration
WebhookIncludeData string `gorm:"not null;default:'full'"`
WebhookEvents int `gorm:"not null;default:0"`
// has one
CampaignTemplateID *uuid.UUID `gorm:"index;type:uuid;"`
CampaignTemplate *CampaignTemplate
// can has one
CompanyID *uuid.UUID `gorm:"index;type:uuid;index;uniqueIndex:idx_campaigns_unique_name_and_company_id;"`
Company *Company
DenyPageID *uuid.UUID `gorm:"type:uuid;index;"`
DenyPage *Page `gorm:"foreignKey:DenyPageID;references:ID"`
EvasionPageID *uuid.UUID `gorm:"type:uuid;index;"`
EvasionPage *Page `gorm:"foreignKey:EvasionPageID;references:ID"`
// NotableEventID notable event for this campaign
NotableEvent *Event `gorm:"foreignKey:NotableEventID;references:ID"`
NotableEventID *uuid.UUID `gorm:"type:uuid;index"`
// deprecated: kept for backward compatibility during migration
WebhookID *uuid.UUID `gorm:"type:uuid;index;"`
// has many-to-many
RecipientGroups []*RecipientGroup `gorm:"many2many:campaign_recipient_groups"`
AllowDeny []*AllowDeny `gorm:"many2many:campaign_allow_denies"`
Webhooks []*Webhook `gorm:"many2many:campaign_webhooks"`
Name string `gorm:"not null;uniqueIndex:idx_campaigns_unique_name_and_company_id"`
}
func (c *Campaign) Migrate(db *gorm.DB) error {
// SQLITE
// ensure name + company id is unique
return UniqueIndexNameAndNullCompanyID(db, "campaigns")
}
func (Campaign) TableName() string {
return CAMPAIGN_TABLE
}