Skip to content

Commit

Permalink
Merge pull request #1173 from proditis/mail-related-improvements
Browse files Browse the repository at this point in the history
Mail related improvements
  • Loading branch information
proditis authored May 6, 2024
2 parents e8ccb9f + 8fd423c commit 3d23bea
Show file tree
Hide file tree
Showing 15 changed files with 476 additions and 494 deletions.
16 changes: 5 additions & 11 deletions backend/commands/PlayerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,24 +165,18 @@ public function actionMail($active=false, $email=false,$status=9)
$this->stdout("Mailing Registered users:\n", Console::BOLD);
}
$event_name=Sysconfig::findOne('event_name')->val;
$emailtpl=\app\modules\content\models\EmailTemplate::findOne(['name' => 'emailVerify']);
$subject=Yii::t('app', '{event_name} Account approved', ['event_name' => trim(Yii::$app->sys->event_name)]);

foreach($players as $player)
{
// Generate activation URL
$activationURL=sprintf("https://%s/verify-email?token=%s",\Yii::$app->sys->offense_domain, $player->verification_token);
$contentHtml = \app\components\BaseController::renderPhpContent("?>" . $emailtpl->html, ['user' => $player,'verifyLink'=>$activationURL]);
$contentTxt = \app\components\BaseController::renderPhpContent("?>" . $emailtpl->txt, ['user' => $player,'verifyLink'=>$activationURL]);

$this->stdout($player->email);
$numSend=Yii::$app
->mailer
->compose(
['html' => 'emailVerify-html', 'text' => 'emailVerify-text'],
['user' => $player,'verifyLink'=>$activationURL]
)
->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName])
->setBcc([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName])
->setTo([$player->email => $player->fullname])
->setSubject(trim(Yii::$app->sys->event_name). ' Account approved')
->send();
$numSend=intval($player->mail($subject,$contentHtml,$contentTxt));
$this->stdout($numSend ? " Ok\n" : "Not Ok\n");
}
}
Expand Down
2 changes: 1 addition & 1 deletion backend/components/BaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function init()
parent::init();
}

public function renderPhpContent($_content_, $_params_ = [])
public static function renderPhpContent($_content_, $_params_ = [])
{
$_obInitialLevel_ = ob_get_level();
ob_start();
Expand Down
55 changes: 17 additions & 38 deletions backend/components/Mailer.php
Original file line number Diff line number Diff line change
@@ -1,49 +1,28 @@
<?php

namespace app\components;

use Yii;

class Mailer extends \yii\symfonymailer\Mailer
{
public function init()
{
parent::init();

$this->useFileTransport=Yii::$app->sys->mail_useFileTransport;

$config['scheme']='smtp';
$config['options']['local_domain']=\Yii::$app->sys->offense_domain;

if(Yii::$app->sys->mail_host !== false)
{
$config['host']=Yii::$app->sys->mail_host;
}

if(Yii::$app->sys->mail_port !== false)
{
$config['port']=intval(Yii::$app->sys->mail_port);
}

if(Yii::$app->sys->mail_username !== false)
{
$config['username']=Yii::$app->sys->mail_username;
}

if(Yii::$app->sys->mail_password !== false)
{
$config['password']=Yii::$app->sys->mail_password;
}

if(Yii::$app->sys->mail_encryption !== false && trim(Yii::$app->sys->mail_encryption)!='')
{
$config['scheme']=Yii::$app->sys->mail_encryption;
}

if(Yii::$app->sys->mail_verify_peer !== false)
{
$this->ssl['verify_peer']=Yii::$app->sys->mail_verify_peer;
}
if(Yii::$app->sys->mail_verify_peer_name !== false)
{
$this->ssl['verify_peer_name']=Yii::$app->sys->mail_verify_peer_name;
$this->useFileTransport = (bool)Yii::$app->sys->mail_useFileTransport;
if (trim(\Yii::$app->sys->dsn)!=="") {
$config['dsn']=trim(\Yii::$app->sys->dsn);
} else {
$config['dsn'] = Yii::t('app', '{mail_encryption}://{mail_userpass}{mail_host}:{mail_port}?verify_peer={verify_peer}&local_domain={local_domain}&verify_peer_name={verify_peer_name}', [
'mail_encryption' => \Yii::$app->sys->mail_encryption ?? "smtp",
'mail_userpass' => (trim(\Yii::$app->sys->mail_username) != "" && trim(\Yii::$app->sys->mail_password) != "") ? trim(\Yii::$app->sys->mail_username) . ':' . trim(\Yii::$app->sys->mail_password) . '@' : '',
'mail_password' => \Yii::$app->sys->mail_password,
'mail_host' => \Yii::$app->sys->mail_host,
'mail_port' => \Yii::$app->sys->mail_port ?? "25",
'verify_peer' => intval(\Yii::$app->sys->verify_peer),
'local_domain' => \Yii::$app->sys->offense_domain,
'verify_peer_name' => intval(\Yii::$app->sys->verify_peer_name),
]);
}
$this->setTransport($config);
}
Expand Down
52 changes: 25 additions & 27 deletions backend/modules/frontend/actions/player/MailAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,21 @@ public function run(int $id, $baseURL = "https://echoctf.red/activate/")
private function rejectionMail($player)
{
try {
$this->sendMail(
$player,
'rejectVerify-html',
'rejectVerify-text',
Yii::t('app', '{event_name} Account rejected', ['event_name' => trim(Yii::$app->sys->event_name)])
);
\Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player rejection mail send.'));
$emailtpl=\app\modules\content\models\EmailTemplate::findOne(['name' => 'rejectVerify']);
$contentHtml = $this->controller->renderPhpContent("?>" . $emailtpl->html, ['user' => $player]);
$contentTxt = $this->controller->renderPhpContent("?>" . $emailtpl->txt, ['user' => $player]);
$subject=Yii::t('app', '{event_name} Account rejected', ['event_name' => trim(Yii::$app->sys->event_name)]);
if(!$player->mail($subject,$contentHtml,$contentTxt))
{
throw new \Exception('Could not send mail');
}

if (Yii::$app->sys->player_require_approval === true && $player->approval == 3) {
$player->updateAttributes(['approval' => 4]);
\Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player rejection mail send and approval status updated.'));
} else {
\Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player rejection mail send.'));
}
} catch (\Exception $e) {
\Yii::$app->getSession()->setFlash('error', Yii::t('app', 'Failed to mail rejection to player. {exception}', ['exception' => Html::encode($e->getMessage())]));
}
Expand All @@ -72,12 +80,16 @@ private function approvalMail($player)
{
try {
$activationURL = sprintf("https://%s/verify-email?token=%s", \Yii::$app->sys->offense_domain, $player->verification_token);
$this->sendMail(
$player,
'emailVerify-html',
'emailVerify-text',
Yii::t('app', '{event_name} Account approved', ['event_name' => trim(Yii::$app->sys->event_name)])
);
$emailtpl=\app\modules\content\models\EmailTemplate::findOne(['name' => 'emailVerify']);
$contentHtml = $this->controller->renderPhpContent("?>" . $emailtpl->html, ['user' => $player,'verifyLink'=>$activationURL]);
$contentTxt = $this->controller->renderPhpContent("?>" . $emailtpl->txt, ['user' => $player,'verifyLink'=>$activationURL]);
$subject=Yii::t('app', '{event_name} Account approved', ['event_name' => trim(Yii::$app->sys->event_name)]);

if(!$player->mail($subject,$contentHtml,$contentTxt))
{
throw new \Exception('Could not send mail');
}

if (Yii::$app->sys->player_require_approval === true && $player->approval == 1) {
$player->updateAttributes(['approval' => 2]);
\Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player activation mail send and approval status updated.'));
Expand All @@ -88,18 +100,4 @@ private function approvalMail($player)
\Yii::$app->getSession()->setFlash('error', Yii::t('app', 'Failed to mail player. {exception}', ['exception' => Html::encode($e->getMessage())]));
}
}

private function sendMail($player, $html, $text, $subject)
{
Yii::$app
->mailer
->compose(
['html' => $html, 'text' => $text],
['user' => $player]
)
->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName . ' robot'])
->setTo([$player->email => $player->fullname])
->setSubject($subject)
->send();
}
}
19 changes: 15 additions & 4 deletions backend/modules/frontend/models/Player.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,28 @@ public function saveWithSsl()
return false;
}

public function mail($content, $subject)
/**
* Send mail to player with
* @param string $subject
* @param string $html
* @param string $txt
* @param array $headers
* @return bool
*/
public function mail($subject, $html, $txt,$headers=[])
{
// Get mailer
try
{
\Yii::$app->mailer->compose()
$message=\Yii::$app->mailer->compose()
->setFrom([\app\modules\settings\models\Sysconfig::findOne('mail_from')->val => \app\modules\settings\models\Sysconfig::findOne('mail_fromName')->val])
->setTo([$this->email=>$this->username])
->setSubject($subject)
->setTextBody($content)
->send();
->setTextBody($txt)
->setHtmlBody($html);
foreach($headers as $entry)
$message->addHeader($entry[0],$entry[1]);
$message->send();
if (Yii::$app instanceof \yii\web\Application)
\Yii::$app->session->setFlash('success', Yii::t('app',"The user has been mailed."));
else {
Expand Down
9 changes: 7 additions & 2 deletions backend/modules/settings/models/ConfigureForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class ConfigureForm extends Model
public $profile_twitch;
public $profile_youtube;
public $guest_visible_leaderboards;
public $dsn;

public $dn_countryName;
public $dn_stateOrProvinceName;
Expand Down Expand Up @@ -164,7 +165,8 @@ class ConfigureForm extends Model
'profile_htb',
'profile_twitch',
'profile_youtube',
'guest_visible_leaderboards'
'guest_visible_leaderboards',
'dsn'
];

/**
Expand Down Expand Up @@ -203,6 +205,7 @@ public function rules()
'stripe_apiKey',
'stripe_publicApiKey',
'stripe_webhookSecret',
'dsn'
], 'string'],
[['offense_registered_tag',
'defense_registered_tag',
Expand Down Expand Up @@ -233,7 +236,8 @@ public function rules()
'dn_localityName',
'dn_organizationName',
'dn_organizationalUnitName',
'pf_state_limits'
'pf_state_limits',
'dsn'
], 'trim'],
// required fields
[['teams',
Expand Down Expand Up @@ -380,6 +384,7 @@ public function attributeLabels()
'profile_twitch'=>'Twitch',
'profile_youtube'=>'Youtube',
'guest_visible_leaderboards'=>'Guest visible leaderboards',
'dsn'=>'Mail DSN'
];
}

Expand Down
11 changes: 3 additions & 8 deletions backend/modules/settings/views/sysconfig/configure.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,7 @@
<div class="col-sm-3"><?= $form->field($model, 'mail_useFileTransport')->checkbox()->hint('Activate the use of file transport (save mails in files)?') ?></div>
<div class="col-sm-3"><?= $form->field($model, 'mail_from')->textInput(['maxlength' => true])->hint('Mail From (eg. [email protected])') ?></div>
<div class="col-sm-3"><?= $form->field($model, 'mail_fromName')->textInput(['maxlength' => true])->hint('Mail From Name (eg. echoCTF RED)') ?></div>
<div class="col-sm-3"><?= $form->field($model, 'mail_host')->textInput(['maxlength' => true])->hint('Mail host (eg. smtp-relay.gmail.com)') ?></div>
<div class="col-sm-3"><?= $form->field($model, 'mail_port')->textInput(['maxlength' => true])->hint('Mail port (eg. 25)') ?></div>
<div class="col-sm-3"><?= $form->field($model, 'mail_username')->textInput(['maxlength' => true])->hint('Mail server username') ?></div>
<div class="col-sm-3"><?= $form->field($model, 'mail_password')->textInput(['maxlength' => true])->hint('Mail server password') ?></div>
<div class="col-sm-3"><?= $form->field($model, 'mail_encryption')->textInput(['maxlength' => true])->hint('Mail server encryption (ssl,tls,none)') ?></div>
<div class="col-sm-3"><?= $form->field($model, 'mail_verify_peer')->checkbox()->hint('Verify peer sertificate?') ?></div>
<div class="col-sm-3"><?= $form->field($model, 'mail_verify_peer_name')->checkbox()->hint('Verify peer name from certificate?') ?></div>
<div class="col-sm-6"><?= $form->field($model, 'dsn')->textInput(['maxlength' => true,'placeholder'=>'smtp://username:[email protected]:25?local_domain=blah'])->hint('Mail DSN see '.Html::a('Symphony Mailer','https://symfony.com/doc/current/mailer.html',['title'=>'Symphony Mailer Reference','target'=>'_blank'])) ?></div>
</div>
<hr/>

Expand Down Expand Up @@ -150,7 +144,8 @@
</div>
<hr/>

<h4>VPN Certificate Settings <span><small>If you change these values you will have to regenerate your ca keys and player certificates again.</small></span></h4>
<h4>VPN Certificate Settings</h4>
<small class="text-danger">If you change these values you will have to regenerate your CA keys and player certificates.</small>

<div class="row form-group">
<div class="col-sm-2"><?= $form->field($model, 'dn_countryName')->textInput(['maxlength' => true])->input('text', ['placeholder' => ""])->hint('') ?></div>
Expand Down
6 changes: 6 additions & 0 deletions docs/Sysconfig-Keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,16 @@
## mail configuration
* `mail_from` Email address used to send registration and password reset mails from
* `mail_fromName` The name appeared on the email send for registration and password resets
* `dsn` A symphony mailer compatible DSN

Or instead if not DSN then use the following
* `mail_host` The mail server host to send mails through
* `mail_port` The mail server port to connect
* `mail_username` The username to authenticate to the mail server
* `mail_password` The password to authenticate to the mail server
* `local_domain` Set the EHLO mail used when sending mail
* `verify_peer_name` Verify the SSL peer name of the remote server when sending email
* `verify_peer` Verify the remote peer certificate when sending mail

## VPN specific keys
* `CA.csr` The CA CSR
Expand Down
51 changes: 14 additions & 37 deletions frontend/components/Mailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,20 @@ class Mailer extends \yii\symfonymailer\Mailer
public function init()
{
parent::init();

$this->useFileTransport=Yii::$app->sys->mail_useFileTransport;

$config['scheme']='smtp';
$config['options']['local_domain']=\Yii::$app->sys->offense_domain;
if(Yii::$app->sys->mail_host !== false)
{
$config['host']=Yii::$app->sys->mail_host;
}

if(Yii::$app->sys->mail_port !== false)
{
$config['port']=intval(Yii::$app->sys->mail_port);
}

if(Yii::$app->sys->mail_username !== false)
{
$config['username']=Yii::$app->sys->mail_username;
}

if(Yii::$app->sys->mail_password !== false)
{
$config['password']=Yii::$app->sys->mail_password;
}

if(Yii::$app->sys->mail_encryption !== false && trim(Yii::$app->sys->mail_encryption)!='')
{
$config['scheme']=Yii::$app->sys->mail_encryption;
}

if(Yii::$app->sys->mail_verify_peer !== false)
{
$this->ssl['verify_peer']=Yii::$app->sys->mail_verify_peer;
}
if(Yii::$app->sys->mail_verify_peer_name !== false)
{
$this->ssl['verify_peer_name']=Yii::$app->sys->mail_verify_peer_name;
$this->useFileTransport = (bool)Yii::$app->sys->mail_useFileTransport;
if (\Yii::$app->sys->dsn !== false) {
$config['dsn']=trim(\Yii::$app->sys->dsn);
} else {
$config['dsn'] = Yii::t('app', '{mail_encryption}://{mail_userpass}{mail_host}:{mail_port}?verify_peer={verify_peer}&local_domain={local_domain}&verify_peer_name={verify_peer_name}', [
'mail_encryption' => \Yii::$app->sys->mail_encryption ?? "smtp",
'mail_userpass' => (trim(\Yii::$app->sys->mail_username) != "" && trim(\Yii::$app->sys->mail_password) != "") ? trim(\Yii::$app->sys->mail_username) . ':' . trim(\Yii::$app->sys->mail_password) . '@' : '',
'mail_password' => \Yii::$app->sys->mail_password,
'mail_host' => \Yii::$app->sys->mail_host,
'mail_port' => \Yii::$app->sys->mail_port ?? "25",
'verify_peer' => intval(\Yii::$app->sys->verify_peer),
'local_domain' => \Yii::$app->sys->offense_domain,
'verify_peer_name' => intval(\Yii::$app->sys->verify_peer_name),
]);
}
$this->setTransport($config);
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/echoCTFView.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public function getTwitter_image_height()
return ['name'=>'twitter:image:height', 'content'=>$this->_image_height];
}

public function renderPhpContent($_content_, $_params_ = [])
public static function renderPhpContent($_content_, $_params_ = [])
{
$_obInitialLevel_ = ob_get_level();
ob_start();
Expand Down
Loading

0 comments on commit 3d23bea

Please sign in to comment.