github.com/go-email-validator/go-email-validator@v0.0.0-20230409163946-b8b9e6a0552e/pkg/presentation/mailboxvalidator/dep.go (about)

     1  package mailboxvalidator
     2  
     3  import (
     4  	"github.com/emirpasic/gods/sets/hashset"
     5  	"github.com/go-email-validator/go-email-validator/pkg/ev"
     6  	"github.com/go-email-validator/go-email-validator/pkg/ev/contains"
     7  	"github.com/go-email-validator/go-email-validator/pkg/ev/evmail"
     8  	"github.com/go-email-validator/go-email-validator/pkg/presentation/converter"
     9  	"strconv"
    10  	"time"
    11  )
    12  
    13  //go:generate go run cmd/dep_test_generator/gen.go
    14  
    15  // Name of MailBoxValidator converter
    16  const Name converter.Name = "MailBoxValidator"
    17  
    18  // Error constants
    19  const (
    20  	MissingParameter        int32 = 100
    21  	MissingParameterMessage       = "Missing parameter."
    22  	UnknownErrorMessage           = "Unknown error."
    23  )
    24  
    25  // DepPresentation is representation of https://www.mailboxvalidator.com/
    26  type DepPresentation struct {
    27  	EmailAddress          string        `json:"email_address"`
    28  	Domain                string        `json:"domain"`
    29  	IsFree                EmptyBool     `json:"is_free"`
    30  	IsSyntax              EmptyBool     `json:"is_syntax"`
    31  	IsDomain              EmptyBool     `json:"is_domain"`
    32  	IsSMTP                EmptyBool     `json:"is_smtp"`
    33  	IsVerified            EmptyBool     `json:"is_verified"`
    34  	IsServerDown          EmptyBool     `json:"is_server_down"`
    35  	IsGreylisted          EmptyBool     `json:"is_greylisted"`
    36  	IsDisposable          EmptyBool     `json:"is_disposable"`
    37  	IsSuppressed          EmptyBool     `json:"is_suppressed"`
    38  	IsRole                EmptyBool     `json:"is_role"`
    39  	IsHighRisk            EmptyBool     `json:"is_high_risk"`
    40  	IsCatchall            EmptyBool     `json:"is_catchall"`
    41  	MailboxvalidatorScore float64       `json:"mailboxvalidator_score"`
    42  	TimeTaken             time.Duration `json:"time_taken"`
    43  	Status                EmptyBool     `json:"status"`
    44  	CreditsAvailable      uint32        `json:"credits_available"`
    45  	ErrorCode             string        `json:"error_code"`
    46  	ErrorMessage          string        `json:"error_message"`
    47  }
    48  
    49  // FuncCalculateScore is a interface for calculation score function
    50  type FuncCalculateScore func(presentation DepPresentation) float64
    51  
    52  // NewDepConverterDefault is the default constructor
    53  func NewDepConverterDefault() DepConverter {
    54  	return NewDepConverter(CalculateScore)
    55  }
    56  
    57  // NewDepConverter is the constructor
    58  func NewDepConverter(calculateScore FuncCalculateScore) DepConverter {
    59  	return DepConverter{calculateScore}
    60  }
    61  
    62  // DepConverter is the converter for https://www.mailboxvalidator.com/
    63  type DepConverter struct {
    64  	calculateScore FuncCalculateScore
    65  }
    66  
    67  // Can ev.ValidationResult be converted in DepConverter
    68  func (DepConverter) Can(_ evmail.Address, result ev.ValidationResult, opts converter.Options) bool {
    69  	return opts.ExecutedTime() != 0 && result.ValidatorName() == ev.DepValidatorName
    70  }
    71  
    72  var depPresentationError = DepPresentation{
    73  	ErrorCode:        strconv.Itoa(int(MissingParameter)),
    74  	CreditsAvailable: ^uint32(0),
    75  }
    76  
    77  func getBlankError() DepPresentation {
    78  	return depPresentationError
    79  }
    80  
    81  // Convert ev.ValidationResult in mailboxvalidator presentation
    82  func (d DepConverter) Convert(email evmail.Address, resultInterface ev.ValidationResult, opts converter.Options) (result interface{}) {
    83  	defer func() {
    84  		if r := recover(); r != nil {
    85  			depPresentation := getBlankError()
    86  			depPresentation.ErrorMessage = UnknownErrorMessage
    87  
    88  			result = depPresentation
    89  		}
    90  	}()
    91  	var depPresentation DepPresentation
    92  	if len(email.String()) == 0 {
    93  		depPresentation := getBlankError()
    94  		depPresentation.ErrorMessage = MissingParameterMessage
    95  
    96  		return depPresentation
    97  	}
    98  
    99  	depResult := resultInterface.(ev.DepValidationResult)
   100  	validationResults := depResult.GetResults()
   101  
   102  	smtpPresentation := converter.NewSMTPConverter().Convert(email, validationResults[ev.SMTPValidatorName], nil).(converter.SMTPPresentation)
   103  
   104  	isFree := !validationResults[ev.FreeValidatorName].IsValid()
   105  	isSyntax := validationResults[ev.SyntaxValidatorName].IsValid()
   106  	depPresentation = DepPresentation{
   107  		EmailAddress:     email.String(),
   108  		Domain:           email.Domain(),
   109  		IsFree:           NewEmptyBool(isFree),
   110  		IsSyntax:         NewEmptyBool(isSyntax),
   111  		IsDomain:         NewEmptyBool(validationResults[ev.MXValidatorName].IsValid()),
   112  		IsSMTP:           NewEmptyBool(smtpPresentation.CanConnectSMTP),
   113  		IsVerified:       NewEmptyBool(smtpPresentation.IsDeliverable),
   114  		IsServerDown:     NewEmptyBool(isSyntax && !smtpPresentation.CanConnectSMTP),
   115  		IsGreylisted:     NewEmptyBool(smtpPresentation.IsGreyListed),
   116  		IsDisposable:     NewEmptyBool(!validationResults[ev.DisposableValidatorName].IsValid()),
   117  		IsSuppressed:     NewEmptyBool(!validationResults[ev.BlackListEmailsValidatorName].IsValid()), // TODO find more examples example@example.com
   118  		IsRole:           NewEmptyBool(!validationResults[ev.RoleValidatorName].IsValid()),
   119  		IsHighRisk:       NewEmptyBool(!validationResults[ev.BanWordsUsernameValidatorName].IsValid()), // TODO find more words
   120  		IsCatchall:       NewEmptyBool(smtpPresentation.IsCatchAll),
   121  		TimeTaken:        opts.ExecutedTime(),
   122  		CreditsAvailable: ^uint32(0),
   123  	}
   124  
   125  	depPresentation.MailboxvalidatorScore = d.calculateScore(depPresentation)
   126  	depPresentation.Status = NewEmptyBool(depPresentation.MailboxvalidatorScore >= 0.5)
   127  	return depPresentation
   128  }
   129  
   130  // NewDepValidator returns the mailboxvalidator validator
   131  func NewDepValidator(smtpValidator ev.Validator) ev.Validator {
   132  	builder := ev.NewDepBuilder(nil)
   133  	if smtpValidator == nil {
   134  		smtpValidator = builder.Get(ev.SMTPValidatorName)
   135  	}
   136  
   137  	return ev.NewDepBuilder(nil).Set(
   138  		ev.BlackListEmailsValidatorName,
   139  		ev.NewBlackListEmailsValidator(contains.NewSet(hashset.New(
   140  			"example@example.com", "localhost@localhost",
   141  		))),
   142  	).Set(
   143  		ev.BanWordsUsernameValidatorName,
   144  		ev.NewBanWordsUsername(contains.NewInStringsFromArray([]string{"test"})),
   145  	).Set(
   146  		ev.FreeValidatorName,
   147  		ev.FreeDefaultValidator(),
   148  	).Set(ev.SMTPValidatorName, smtpValidator).Build()
   149  }