Browse Source

added TOTP & CAPTCHA modules

- updated Aauth to load CAPTCHA or TOTP module if enabled
v3-dev
REJack 6 years ago
parent
commit
9804cc9e1a
No known key found for this signature in database
GPG Key ID: 4A44B48700429F46
  1. 10
      app/Libraries/Aauth.php
  2. 166
      app/Libraries/Aauth/CAPTCHA.php
  3. 153
      app/Libraries/Aauth/TOTP.php

10
app/Libraries/Aauth.php

@ -133,6 +133,16 @@ class Aauth
$this->session = $session;
$this->modules = $this->config->modules;
if ($this->config->captchaEnabled)
{
$this->modules = array_merge($this->config->modules, ['CAPTCHA']);
}
if ($this->config->totpEnabled)
{
$this->modules = array_merge($this->config->modules, ['TOTP']);
}
$this->cachePermIds = [];
$this->cacheGroupIds = [];

166
app/Libraries/Aauth/CAPTCHA.php

@ -0,0 +1,166 @@
<?php
/**
* CodeIgniter-Aauth
*
* Aauth is a User Authorization Library for CodeIgniter 4.x, which aims to make
* easy some essential jobs such as login, permissions and access operations.
* Despite ease of use, it has also very advanced features like grouping,
* access management, public access etc..
*
* @package CodeIgniter-Aauth
* @author Emre Akay
* @author Raphael "REJack" Jackstadt
* @copyright 2014-2019 Emre Akay
* @license https://opensource.org/licenses/MIT MIT License
* @link https://github.com/emreakay/CodeIgniter-Aauth
*/
namespace App\Libraries\Aauth;
use \App\Models\Aauth\LoginAttemptModel;
/**
* Aauth CAPTCHA
*
* Class for handling CAPTCHA (reCAPTCHA & hCAPTCHA)
*
* @package CodeIgniter-Aauth
*/
class CAPTCHA extends \App\Libraries\Aauth
{
/**
* Verify Response
*
* Calls the CAPTCHA site verify API to verify whether the user passes
* CAPTCHA test.
*
* @param string $response Response string from CAPTCHA verification.
*
* @return array
*/
public function verifyResponse($response)
{
if ($response === null || strlen($response) === 0)
{
return [
'success' => false,
'errorCodes' => 'missing-input',
];
}
$request = \Config\Services::request();
$remoteIp = $request->getIPAddress();
if ($this->config->captchaType === 'recaptcha')
{
$siteUrl = 'https://www.google.com/recaptcha/api/siteverify';
$request = $this->_submitGet(
$siteUrl,
[
'secret' => $this->config->captchaSecret,
'remoteip' => $remoteIp,
'response' => $response,
'version' => 'php_1.0.0',
]);
}
else if ($this->config->captchaType === 'hcaptcha')
{
$siteUrl = 'https://hcaptcha.com/siteverify';
$request = $this->_submitPost(
$siteUrl,
[
'secret' => $this->config->captchaSecret,
'response' => $response,
'remoteip' => $remoteIp,
]);
}
$answer = json_decode($request, true);
if (trim($answer['success']) === true)
{
return ['success' => true];
}
else
{
return [
'success' => false,
'errorCodes' => $answer['error-codes'],
];
}
}
/**
* Generate CAPTCHA HTML
*
* @return string
*/
public function generateCaptchaHtml()
{
$content = '';
if ($this->config->loginProtection && $this->config->captchaEnabled)
{
$loginAttemptModel = new LoginAttemptModel();
if ($loginAttemptModel->find() >= $this->config->captchaLoginAttempts)
{
$siteKey = $this->config->captchaSiteKey;
if ($this->config->captchaType === 'recaptcha')
{
$content .= "<div class='g-recaptcha' data-sitekey='{$siteKey}'></div>";
$content = '<script src="https://www.google.com/recaptcha/api.js" async defer></script>';
}
else if ($this->config->captchaType === 'hcaptcha')
{
$content = "<div class='h-captcha' data-sitekey='{$siteKey}'></div>";
$content .= '<script src="https://hcaptcha.com/1/api.js" async defer></script>';
}
}
}
return $content;
}
/**
* Submit GET
*
* Submits an HTTP GET to a CAPTCHA server.
*
* @param string $url URL path to CAPTCHA server.
* @param array $data Array of parameters to be sent.
*
* @return array response
*/
private function _submitGet($url, $data)
{
$client = \Config\Services::curlrequest();
$response = $client->request('GET', $url, [
'query' => $data,
]);
return $response->getBody();
}
/**
* Submit POST
*
* Submits an HTTP POST to a CAPTCHA server.
*
* @param string $url URL path to CAPTCHA server.
* @param array $data Array of parameters to be sent.
*
* @return array response
*/
private function _submitPost($url, $data)
{
$client = \Config\Services::curlrequest();
$response = $client->request('POST', $url, [
'query' => $data,
]);
return $response->getBody();
}
}

153
app/Libraries/Aauth/TOTP.php

@ -0,0 +1,153 @@
<?php
/**
* CodeIgniter-Aauth
*
* Aauth is a User Authorization Library for CodeIgniter 4.x, which aims to make
* easy some essential jobs such as login, permissions and access operations.
* Despite ease of use, it has also very advanced features like grouping,
* access management, public access etc..
*
* @package CodeIgniter-Aauth
* @author Emre Akay
* @author Raphael "REJack" Jackstadt
* @copyright 2014-2019 Emre Akay
* @license https://opensource.org/licenses/MIT MIT License
* @link https://github.com/emreakay/CodeIgniter-Aauth
*/
namespace App\Libraries\Aauth;
use \App\Models\Aauth\UserVariableModel;
use OTPHP\TOTP as OTPHP_TOTP;
/**
* Aauth TOTP
*
* Class for handling 2-factor authentication
*
* @package CodeIgniter-Aauth
*/
class TOTP extends \App\Libraries\Aauth
{
/**
* Update User TOTP Secret
*
* @param integer $userId User Id
* @param string $secret Secret Key
*
* @return boolean
*/
public function updateUserTotpSecret(int $userId = null, string $secret)
{
if (! $userId)
{
$userId = (int) @$this->session->user['id'];
}
$userVariableModel = new UserVariableModel();
return $userVariableModel->save($userId, 'totp_secret', $secret, true);
}
/**
* Generate Unique TOTP Secret
*
* @return string
*/
public function generateUniqueTotpSecret()
{
$stop = false;
while (! $stop)
{
$secret = OTPHP_TOTP::create();
if ($userVariable !== $userVariableModel->where(['data_key' => 'totp_secret', 'data_value' => $secret, 'system' => 1])->getFirstRow('array'))
{
$stop = true;
return $secret;
}
}
}
/**
* Generate TOTP QR Code
*
* Generate TOTP QR Code URI by Secret
*
* @param string $secret Secret Key
*
* @return string
*/
public function generateTotpQrCode(string $secret)
{
$totp = OTPHP_TOTP::create($secret);
return $totp->getQrCodeUri();
}
/**
* Verify user TOTP Code
*
* @param integer $totpCode TOTP Code
* @param string $userId User Id
*
* @return boolean
*/
public function verifyUserTotpCode(int $totpCode, string $userId = null)
{
if (! $this->isTotpRequired())
{
return true;
}
if (! $userId)
{
$userId = (int) @$this->session->user['id'];
}
if (empty($totpCode))
{
$this->error(lang('Aauth.requiredTOTPCode'));
return false;
}
$userVariableModel = new UserVariableModel();
$totpSecret = $userVariableModel->find($userId, 'totp_secret', true);
$totp = OTPHP_TOTP::create($totpSecret);
if (! $totp->verify($totpCode))
{
$this->error(lang('Aauth.invalidTOTPCode'));
return false;
}
else
{
unset($_SESSION['user']['totp_required']);
return true;
}
}
/**
* IS TOTP Required
*
* Checks if User need TOTP verification.
*
* @return boolean
*/
public function isTotpRequired()
{
if (@$this->session->user['totp_required'])
{
return true;
}
return false;
}
}
Loading…
Cancel
Save