Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * sendEmail
- * Function mapped to Laravel route. Defines variable arrays and calls Email Class executeEmail.
- *
- * @param Request $request Request object passed via AJAX from client.
- */
- public function sendEmail(Request $request) {
- $projectName = $request['projectName'];
- $projectId = intval($projectName,strpos($projectName,'_'));
- $projectName = substr($projectName,0,strpos($projectName,'_')-1);
- $period = 4;
- try {
- $templateConfig = new TemplateConfiguration(
- array(
- 'templateName'=>$request['emailTemplate'],
- 'companyName'=>$request['companyName'],
- 'projectName'=>$projectName,
- 'projectId'=>$projectId
- )
- );
- $emailConfig = new EmailConfiguration(
- array(
- 'host'=>$request['hostName'],
- 'port'=>$request['port'],
- 'authUsername'=>$request['username'],
- 'authPassword'=>$request['password'],
- 'fromEmail'=>$request['fromEmail'],
- 'subject'=>$request['subject']
- )
- );
- Email::executeEmail($emailConfig,$templateConfig,$period);
- } catch(ConfigurationException $ce) {
- } catch(EmailException $ee) {
- }
- }
- private $host;
- private $port;
- private $authUsername;
- private $authPassword;
- private $fromEmail;
- private $subject;
- private $usersIterator;
- /**
- * EmailConfiguration constructor.
- * @param $emailSettings
- */
- public function __construct($emailSettings) {
- try {
- if($this->areSettingsValid($emailSettings)) {
- $this->host = $emailSettings['host'];
- $this->port = $emailSettings['port'];
- $this->authUsername = $emailSettings['authUsername'];
- $this->authPassword = $emailSettings['authPassword'];
- $this->fromEmail = $emailSettings['fromEmail'];
- $this->subject = $emailSettings['subject'];
- try {
- $db = new DBManager();
- $sql = "SELECT * FROM gaig_users.users;";
- $users = $db->query($sql,array(),array('PDO::ATTR_CURSOR'),array('PDO::CURSOR_SCROLL'));
- $this->usersIterator = new PDOIterator($users);
- } catch(PDOException $pdoe) {
- DBManager::logConnectError(__CLASS__,__FUNCTION__,$pdoe->getMessage(),$pdoe->getTrace());
- throw new ConfigurationException('Failed to connect to database.',0,$pdoe);
- } catch(QueryException $qe) {
- DBManager::logQueryError(__CLASS__,__FUNCTION__,$qe);
- throw new ConfigurationException('Failed to query users from database.',0,$qe);
- }
- }
- } catch(OutOfBoundsException $oobe) {
- throw new ConfigurationException('Invalid email setting(s).',0,$oobe);
- } catch(InvalidArgumentException $iae) {
- throw new ConfigurationException('Invalid email setting(s).',0,$iae);
- }
- }
- /**
- * @param $emailSettings
- * @return bool
- */
- private function areSettingsValid($emailSettings) {
- $message = '';
- if(empty($emailSettings)) {
- throw new OutOfBoundsException('No settings specified.');
- }
- if(!is_array($emailSettings)) {
- throw new OutOfBoundsException('Expected array, received ' . get_class($emailSettings) . ' Object');
- }
- if(is_null($emailSettings['host'])) {
- $message .= 'Host value cannot be null.' . PHP_EOL;
- }
- if(is_null($emailSettings['port'])) {
- $message .= 'Port value cannot be null.' . PHP_EOL;
- }
- if(is_null($emailSettings['authUsername'])) {
- $message .= 'Authenticating username value cannot be null.' . PHP_EOL;
- }
- if(is_null($emailSettings['authPassword'])) {
- $message .= 'Authenticating password value cannot be null.' . PHP_EOL;
- }
- if(is_null($emailSettings['fromEmail'])) {
- $message .= 'From email address value cannot be null.' . PHP_EOL;
- }
- if(is_null($emailSettings['subject'])) {
- $message .= 'Subject value cannot be null.' . PHP_EOL;
- }
- if(!empty($message)) {
- throw new OutOfBoundsException($message);
- }
- if($this->isValidDomainName($emailSettings['host'])) {
- if(!filter_var($emailSettings['port'],FILTER_VALIDATE_INT)) {
- $message .= 'Port is not a valid integer. Value provided: ' . var_export(['port'],true) . PHP_EOL;
- }
- if(!filter_var($emailSettings['fromEmail'],FILTER_VALIDATE_EMAIL)) {
- $message .= 'From Email is not a valid email address. Value provided: ' . var_export($emailSettings['fromEmail'],true) . PHP_EOL;
- }
- } else {
- if(filter_var($emailSettings['host'],FILTER_VALIDATE_IP)) {
- if(!filter_var($emailSettings['port'],FILTER_VALIDATE_INT)) {
- $message .= 'Port is not a valid integer. Value provided: ' . var_export(['port'],true) . PHP_EOL;
- }
- if(!filter_var($emailSettings['fromEmail'],FILTER_VALIDATE_EMAIL)) {
- $message .= 'From Email is not a valid email address. Value provided: ' . var_export($emailSettings['fromEmail'],true) . PHP_EOL;
- }
- } else {
- $message = 'Host is not a valid host name or IP address. Value provided: ' . var_export($emailSettings['host'],true) . PHP_EOL;
- }
- }
- if(!empty($message)) {
- throw new InvalidArgumentException($message);
- }
- return true;
- }
- /**
- * @param $domainName
- * @return int
- */
- private function isValidDomainName($domainName) {
- $pattern = ';(?:https?://)?(?:[a-zA-z0-9]+?.(?:com|net|org|gov|edu|co.uk));';
- return (preg_match($pattern, $domainName));
- }
- private $template;
- private $templatePrefix;
- private $companyName;
- private $projectName;
- private $projectId;
- /**
- * TemplateConfiguration constructor.
- * @param $templateSettings
- */
- public function __construct($templateSettings) {
- try {
- if($this->areSettingsValid($templateSettings)) {
- $this->checkFileExist($templateSettings);
- }
- } catch(FileNotFoundException $fnfe) {
- throw new ConfigurationException('Invalid template name.',0,$fnfe);
- } catch(OutOfBoundsException $oobe) {
- throw new ConfigurationException('Invalid template setting(s).',0,$oobe);
- }
- }
- /**
- * @param $templateSettings
- */
- private function checkFileExist($templateSettings) {
- $path = '../resources/views/emails';
- $templateName = $templateSettings['templateName'];
- if(file_exists("$path/phishing/$templateName")) {
- $this->templatePrefix = 'emails.phishing.';
- $this->setSettings($templateSettings);
- } else if(file_exists("$path/edu/$templateName")) {
- $this->templatePrefix = 'emails.edu.';
- $this->setSettings($templateSettings);
- } else {
- throw new FileNotFoundException("Failed to find template: $templateName");
- }
- }
- /**
- * @param $templateSettings
- * @return bool
- */
- private function areSettingsValid($templateSettings) {
- $message = '';
- if(empty($templateSettings)) {
- throw new OutOfBoundsException('No settings specified.');
- }
- if(!is_array($templateSettings)) {
- throw new OutOfBoundsException('Expected array, received ' . get_class($templateSettings) . ' Object');
- }
- if(is_null($templateSettings['templateName'])) {
- $message .= 'Template Name value cannot be null.' . PHP_EOL;
- }
- if(is_null($templateSettings['companyName'])) {
- $message .= 'Company Name value cannot be null.' . PHP_EOL;
- }
- if(is_null($templateSettings['projectName'])) {
- $message .= 'Project Name value cannot be null.' . PHP_EOL;
- }
- if(is_null($templateSettings['projectId'])) {
- $message .= 'Project ID value cannot be null.' . PHP_EOL;
- }
- if(!empty($message)) {
- throw new OutOfBoundsException($message);
- }
- return true;
- }
- /**
- * @param $templateSettings
- */
- private function setSettings($templateSettings) {
- $this->template = $templateSettings['templateName'];
- $this->companyName = $templateSettings['companyName'];
- $this->projectName = $templateSettings['projectName'];
- $this->projectId = $templateSettings['projectId'];
- }
- /**
- * executeEmail
- * Public-facing method to send an email to a database of users if they are a valid recipient.
- *
- * @param array $emailSettings Host, port, username, and password variables for the mail server
- * @param array $template Email Template, Template Type, Template Target Type for user validation
- * string Email Template Path to the blade.php template file from the views directory
- * string Template Type Specifies whether the email is an Advanced (adv) or Basic (bsc) scam
- * string Template Target Type Specifies whether the email is a Targeted (T) or Generic (G) scam
- * @param array $params Period, Project Name, Project ID, From Email Address, Company Name, Subject
- * int Period Number of weeks to check back for recipient validation
- * string Project Name Name of this project
- * int Project Id ID of this project
- * string From Email Address Email to be sent from
- * string Company Name Name of company sponsoring this awareness test *optional*
- * string Subject Subject of email *optional*
- * @throws FailureException Thrown from sendEmail() if mail fails to be given to mail server
- */
- /**
- * @param appEmailConfiguration $emailConfig
- * @param TemplateConfiguration $templateConfig
- * @param $period
- * @throws EmailException
- */
- public static function executeEmail(EmailConfiguration $emailConfig, TemplateConfiguration $templateConfig, $period) {
- try {
- foreach($emailConfig->getUsersIterator() as $user) {
- if(self::validateUser($templateConfig->getTemplateComplexityType(),
- $templateConfig->getTemplateTargetType(), $user, $period))
- {
- $urlId = self::getUrlId($user,$templateConfig->getProjectId());
- $headers = array(
- 'companyName'=>$templateConfig->getCompanyName(),
- 'projectName'=>$templateConfig->getProjectName(),
- 'projectId'=>$templateConfig->getProjectId(),
- 'lastName'=>$user['USR_LastName'],
- 'username'=>$user['USR_Username'],
- 'urlId'=>$urlId
- );
- self::sendEmail($templateConfig->getTemplate(),$headers,$user['USR_Email'],
- $emailConfig->getFromEmail(),$emailConfig->getSubject());
- $projects = array($templateConfig->getProjectName(),$user['USR_ProjectMostRecent'],$user['USR_ProjectPrevious']);
- self::updateUserProjects($projects,$user);
- }
- }
- } catch(PDOException $pdoe) {
- throw new EmailException('Failed to connect to database.',0,$pdoe);
- } catch(QueryException $qe) {
- throw new EmailException('Failed to query users from database.',0,$qe);
- } catch(FailureException $fe) {
- throw new EmailException('Failed to send email.',0,$fe);
- }
- }
- /**
- * validateUser
- * Function checks if the specified user has not received a test within the specified duration,
- * if the template type is the same for the last two project participants, if the template target
- * is the same for last three project participants, or if the last project is identical to the new project.
- *
- * @param string $templateType Specifies whether the email is an Advanced (adv) or Basic (bsc) scam
- * @param string $templateTarget Specifies whether the email is a Targeted (T) or Generic (G) scam
- * @param array $user Associative Array containing the fields associated to the user
- * @param int $period Number of weeks to check back for recipient validation
- * @return bool
- */
- private function validateUser($templateType,$templateTarget,$user,$period) {
- $db = new DBManager();
- $date = date('Y-m-d',strtotime('-' . $period . 'weeks')) . '00:00:00';
- $sql = "SELECT max(SML_AccessTimestamp) as 'timestamp_check' from gaig_users.sent_email where SML_UserId = ? and SML_ProjectName = ?;";
- $bindings = array($user['USR_UserId'],$user['USR_ProjectMostRecent']);
- $timestampData = $db->query($sql,$bindings);
- $result = $timestampData->fetch(PDO::FETCH_ASSOC);
- if(!filter_var($user['USR_Email'],FILTER_VALIDATE_EMAIL)) {
- $this->badEmailAddressWarning(['USR_Username'] . ' has a bad email address. email=' . $user['USR_Email']);
- return false;
- }
- if($result['timestamp_check'] <= $date) {
- return true;
- } else if($templateType == substr($user['USR_ProjectMostRecent'],-5,3) &&
- $templateType == substr($user['USR_ProjectPrevious'],-5,3)) {
- return false;
- } else if($templateTarget == substr($user['USR_ProjectMostRecent'],-2,1) &&
- $templateTarget == substr($user['USR_ProjectPrevious'],-2,1) &&
- $templateTarget == substr($user['USR_ProjectLast'],-2,1)) {
- return false;
- } else if($templateType.$templateTarget ==
- substr($user['USR_ProjectMostRecent'],strpos($user['USR_ProjectMostRecent'],'-')+1,4)) {
- return false;
- }
- return true;
- }
- /**
- * getUrlId
- * Generates or retrieves the UniqueURLId of the passed user.
- *
- * @param array $user User array extracted from PDOStatement
- * @return string
- */
- private function getUrlId($user,$projectId) {
- $db = new DBManager();
- if(!is_null($user['USR_UniqueURLId'])) {
- $urlId = $user['USR_UniqueURLId'];
- } else {
- $urlId = $this->random_str(15) . $projectId;
- $sql = "UPDATE gaig_users.users SET USR_UniqueURLId=? WHERE USR_UserId=?;";
- $bindings = array($urlId,$user['USR_UserId']);
- $db->query($sql,$bindings);
- }
- return $urlId;
- }
- /**
- * updateUserProjects
- * Updates the user with the newest project and rotates the old projects down one.
- *
- * @param array $projects Most Recent Project, Previous Project, Oldest Project
- * @param array $user User array extracted from PDOStatement
- */
- private function updateUserProjects($projects,$user) {
- $db = new DBManager();
- $sql = "UPDATE gaig_users.users SET USR_ProjectMostRecent=?, USR_ProjectPrevious=?,
- USR_ProjectLast=? WHERE USR_Username=?;";
- $bindings = array($projects[0],$projects[1],$projects[2],$user['USR_Username']);
- $db->query($sql,$bindings);
- }
- /**
- * sendEmail
- * Iterates through the PDO Result Set of users. Calls validRecipientAlgo to validate user. Sends email if
- * valid and updates user if valid.
- * @param array $params Required parameters to pass to the email template
- * @param string $from Email to be sent from
- * @param string $subject Subject of email
- * @throws FatalErrorException
- */
- private function sendEmail($template, $headers, $to, $from, $subject) {
- if(!Mail::send(['html' => $template],$headers, function($m) use ($from, $to, $subject) {
- $m->from($from);
- $m->to($to)->subject($subject);
- })) {
- throw new FailureException('Email failed to send to ' . $to . ' from ' . $from);
- }
- }
- /**
- * random_str
- * Generates a random string.
- *
- * @param int $length Length of string to be returned
- * @param string $keyspace Allowed characters to be used in string
- * @return string
- */
- private function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
- {
- $str = '';
- $max = mb_strlen($keyspace, '8bit') - 1;
- for ($i = 0; $i < $length; ++$i) {
- $str .= $keyspace[random_int(0, $max)];
- }
- return $str;
- }
- /**
- * badEmailAddressWarning
- * Logs error when a bad email address is found associated with a user
- *
- * @param string $message Error message to be logged
- */
- private function badEmailAddressWarning($message) {
- $path = '../storage/logs/badEmailAddress' . date('m-d-Y') . '.log';
- if(!file_exists($path)) {
- $file = fopen($path,'w');
- fclose($file);
- }
- error_log($message,3,$path);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement