Skip to content

Commit

Permalink
Merge pull request #1163 from proditis/player-approval-status
Browse files Browse the repository at this point in the history
Player approval status and process
  • Loading branch information
proditis authored May 6, 2024
2 parents fc27a65 + 0eee80a commit 0a37fe9
Show file tree
Hide file tree
Showing 10 changed files with 438 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class m211204_005430_load_default_email_templates extends Migration
public $TPL=[
'emailChangeVerify',
'emailVerify',
'passwordResetToken'
'passwordResetToken',
'rejectVerify',
];
/**
* {@inheritdoc}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

use yii\db\Migration;

/**
* Handles adding columns to table `{{%player}}`.
*/
class m240502_232532_add_approval_column_to_player_table extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('{{%player}}', 'approval', $this->integer()->defaultValue(0));
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropColumn('{{%player}}', 'approval');
}
}
122 changes: 72 additions & 50 deletions backend/modules/frontend/actions/player/MailAction.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace app\modules\frontend\actions\player;

use Yii;
Expand All @@ -17,67 +18,88 @@ class MailAction extends \yii\base\Action
/*
Mail Users their activation URL
*/
public function run(int $id, $baseURL="https://echoctf.red/activate/")
public function run(int $id, $baseURL = "https://echoctf.red/activate/")
{

// Get innactive players
$player=$this->controller->findModel($id);
if($player->status==10)
$player = $this->controller->findModel($id);
if ($player->status == 10)
{
\Yii::$app->getSession()->setFlash('warning', Yii::t('app','Player already active skipping mail.'));
return $this->controller->goBack(Yii::$app->request->referrer);
\Yii::$app->getSession()->setFlash('warning', Yii::t('app', 'Player already active skipping mail.'));
}
elseif($player->status==9)
elseif ($player->status == 9)
{
//$event_name=Sysconfig::findOne('event_name')->val;
try {
$activationURL=sprintf("https://%s/verify-email?token=%s",\Yii::$app->sys->offense_domain, $player->verification_token);
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.' robot'])
->setTo([$player->email => $player->fullname])
->setSubject(Yii::t('app','{event_name} Account approved',['event_name'=>trim(Yii::$app->sys->event_name)]))
->send();
\Yii::$app->getSession()->setFlash('success', Yii::t('app','Player activation mail send.'));
}
catch(\Exception $e)
{
\Yii::$app->getSession()->setFlash('error', Yii::t('app','Failed to mail player. {exception}',['exception'=>Html::encode($e->getMessage())]));
}
if (\Yii::$app->sys->players_require_approval === true && $player->approval > 0 && $player->approval <= 2)
$this->approvalMail($player);
elseif (\Yii::$app->sys->players_require_approval === true && $player->approval > 2 && $player->approval <= 4)
$this->rejectionMail($player);
}
elseif($player->status==0)
elseif ($player->status == 0)
{
try {
$activationURL=sprintf("https://%s/verify-email?token=%s",\Yii::$app->sys->offense_domain, $player->verification_token);
Yii::$app
->mailer
->compose(
['html' => 'rejectVerify-html', 'text' => 'rejectVerify-text'],
['user' => $player]
)
->setFrom([Yii::$app->sys->mail_from => Yii::$app->sys->mail_fromName.' robot'])
->setTo([$player->email => $player->fullname])
->setSubject(Yii::t('app','{event_name} Account Rejected',['event_name'=>trim(Yii::$app->sys->event_name)]))
->send();
\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())]));
}

$this->rejectionMail($player);
}

// Generate activation URL
// $activationURL=sprintf("%s%s", $baseURL, $player->activkey);
// $content=$this->controller->renderPartial('_account_activation_email', ['player' => $player, 'activationURL'=>$activationURL, 'event_name'=>$event_name]);
// $player->mail($content, 'echoCTF RED re-sending of account activation URL');

if ($player->approval == 1)
$player->updateAttributes(['approval' => 2]);
elseif ($player->approval == 3)
$player->updateAttributes(['approval' => 4]);

return $this->controller->goBack(Yii::$app->request->referrer);
}

/**
* Send player rejection mail
*/
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.'));
} catch (\Exception $e) {
\Yii::$app->getSession()->setFlash('error', Yii::t('app', 'Failed to mail rejection to player. {exception}', ['exception' => Html::encode($e->getMessage())]));
}
}

/**
* Send approval email to user
*/
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)])
);
if (Yii::$app->sys->players_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.'));
} else {
\Yii::$app->getSession()->setFlash('success', Yii::t('app', 'Player activation mail send.'));
}
} catch (\Exception $e) {
\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();
}
}
152 changes: 150 additions & 2 deletions backend/modules/frontend/controllers/PlayerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public function behaviors()
'reset-player-progress' => ['POST'],
'toggle-academic' => ['POST'],
'toggle-active' => ['POST'],
'approve' => ['POST'],
'reject' => ['POST'],
],
],
]);
Expand Down Expand Up @@ -245,11 +247,15 @@ public function actionDelete($id)
*/
public function actionSetDeleted($id)
{
if(\Yii::$app->sys->players_require_approval===true)
$updateAttributes=['status' => 0, 'active' => 0,'approval'=>3];
else
$updateAttributes=['status' => 0, 'active' => 0];

if (($model = Player::findOne($id)) !== null && $model->updateAttributes(['status' => 0, 'active' => 0]))
if (($model = Player::findOne($id)) !== null && $model->updateAttributes($updateAttributes))
Yii::$app->session->setFlash('success', Yii::t('app','Player [{username}] status set to deleted.', ['username'=>Html::encode($model->username)]));
else
Yii::$app->session->setFlash('error', Yii::t('app','Player deletion failed.'));
Yii::$app->session->setFlash('error', Yii::t('app','Player setting deletion flag failed.'));
return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null));
}

Expand Down Expand Up @@ -341,6 +347,50 @@ public function actionToggleActive($id)
return $this->redirect(['index']);
}

/**
* Approve player registration.
* @param integer $id
* @return mixed
* @throws NotFoundHttpException if the model cannot be found
*/
public function actionApprove($id)
{
$trans = Yii::$app->db->beginTransaction();
try {
$model = $this->findModel($id);
$model->updateAttributes(['approval' => 1]);
$trans->commit();
Yii::$app->session->setFlash('success', Yii::t('app','Player [{username}] registration approved.', ['username'=>Html::encode($model->username)]));
} catch (\Exception $e) {
$trans->rollBack();
Yii::$app->session->setFlash('error', Yii::t('app','Failed to approve player [{username}] registration [{exception}]', ['username'=>Html::encode($model->username),'exception'=>Html::encode($e->getMessage())]));
}

return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null));
}

/**
* Reject player registration.
* @param integer $id
* @return mixed
* @throws NotFoundHttpException if the model cannot be found
*/
public function actionReject($id)
{
$trans = Yii::$app->db->beginTransaction();
try {
$model = $this->findModel($id);
$model->updateAttributes(['approval' => 3]);
$trans->commit();
Yii::$app->session->setFlash('success', Yii::t('app','Player [{username}] registration rejected.', ['username'=>Html::encode($model->username)]));
} catch (\Exception $e) {
$trans->rollBack();
Yii::$app->session->setFlash('error', Yii::t('app','Failed to reject player [{username}] registration.', ['username'=>Html::encode($model->username)]));
}

return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null));
}

public function actionGenerateSsl($id)
{
$player = $this->findModel($id);
Expand Down Expand Up @@ -440,6 +490,104 @@ public function actionClearVpn($id)
}

/**
* Reject all filtered results
*/
public function actionRejectFiltered()
{
$searchModel = new PlayerSearch();
$query = $searchModel->search(['PlayerSearch' => Yii::$app->request->post()]);
$query->pagination = false;
if (intval($query->count) === intval(Player::find()->count())) {
Yii::$app->session->setFlash('error', Yii::t('app','You have attempted to reject all the records.'));
return $this->redirect(['index']);
}

$trans = Yii::$app->db->beginTransaction();
try {
$counter = $query->count;
foreach ($query->getModels() as $q)
{
$q->approval=3;
$q->save();
}
$trans->commit();
Yii::$app->session->setFlash('success', Yii::t('app','[<code><b>{counter}</b></code>] Players rejected',['counter'=>intval($counter)]));
} catch (\Exception $e) {
$trans->rollBack();
Yii::$app->session->setFlash('error', Yii::t('app','Failed to reject users'));
}
return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null));
}

/**
* Approve all filtered results
*/
public function actionApproveFiltered()
{
$searchModel = new PlayerSearch();
$query = $searchModel->search(['PlayerSearch' => Yii::$app->request->post()]);
$query->pagination = false;
if (intval($query->count) === intval(Player::find()->count())) {
Yii::$app->session->setFlash('error', Yii::t('app','You have attempted to approve all the records.'));
return $this->redirect(['index']);
}

$trans = Yii::$app->db->beginTransaction();
try {
$counter = $query->count;
foreach ($query->getModels() as $q)
{
$q->approval=1;
$q->save();
}
$trans->commit();
Yii::$app->session->setFlash('success', Yii::t('app','[<code><b>{counter}</b></code>] Players approved',['counter'=>intval($counter)]));
} catch (\Exception $e) {
$trans->rollBack();
Yii::$app->session->setFlash('error', Yii::t('app','Failed to approve users'));
}
return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null));
}

/**
* Mail all filtered results
*/
public function actionMailFiltered()
{
$searchModel = new PlayerSearch();
$query = $searchModel->search(['PlayerSearch' => Yii::$app->request->post()]);
$query->query->andFilterWhere([
'player.approval' => [1,3],
]);
//$query->pagination = false;
$query->pagination = ['pageSize' => 5];
if (intval($query->count) === intval(Player::find()->count())) {
Yii::$app->session->setFlash('error', Yii::t('app','You have attempted to mail all the players.'));
return $this->redirect(['index']);
}
$approved=$rejected=0;
$trans = Yii::$app->db->beginTransaction();
try {
$counter = $query->count;
foreach ($query->getModels() as $q)
{
if($q->approval==1)
$approved++;
elseif($q->approval==3)
$rejected++;
Yii::$app->runAction('frontend/player/mail', ['id' => $q->id]);
}
$trans->commit();

Yii::$app->session->setFlash('success', Yii::t('app','[<code><b>{counter}</b></code>] total Players mailed [{approved} approved/{rejected} rejected]',['counter'=>intval($counter),'approved'=>$approved,'rejected'=>$rejected]));
} catch (\Exception $e) {
$trans->rollBack();
Yii::$app->session->setFlash('error', Yii::t('app','Failed to mail users'));
}
return $this->goBack((!empty(Yii::$app->request->referrer) ? Yii::$app->request->referrer : null));
}

/**
* Finds the Player model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* @param integer $id
Expand Down
5 changes: 4 additions & 1 deletion backend/modules/frontend/models/PlayerAR.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* @property int $active
* @property int $academic
* @property int $status
* @property int $approval
* @property string $ts
*
* @property PlayerBadge[] $playerBadges
Expand Down Expand Up @@ -63,6 +64,8 @@ class PlayerAR extends \yii\db\ActiveRecord
const STATUS_UNVERIFIED=8;
const STATUS_INACTIVE=9;
const STATUS_ACTIVE=10;
const APPROVAL=[4 => 'Rejection Mailed',3 => 'Rejected', 2 => 'Approval Mailed', 1 => "Approved", 0 => "Pending",];

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -100,7 +103,7 @@ public function rules()
return [
[['username', 'type', 'status','email'], 'required'],
[['type','affiliation'], 'string'],
[['active', 'status'], 'integer'],
[['active', 'status','approval'], 'integer'],
[['academic'], 'integer'],
[['academic'], 'default','value'=>0],
[['password_hash'], 'default', 'value'=>""],
Expand Down
Loading

0 comments on commit 0a37fe9

Please sign in to comment.