mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-02-12 16:12:44 +00:00
282 lines
8.3 KiB
Go
282 lines
8.3 KiB
Go
package model
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/go-errors/errors"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/oapi-codegen/nullable"
|
|
"github.com/phishingclub/phishingclub/errs"
|
|
"github.com/phishingclub/phishingclub/validate"
|
|
"github.com/phishingclub/phishingclub/vo"
|
|
)
|
|
|
|
// CampaignTemplate is a campaign template
|
|
type CampaignTemplate struct {
|
|
ID nullable.Nullable[uuid.UUID] `json:"id"`
|
|
CreatedAt *time.Time `json:"createdAt"`
|
|
UpdatedAt *time.Time `json:"updatedAt"`
|
|
|
|
Name nullable.Nullable[vo.String64] `json:"name"`
|
|
|
|
DomainID nullable.Nullable[uuid.UUID] `json:"domainID"`
|
|
Domain *Domain `json:"domain"`
|
|
|
|
BeforeLandingPageID nullable.Nullable[uuid.UUID] `json:"beforeLandingPageID"`
|
|
BeforeLandingePage *Page `json:"beforeLandingPage"`
|
|
|
|
// before landing page can also be a proxy
|
|
BeforeLandingProxyID nullable.Nullable[uuid.UUID] `json:"beforeLandingProxyID"`
|
|
BeforeLandingProxy *Proxy `json:"beforeLandingProxy"`
|
|
|
|
LandingPageID nullable.Nullable[uuid.UUID] `json:"landingPageID"`
|
|
LandingPage *Page `json:"landingPage"`
|
|
|
|
// landing page can also be a proxy
|
|
LandingProxyID nullable.Nullable[uuid.UUID] `json:"landingProxyID"`
|
|
LandingProxy *Proxy `json:"landingProxy"`
|
|
|
|
AfterLandingPageID nullable.Nullable[uuid.UUID] `json:"afterLandingPageID"`
|
|
AfterLandingPage *Page `json:"afterLandingPage"`
|
|
|
|
// after landing page can also be a proxy
|
|
AfterLandingProxyID nullable.Nullable[uuid.UUID] `json:"afterLandingProxyID"`
|
|
AfterLandingProxy *Proxy `json:"afterLandingProxy"`
|
|
|
|
AfterLandingPageRedirectURL nullable.Nullable[vo.OptionalString255] `json:"afterLandingPageRedirectURL"`
|
|
|
|
URLIdentifierID nullable.Nullable[*uuid.UUID] `json:"urlIdentifierID"`
|
|
URLIdentifier *Identifier `json:"urlIdentifier"`
|
|
|
|
StateIdentifierID nullable.Nullable[*uuid.UUID] `json:"stateIdentifierID"`
|
|
StateIdentifier *Identifier `json:"stateIdentifier"`
|
|
|
|
URLPath nullable.Nullable[vo.URLPath] `json:"urlPath"`
|
|
|
|
EmailID nullable.Nullable[uuid.UUID] `json:"emailID"`
|
|
Email *Email `json:"email"`
|
|
|
|
SMTPConfigurationID nullable.Nullable[uuid.UUID] `json:"smtpConfigurationID"`
|
|
SMTPConfiguration *SMTPConfiguration `json:"smtpConfiguration"`
|
|
|
|
APISenderID nullable.Nullable[uuid.UUID] `json:"apiSenderID"`
|
|
APISender *APISender `json:"apiSender"`
|
|
|
|
CompanyID nullable.Nullable[uuid.UUID] `json:"companyID"`
|
|
Company *Company `json:"company"`
|
|
|
|
IsUsable nullable.Nullable[bool] `json:"isUsable"`
|
|
}
|
|
|
|
// Validate checks if the campaign template has a valid state
|
|
func (c *CampaignTemplate) Validate() error {
|
|
if err := validate.NullableFieldRequired("name", c.Name); err != nil {
|
|
return err
|
|
}
|
|
if err := validate.NullableFieldRequired("urlIdentifierID", c.URLIdentifierID); err != nil {
|
|
return err
|
|
}
|
|
if err := validate.NullableFieldRequired("stateIdentifierID", c.StateIdentifierID); err != nil {
|
|
return err
|
|
}
|
|
if a, err := c.URLIdentifierID.Get(); err == nil {
|
|
if b, err := c.StateIdentifierID.Get(); err == nil {
|
|
if a.String() == b.String() {
|
|
return errs.NewValidationError(
|
|
errors.New("URL and state identifier can not be the same"),
|
|
)
|
|
}
|
|
}
|
|
}
|
|
// URLPath is optional, no validation needed
|
|
|
|
// validate that only one type is set per stage
|
|
// before landing page: can have neither (optional), or one type, but not both
|
|
_, errBeforePage := c.BeforeLandingPageID.Get()
|
|
_, errBeforeProxy := c.BeforeLandingProxyID.Get()
|
|
if errBeforePage == nil && errBeforeProxy == nil {
|
|
return errs.NewValidationError(
|
|
errors.New("before landing page cannot be both a page and a proxy"),
|
|
)
|
|
}
|
|
|
|
// landing page: must have exactly one type (required)
|
|
_, errLandingPage := c.LandingPageID.Get()
|
|
_, errLandingProxy := c.LandingProxyID.Get()
|
|
if errLandingPage == nil && errLandingProxy == nil {
|
|
return errs.NewValidationError(
|
|
errors.New("landing page cannot be both a page and a proxy"),
|
|
)
|
|
|
|
}
|
|
if errLandingPage != nil && errLandingProxy != nil {
|
|
return errs.NewValidationError(
|
|
errors.New("landing page is required (must be either a page or a proxy)"),
|
|
)
|
|
}
|
|
|
|
// after landing page: can have neither (optional), or one type, but not both
|
|
_, errAfterPage := c.AfterLandingPageID.Get()
|
|
_, errAfterProxy := c.AfterLandingProxyID.Get()
|
|
if errAfterPage == nil && errAfterProxy == nil {
|
|
return errs.NewValidationError(
|
|
errors.New("after landing page cannot be both a page and a proxy"),
|
|
)
|
|
}
|
|
|
|
// validate that smtp configuration and api sender are mutually exclusive
|
|
_, errSMTP := c.SMTPConfigurationID.Get()
|
|
_, errAPISender := c.APISenderID.Get()
|
|
if errSMTP == nil && errAPISender == nil {
|
|
return errs.NewValidationError(
|
|
errors.New("smtp configuration and api sender cannot both be set"),
|
|
)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ToDBMap converts the fields that can be stored or updated to a map
|
|
// if the value is nullable and not set, it is not included
|
|
// if the value is nullable and set, it is included, if it is null, it is set to nil
|
|
func (c *CampaignTemplate) ToDBMap() map[string]any {
|
|
m := map[string]any{}
|
|
if c.Name.IsSpecified() {
|
|
m["name"] = nil
|
|
if name, err := c.Name.Get(); err == nil {
|
|
m["name"] = name.String()
|
|
}
|
|
}
|
|
if c.DomainID.IsSpecified() {
|
|
if c.DomainID.IsNull() {
|
|
m["domain_id"] = nil
|
|
} else {
|
|
m["domain_id"] = c.DomainID.MustGet()
|
|
}
|
|
}
|
|
|
|
if c.BeforeLandingPageID.IsSpecified() {
|
|
if c.BeforeLandingPageID.IsNull() {
|
|
m["before_landing_page_id"] = nil
|
|
} else {
|
|
m["before_landing_page_id"] = c.BeforeLandingPageID.MustGet()
|
|
}
|
|
}
|
|
|
|
if c.BeforeLandingProxyID.IsSpecified() {
|
|
if c.BeforeLandingProxyID.IsNull() {
|
|
m["before_landing_proxy_id"] = nil
|
|
} else {
|
|
m["before_landing_proxy_id"] = c.BeforeLandingProxyID.MustGet()
|
|
}
|
|
}
|
|
|
|
if c.LandingPageID.IsSpecified() {
|
|
if c.LandingPageID.IsNull() {
|
|
m["landing_page_id"] = nil
|
|
} else {
|
|
m["landing_page_id"] = c.LandingPageID.MustGet()
|
|
}
|
|
}
|
|
|
|
if c.LandingProxyID.IsSpecified() {
|
|
if c.LandingProxyID.IsNull() {
|
|
m["landing_proxy_id"] = nil
|
|
} else {
|
|
m["landing_proxy_id"] = c.LandingProxyID.MustGet()
|
|
}
|
|
}
|
|
|
|
if c.AfterLandingPageID.IsSpecified() {
|
|
if c.AfterLandingPageID.IsNull() {
|
|
m["after_landing_page_id"] = nil
|
|
} else {
|
|
m["after_landing_page_id"] = c.AfterLandingPageID.MustGet()
|
|
}
|
|
}
|
|
|
|
if c.AfterLandingProxyID.IsSpecified() {
|
|
if c.AfterLandingProxyID.IsNull() {
|
|
m["after_landing_proxy_id"] = nil
|
|
} else {
|
|
m["after_landing_proxy_id"] = c.AfterLandingProxyID.MustGet()
|
|
}
|
|
}
|
|
if c.AfterLandingPageRedirectURL.IsSpecified() {
|
|
if c.AfterLandingPageRedirectURL.IsNull() {
|
|
m["after_landing_page_redirect_url"] = ""
|
|
} else {
|
|
if v, err := c.AfterLandingPageRedirectURL.Get(); err == nil {
|
|
m["after_landing_page_redirect_url"] = v.String()
|
|
} else {
|
|
m["after_landing_page_redirect_url"] = ""
|
|
}
|
|
}
|
|
}
|
|
|
|
if c.EmailID.IsSpecified() {
|
|
if c.EmailID.IsNull() {
|
|
m["email_id"] = nil
|
|
} else {
|
|
m["email_id"] = c.EmailID.MustGet()
|
|
}
|
|
}
|
|
if c.SMTPConfigurationID.IsSpecified() {
|
|
if c.SMTPConfigurationID.IsNull() {
|
|
m["smtp_configuration_id"] = nil
|
|
} else {
|
|
m["smtp_configuration_id"] = c.SMTPConfigurationID.MustGet()
|
|
}
|
|
}
|
|
if c.APISenderID.IsSpecified() {
|
|
if c.APISenderID.IsNull() {
|
|
m["api_sender_id"] = nil
|
|
} else {
|
|
m["api_sender_id"] = c.APISenderID.MustGet()
|
|
}
|
|
}
|
|
|
|
if c.CompanyID.IsSpecified() {
|
|
if c.CompanyID.IsNull() {
|
|
m["company_id"] = nil
|
|
} else {
|
|
m["company_id"] = c.CompanyID.MustGet()
|
|
}
|
|
}
|
|
if v, err := c.URLIdentifierID.Get(); err == nil {
|
|
m["url_identifier_id"] = v
|
|
}
|
|
if v, err := c.StateIdentifierID.Get(); err == nil {
|
|
m["state_identifier_id"] = v
|
|
}
|
|
if c.URLPath.IsSpecified() {
|
|
if c.URLPath.IsNull() {
|
|
m["url_path"] = ""
|
|
} else {
|
|
if v, err := c.URLPath.Get(); err == nil {
|
|
m["url_path"] = v.String()
|
|
} else {
|
|
m["url_path"] = ""
|
|
}
|
|
}
|
|
}
|
|
|
|
_, errDomain := c.DomainID.Get()
|
|
_, errSMTP := c.SMTPConfigurationID.Get()
|
|
_, errAPISender := c.APISenderID.Get()
|
|
_, errEmail := c.EmailID.Get()
|
|
_, errLandingPage := c.LandingPageID.Get()
|
|
_, errLandingProxy := c.LandingProxyID.Get()
|
|
|
|
// landing page is required (either page or proxy)
|
|
hasLanding := errLandingPage == nil || errLandingProxy == nil
|
|
|
|
m["is_usable"] = errDomain == nil &&
|
|
errEmail == nil &&
|
|
hasLanding &&
|
|
(errSMTP == nil || errAPISender == nil)
|
|
|
|
return m
|
|
}
|