You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
366 lines
13 KiB
366 lines
13 KiB
<?php
|
|
/* For licensing terms, see /license.txt */
|
|
|
|
namespace Chamilo\PluginBundle\WhispeakAuth\Controller;
|
|
|
|
use Chamilo\PluginBundle\Entity\WhispeakAuth\LogEvent;
|
|
use Chamilo\PluginBundle\WhispeakAuth\Request\ApiRequest;
|
|
use Chamilo\UserBundle\Entity\User;
|
|
use ChamiloSession;
|
|
use Display;
|
|
use Login;
|
|
use WhispeakAuthPlugin;
|
|
|
|
/**
|
|
* Class AuthenticationController.
|
|
*
|
|
* @package Chamilo\PluginBundle\WhispeakAuth\Controller
|
|
*/
|
|
class AuthenticationController extends BaseController
|
|
{
|
|
/**
|
|
* @throws \Exception
|
|
*/
|
|
public function index()
|
|
{
|
|
if (!$this->plugin->toolIsEnabled()) {
|
|
throw new \Exception(get_lang('NotAllowed'));
|
|
}
|
|
|
|
/** @var array $lpQuestionInfo */
|
|
$lpQuestionInfo = ChamiloSession::read(WhispeakAuthPlugin::SESSION_QUIZ_QUESTION, []);
|
|
|
|
if (ChamiloSession::read(WhispeakAuthPlugin::SESSION_AUTH_PASSWORD, false)) {
|
|
ChamiloSession::erase(WhispeakAuthPlugin::SESSION_AUTH_PASSWORD);
|
|
|
|
if (empty($lpQuestionInfo)) {
|
|
$message = $this->plugin->get_lang('MaxAttemptsReached')
|
|
.'<br><strong>'.$this->plugin->get_lang('LoginWithUsernameAndPassword').'</strong>';
|
|
|
|
Display::addFlash(
|
|
Display::return_message($message, 'warning')
|
|
);
|
|
}
|
|
|
|
header('Location: '.api_get_path(WEB_PLUGIN_PATH).'whispeakauth/authentify_password.php');
|
|
exit;
|
|
}
|
|
|
|
/** @var array $lpItemInfo */
|
|
$lpItemInfo = ChamiloSession::read(WhispeakAuthPlugin::SESSION_LP_ITEM, []);
|
|
/** @var \learnpath $oLp */
|
|
$oLp = ChamiloSession::read('oLP', null);
|
|
/** @var \Exercise $objExercise */
|
|
$objExercise = ChamiloSession::read('objExercise', null);
|
|
|
|
$isAuthOnLp = !empty($lpItemInfo) && !empty($oLp);
|
|
$isAuthOnQuiz = !empty($lpQuestionInfo) && !empty($objExercise);
|
|
$showFullPage = !$isAuthOnLp && !$isAuthOnQuiz;
|
|
|
|
$user = api_get_user_entity(
|
|
ChamiloSession::read(WhispeakAuthPlugin::SESSION_2FA_USER, 0) ?: api_get_user_id()
|
|
);
|
|
|
|
$showForm = !$user;
|
|
|
|
if ($user) {
|
|
if (!WhispeakAuthPlugin::getAuthUidValue($user)) {
|
|
$message = Display::return_message($this->plugin->get_lang('SpeechAuthNotEnrolled'), 'warning');
|
|
|
|
if (!empty($lpQuestionInfo) && empty($lpItemInfo)) {
|
|
echo $message;
|
|
} else {
|
|
Display::addFlash($message);
|
|
}
|
|
|
|
header('Location: '.api_get_path(WEB_PLUGIN_PATH).'whispeakauth/authentify_password.php');
|
|
|
|
exit;
|
|
}
|
|
}
|
|
|
|
if (!empty($lpQuestionInfo) && empty($lpItemInfo)) {
|
|
echo api_get_js('rtc/RecordRTC.js');
|
|
echo api_get_js_simple(api_get_path(WEB_PLUGIN_PATH).'whispeakauth/assets/js/RecordAudio.js');
|
|
}
|
|
|
|
$request = new ApiRequest();
|
|
$response = $request->createAuthenticationSessionToken($user);
|
|
|
|
if (empty($response['text'])) {
|
|
$varNumber = mt_rand(1, 6);
|
|
$response['text'] = $this->plugin->get_lang("AuthentifySampleText$varNumber");
|
|
}
|
|
|
|
ChamiloSession::write(WhispeakAuthPlugin::SESSION_SENTENCE_TEXT, $response['token']);
|
|
|
|
if (!empty($lpQuestionInfo) && empty($lpItemInfo)) {
|
|
$template = new \Template('', $showFullPage, $showFullPage, false, true, false);
|
|
$template->assign('show_form', $showForm);
|
|
$template->assign('sample_text', $response['text']);
|
|
|
|
echo $template->fetch('whispeakauth/view/authentify_recorder.html.twig');
|
|
exit;
|
|
}
|
|
|
|
$this->displayPage(
|
|
$showFullPage,
|
|
[
|
|
'show_form' => $showForm,
|
|
'sample_text' => $response['text'],
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @throws \Exception
|
|
*/
|
|
public function ajax()
|
|
{
|
|
$userId = api_get_user_id();
|
|
$user2fa = ChamiloSession::read(WhispeakAuthPlugin::SESSION_2FA_USER, 0);
|
|
|
|
$result = [];
|
|
|
|
if (!empty($user2fa) || !empty($userId)) {
|
|
$isAllowed = !empty($_FILES['audio']);
|
|
} else {
|
|
$isAllowed = !empty($_POST['username']) && !empty($_FILES['audio']);
|
|
}
|
|
|
|
if (!$isAllowed || !$this->plugin->toolIsEnabled()) {
|
|
throw new \Exception(get_lang('NotAllowed'));
|
|
}
|
|
|
|
if (!empty($user2fa)) {
|
|
$user = api_get_user_entity($user2fa);
|
|
} elseif (!empty($userId)) {
|
|
$user = api_get_user_entity($userId);
|
|
} else {
|
|
/** @var User|null $user */
|
|
$user = \UserManager::getRepository()->findOneBy(['username' => $_POST['username']]);
|
|
}
|
|
|
|
if (!$user) {
|
|
throw new \Exception(get_lang('NotFound'));
|
|
}
|
|
|
|
$audioFilePath = $this->uploadAudioFile($user);
|
|
|
|
$failedLogins = ChamiloSession::read(WhispeakAuthPlugin::SESSION_FAILED_LOGINS, 0);
|
|
$maxAttempts = $this->plugin->getMaxAttempts();
|
|
|
|
if ($maxAttempts && $failedLogins >= $maxAttempts) {
|
|
throw new \Exception($this->plugin->get_lang('MaxAttemptsReached'));
|
|
}
|
|
|
|
$token = \ChamiloSession::read(\WhispeakAuthPlugin::SESSION_SENTENCE_TEXT);
|
|
|
|
\ChamiloSession::erase(\WhispeakAuthPlugin::SESSION_SENTENCE_TEXT);
|
|
|
|
/** @var array $lpItemInfo */
|
|
$lpItemInfo = ChamiloSession::read(WhispeakAuthPlugin::SESSION_LP_ITEM, []);
|
|
/** @var array $quizQuestionInfo */
|
|
$quizQuestionInfo = ChamiloSession::read(WhispeakAuthPlugin::SESSION_QUIZ_QUESTION, []);
|
|
|
|
$success = true;
|
|
|
|
$request = new ApiRequest();
|
|
|
|
try {
|
|
$request->performAuthentication($token, $user, $audioFilePath);
|
|
|
|
$message = $this->plugin->get_lang('AuthentifySuccess');
|
|
} catch (\Exception $exception) {
|
|
$message = $this->plugin->get_lang('AuthentifyFailed')
|
|
.PHP_EOL
|
|
.$exception->getMessage();
|
|
|
|
$success = false;
|
|
}
|
|
|
|
if (!$success) {
|
|
if (!empty($lpItemInfo)) {
|
|
$this->plugin->addAttemptInLearningPath(
|
|
LogEvent::STATUS_FAILED,
|
|
$user->getId(),
|
|
$lpItemInfo['lp_item'],
|
|
$lpItemInfo['lp']
|
|
);
|
|
}
|
|
|
|
if (!empty($quizQuestionInfo)) {
|
|
$this->plugin->addAttemptInQuiz(
|
|
LogEvent::STATUS_FAILED,
|
|
$user->getId(),
|
|
$quizQuestionInfo['question'],
|
|
$quizQuestionInfo['quiz']
|
|
);
|
|
}
|
|
|
|
if (empty($lpItemInfo) && empty($quizQuestionInfo)) {
|
|
$this->plugin->addAuthenticationAttempt(LogEvent::STATUS_FAILED, $user->getId());
|
|
}
|
|
|
|
$authTokenRequest = new ApiRequest();
|
|
$authTokenResponse = $authTokenRequest->createAuthenticationSessionToken($user);
|
|
|
|
if (empty($authTokenResponse['text'])) {
|
|
$varNumber = mt_rand(1, 6);
|
|
$authTokenResponse['text'] = $this->plugin->get_lang("AuthentifySampleText$varNumber");
|
|
}
|
|
|
|
$result['text'] = $authTokenResponse['text'];
|
|
|
|
ChamiloSession::write(WhispeakAuthPlugin::SESSION_SENTENCE_TEXT, $authTokenResponse['token']);
|
|
|
|
ChamiloSession::write(WhispeakAuthPlugin::SESSION_FAILED_LOGINS, ++$failedLogins);
|
|
|
|
if ($maxAttempts && $failedLogins >= $maxAttempts) {
|
|
$message .= PHP_EOL
|
|
.'<span data-reach-attempts="true">'.$this->plugin->get_lang('MaxAttemptsReached').'</span>'
|
|
.PHP_EOL.PHP_EOL
|
|
.'<strong>'
|
|
.$this->plugin->get_lang('LoginWithUsernameAndPassword')
|
|
.'</strong>';
|
|
|
|
if (!empty($user2fa)) {
|
|
Display::addFlash(
|
|
Display::return_message($message, 'warning', false)
|
|
);
|
|
}
|
|
} else {
|
|
$message .= PHP_EOL.$this->plugin->get_lang('TryAgain');
|
|
|
|
if ('true' === api_get_setting('allow_lostpassword')) {
|
|
$message .= PHP_EOL
|
|
.Display::url(
|
|
get_lang('LostPassword'),
|
|
api_get_path(WEB_CODE_PATH).'auth/lostPassword.php',
|
|
['target' => $lpItemInfo ? '_top' : '_self']
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
$result['resultHtml'] = Display::return_message(
|
|
nl2br($message),
|
|
$success ? 'success' : 'warning',
|
|
false
|
|
);
|
|
|
|
if (!$success && $maxAttempts && $failedLogins >= $maxAttempts) {
|
|
ChamiloSession::erase(WhispeakAuthPlugin::SESSION_FAILED_LOGINS);
|
|
|
|
if (!empty($lpItemInfo)) {
|
|
$result['resultHtml'] .= '<script>window.location.href = "'
|
|
.api_get_path(WEB_PLUGIN_PATH)
|
|
.'whispeakauth/authentify_password.php";</script>';
|
|
|
|
return $result;
|
|
}
|
|
|
|
if (!empty($quizQuestionInfo)) {
|
|
$url = api_get_path(WEB_CODE_PATH).'exercise/exercise_submit.php?'.$quizQuestionInfo['url_params'];
|
|
|
|
ChamiloSession::write(WhispeakAuthPlugin::SESSION_AUTH_PASSWORD, true);
|
|
|
|
$result['resultHtml'] .= "<script>window.location.href = '".$url."';</script>";
|
|
|
|
return $result;
|
|
}
|
|
|
|
$result['resultHtml'] .= '<script>window.location.href = "'.api_get_path(WEB_PATH).'";</script>';
|
|
|
|
return $result;
|
|
}
|
|
|
|
if ($success) {
|
|
ChamiloSession::erase(WhispeakAuthPlugin::SESSION_SENTENCE_TEXT);
|
|
ChamiloSession::erase(WhispeakAuthPlugin::SESSION_FAILED_LOGINS);
|
|
|
|
if (!empty($lpItemInfo)) {
|
|
ChamiloSession::erase(WhispeakAuthPlugin::SESSION_LP_ITEM);
|
|
ChamiloSession::erase(WhispeakAuthPlugin::SESSION_2FA_USER);
|
|
|
|
$this->plugin->addAttemptInLearningPath(
|
|
LogEvent::STATUS_SUCCESS,
|
|
$user->getId(),
|
|
$lpItemInfo['lp_item'],
|
|
$lpItemInfo['lp']
|
|
);
|
|
|
|
$result['resultHtml'] .= '<script>window.location.href = "'.$lpItemInfo['src'].'";</script>';
|
|
|
|
return $result;
|
|
}
|
|
|
|
if (!empty($quizQuestionInfo)) {
|
|
$quizQuestionInfo['passed'] = true;
|
|
$url = api_get_path(WEB_CODE_PATH).'exercise/exercise_submit.php?'.$quizQuestionInfo['url_params'];
|
|
|
|
ChamiloSession::write(WhispeakAuthPlugin::SESSION_QUIZ_QUESTION, $quizQuestionInfo);
|
|
|
|
$this->plugin->addAttemptInQuiz(
|
|
LogEvent::STATUS_SUCCESS,
|
|
$user->getId(),
|
|
$quizQuestionInfo['question'],
|
|
$quizQuestionInfo['quiz']
|
|
);
|
|
|
|
$result['resultHtml'] .= '<script>window.location.href = "'.$url.'";</script>';
|
|
|
|
return $result;
|
|
}
|
|
|
|
if (empty($lpItemInfo) && empty($quizQuestionInfo)) {
|
|
$this->plugin->addAuthenticationAttempt(LogEvent::STATUS_SUCCESS, $user->getId());
|
|
}
|
|
|
|
$loggedUser = [
|
|
'user_id' => $user->getId(),
|
|
'status' => $user->getStatus(),
|
|
'uidReset' => true,
|
|
];
|
|
|
|
if (empty($user2fa)) {
|
|
ChamiloSession::write(WhispeakAuthPlugin::SESSION_2FA_USER, $user->getId());
|
|
}
|
|
|
|
ChamiloSession::erase(WhispeakAuthPlugin::SESSION_FAILED_LOGINS);
|
|
ChamiloSession::write('_user', $loggedUser);
|
|
Login::init_user($user->getId(), true);
|
|
|
|
$result['resultHtml'] .= '<script>window.location.href = "'.api_get_path(WEB_PATH).'";</script>';
|
|
|
|
return $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
protected function displayPage($isFullPage, array $variables)
|
|
{
|
|
global $htmlHeadXtra;
|
|
|
|
$htmlHeadXtra[] = api_get_js('rtc/RecordRTC.js');
|
|
$htmlHeadXtra[] = api_get_js_simple(api_get_path(WEB_PLUGIN_PATH).'whispeakauth/assets/js/RecordAudio.js');
|
|
|
|
$pageTitle = $this->plugin->get_title();
|
|
|
|
$template = new \Template($pageTitle, $isFullPage, $isFullPage, !$isFullPage);
|
|
|
|
foreach ($variables as $key => $value) {
|
|
$template->assign($key, $value);
|
|
}
|
|
|
|
$pageContent = $template->fetch('whispeakauth/view/authentify_recorder.html.twig');
|
|
|
|
$template->assign('header', $pageTitle);
|
|
$template->assign('content', $pageContent);
|
|
$template->display_one_col_template();
|
|
}
|
|
}
|
|
|