234 lines
9.0 KiB
PHP
234 lines
9.0 KiB
PHP
<?php
|
|
require_once realpath(__DIR__."/../lib/php-jwt/vendor/autoload.php");
|
|
|
|
use Firebase\JWT\JWT;
|
|
|
|
class Auth {
|
|
public $privateKey = 'wscO4QaF'; // Key de codificación
|
|
public $expire = 3600; // 3600 Expire time in seconds
|
|
public $renewTime = 1200; // 1200 Renew time before expired in seconds
|
|
public $now;
|
|
/**
|
|
* @param privateKey: Private Key
|
|
*/
|
|
public function __construct($privateKey = null) {
|
|
if ($privateKey) $this->privateKey = $privateKey;
|
|
$this->now = time();
|
|
}
|
|
|
|
static function AuthenticateUserLocal($loginAccess){
|
|
global $TABLE_PREFIX;
|
|
$user = $loginAccess[0];
|
|
$pass = $loginAccess[1];
|
|
|
|
$userBD = mysql_query_fetch_all_assoc("SELECT *,(neverExpires = '0' AND expiresDate < NOW()) as isExpired FROM ".$TABLE_PREFIX."accounts WHERE `username`='".$user."' and `password`= '".md5($pass)."' LIMIT 1");
|
|
$userBD = @$userBD[0];
|
|
return $userBD;
|
|
}
|
|
|
|
static function AuthenticateUser($loginAccess){
|
|
global $TABLE_PREFIX;
|
|
if (count($loginAccess)<2) API::error(new ApiError("Las credenciales son incorrectas"));
|
|
$user = $loginAccess[0];
|
|
$pass = $loginAccess[1];
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => "https://ws.cocosolution.com/api/auth/",
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => "",
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 30,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => "POST",
|
|
CURLOPT_POSTFIELDS => "",
|
|
CURLOPT_HTTPHEADER => array(
|
|
"Accept: */*",
|
|
"Accept-Encoding: gzip, deflate",
|
|
"Authorization: SimpleAuth ".base64_encode($user.":".$pass),
|
|
"Cache-Control: no-cache",
|
|
"Connection: keep-alive",
|
|
"Content-length: 0",
|
|
"Content-type: application/json",
|
|
"Referer: ".$_SERVER["HTTP_HOST"]
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
$err = curl_error($curl);
|
|
|
|
curl_close($curl);
|
|
|
|
if ($err) {
|
|
API::error(new Exception("Login failed"));
|
|
} else if (@json_decode($response,true)["error"]){
|
|
API::error(new Exception("Login failed"));
|
|
}else{
|
|
$schema = loadINI(__DIR__."/../../custom-schema.ini.php");
|
|
if (!@$schema["enabled"]) API::error(new Exception("Login failed"));
|
|
|
|
try{
|
|
$resultData = json_decode($response,true);
|
|
self::validateUserHash($resultData["data"]["userNum"]);
|
|
return ["num" => $resultData["data"]["userNum"]];
|
|
}catch(Exception $e){
|
|
API::error(new ApiError('Login Failed '.$e->getMessage(),403));
|
|
}
|
|
}
|
|
}
|
|
|
|
static function validateUserHash($num){
|
|
$schema = loadINI(__DIR__."/../../custom-schema.ini.php");
|
|
if (!@$schema["enabled"]) API::error(new Exception("Login failed"));
|
|
if(@$schema['config']["hash"]) {
|
|
$allowed_users = explode(',', $schema['config']['hash']);
|
|
if (!in_array(sha1($num), $allowed_users)) API::error(new Exception("Login failed"));
|
|
} else {
|
|
API::error(new Exception("Login failed"));
|
|
}
|
|
// if (@$schema["config"]["hash"] != sha1($num)) API::error(new Exception("Login failed"));
|
|
}
|
|
|
|
static function updateTokenUserData(){
|
|
$api = new API();
|
|
$auth = new self();
|
|
$token = array(
|
|
'iat' => $auth->now, // Tiempo que inició el token
|
|
'exp' => $auth->now+($auth->expire), // Tiempo que expirará el token
|
|
'data' => API::$user
|
|
);
|
|
$jwt = JWT::encode($token, $auth->privateKey);
|
|
|
|
API::setToken(["renewToken" => $jwt]);
|
|
}
|
|
static function validateMasterKey($requestToken){
|
|
$schema = loadINI(__DIR__."/../../custom-schema.ini.php");
|
|
if (!@$schema["enabled"]) API::error(new Exception("Login failed"));
|
|
if (@$schema["config"]["masterKey"] != $requestToken) return false;
|
|
return true;
|
|
}
|
|
static function authorizeApi($auth = false) {
|
|
|
|
$api = new API();
|
|
$auth = new self();
|
|
$requestToken = self::getBearerToken();
|
|
$loginAccess = self::getLoginAccess();
|
|
|
|
$tokenData = [];
|
|
|
|
if (!$requestToken && !$loginAccess) API::error(new ApiError('No token was sent',403));
|
|
|
|
if ($requestToken) {
|
|
if (self::validateMasterKey($requestToken)) return ["user" => true];
|
|
try{
|
|
$data = (object)JWT::decode($requestToken, $auth->privateKey, array('HS256'));
|
|
$data->data = (array) $data->data;
|
|
|
|
API::$user = json_decode(json_encode($data->data), true);
|
|
|
|
self::validateUserHash(API::$user["num"]);
|
|
|
|
$difference = $data->exp-$auth->now;
|
|
if ($difference<0){
|
|
API::error(new ApiError('Token expired',403));
|
|
}else if($difference >= 0 && $difference < $auth->renewTime){
|
|
$token = array(
|
|
'iat' => $auth->now, // Tiempo que inició el token
|
|
'exp' => $auth->now+($auth->expire), // Tiempo que expirará el token
|
|
'data' => $data->data
|
|
);
|
|
$jwt = JWT::encode($token, $auth->privateKey);
|
|
// AQUI FALTA CONVALIDAR LOS DATOS DEL USUARIO DEL TOKEN CON LA BBDD PARA
|
|
// ECHARLO FUERA SI LOS ACCESOS O ALGUN OTRO DATO HA CAMBIADO
|
|
$tokenData = ["renewToken" => $jwt,"user" => $data->data,"difference" => ($data->exp-$auth->now)];
|
|
if ($auth) $tokenData["token"] = $jwt;
|
|
API::addResponseData($tokenData);
|
|
|
|
return $tokenData;
|
|
}else{
|
|
$tokenData = ["user" => $data->data,"difference" => ($data->exp-$auth->now)];
|
|
if ($auth) $tokenData["token"] = $requestToken;
|
|
API::addResponseData($tokenData);
|
|
return $tokenData;
|
|
}
|
|
|
|
|
|
}catch (Exception $e) {
|
|
API::error(new ApiError('Token expired',403));
|
|
}
|
|
|
|
}else if ($loginAccess){
|
|
|
|
try{
|
|
$authenticated = self::AuthenticateUser($loginAccess);
|
|
|
|
if ($authenticated){
|
|
|
|
$token = array(
|
|
'iat' => $auth->now, // Tiempo que inició el token
|
|
'exp' => $auth->now+($auth->expire), // Tiempo que expirará el token
|
|
'data' => $authenticated
|
|
);
|
|
|
|
$jwt = JWT::encode($token, $auth->privateKey);
|
|
|
|
$tokenData = ["token" => $jwt,"expire" => $auth->now+($auth->expire),"user" => ["num" => $authenticated["num"]],"login" => true];
|
|
|
|
API::$user = $authenticated;
|
|
|
|
return $tokenData;
|
|
}else{
|
|
API::error(new ApiError('Login Failed',403));
|
|
}
|
|
}catch (Exception $e) {
|
|
API::error(new ApiError('Login Failed',403));
|
|
}
|
|
}else{
|
|
API::error(new ApiError('Login Failed',403));
|
|
}
|
|
|
|
}
|
|
|
|
static function getAuthorizationHeader(){
|
|
$headers = null;
|
|
if (isset($_SERVER['Authorization'])) {
|
|
$headers = trim($_SERVER["Authorization"]);
|
|
}
|
|
else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
|
|
$headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
|
|
} elseif (function_exists('apache_request_headers')) {
|
|
$requestHeaders = apache_request_headers();
|
|
// Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
|
|
$requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
|
|
//print_r($requestHeaders);
|
|
if (isset($requestHeaders['Authorization'])) {
|
|
$headers = trim($requestHeaders['Authorization']);
|
|
}
|
|
}
|
|
return $headers;
|
|
}
|
|
|
|
static function getBearerToken() {
|
|
$headers = self::getAuthorizationHeader();
|
|
if (!empty($headers)) {
|
|
if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
|
|
return $matches[1];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
static function getLoginAccess() {
|
|
$headers = self::getAuthorizationHeader();
|
|
if (!empty($headers)) {
|
|
if (preg_match('/Login\s(\S+)/', $headers, $matches)) {
|
|
|
|
$result = base64_decode($matches[1]);
|
|
if (!$result) API::error(new ApiError("Invalid Login"));
|
|
return explode(":",$result);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
} |