/vihu.php
PHP | 404 lines | 299 code | 85 blank | 20 comment | 73 complexity | 0e441769453b812af849b734be431eea MD5 | raw file
- <?php
- //RETIRA WARNINGS E NOTICE
- error_reporting(E_ERROR);
-
- //CONSTANTES
- const PATH = '/home/vihu/php/';
- //const PATH = './';
-
- const DOMAIN = 'api.vihu.ml';
- // const DOMAIN = 'api.vihu.com.br';
- const PWD = 'Vihu#Cond@dmin_2018';
- const SECRET_KEY = 'U2VjcmV0S2V5T2ZWaWh1QDc3Nw=='; //SecretKeyOfVihu@777
- const URL = 'https://'.DOMAIN;
- const TOKEN = PATH . 'vihu-token.key';
- const ACCESS = PATH . 'vihu-access.json';
- const LOG = PATH . 'vihu-log.txt';
- const LOG_ACCESS = PATH . 'vihu-log-access.txt';
- const DEBUG = true;
- const RESULTS = [
- "DELIVERY" => ["type"=>"DELIVERY", "audio"=>"/home/vihu/libera_portao.wav", "open"=>false, "call"=>true],
- "ACESSO_VISITANTE" => ["type"=>"ACESSO_VISITANTE", "audio"=>"/home/vihu/audio/Entrada_autorizada.wav", "open"=>true, "call"=>true],
- "ACESSO_LIBERADO" => ["type"=>"ACESSO_LIBERADO", "audio"=>"/home/vihu/audio/libera_portao.wav", "open"=>true, "call"=>false],
- "ACESSO_INVALIDO" => ["type"=>"ACESSO_INVALIDO", "audio"=>"/home/vihu/audio/Entrada_nao_autorizada.wav", "open"=>false, "call"=>false],
- "ACESSO_MORADOR_RFID" => ["type"=>"ACESSO_MORADOR_RFID", "audio"=>"/home/vihu/audio/libera_portao.wav", "open"=>true, "call"=>false],
- "ACESSO_GARAGEM_RFID" => ["type"=>"ACESSO_GARAGEM_RFID", "audio"=>"/home/vihu/audio/libera_portao.wav", "open"=>true, "call"=>false]
- ];
- function debug($value) {
- if (!DEBUG) return;
- if (!file_exists(LOG)) {
- $handle = fopen(LOG,'w+');
- fwrite($handle, '');
- fclose($handle);
- }
-
- file_put_contents(LOG, date("c") . " - " . $value . "\n", FILE_APPEND);
- }
- function logAccess($value) {
- $data = [];
- if (!file_exists(LOG_ACCESS)) {
- $handle = fopen(LOG_ACCESS,'w+');
- fwrite($handle, '');
- fclose($handle);
- } else {
- $data = json_decode(file_get_contents(LOG_ACCESS));
- if (count($data) == 0) {
- $data = [];
- }
- }
- array_push($data, $value);
- file_put_contents(LOG_ACCESS, json_encode($data));
- }
- function isConnected() {
- debug('CONNECTION: INIT CHECK');
- $connected = @fsockopen(DOMAIN, 80); //website, port (try 80 or 443)
- if ($connected){
- $is_conn = true; //action when connected
- fclose($connected);
- } else {
- $is_conn = false; //action in connection failure
- }
- debug('CONNECTION: ' . $is_conn);
- return boolval($is_conn);
- }
-
- function callAPI($method, $url, $data = false) {
- $curl = curl_init();
-
- switch ($method) {
- case "POST":
- curl_setopt($curl, CURLOPT_POST, 1);
-
- if ($data)
- curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
- break;
- case "PUT":
- curl_setopt($curl, CURLOPT_PUT, 1);
- break;
- default:
- if ($data)
- $url = sprintf("%s?%s", $url, http_build_query($data));
- }
- if (file_exists(TOKEN)) {
- $authorization = "Authorization: Bearer ".file_get_contents(TOKEN);
- curl_setopt($curl, CURLOPT_HTTPHEADER, [$authorization]);
- }
- curl_setopt($curl, CURLOPT_URL, $url);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
-
- $result = curl_exec($curl);
- curl_close($curl);
-
- return $result;
- }
- function monstroEncrypt($pwd) {
- // Remove the base64 encoding from our key
- $encryption_key = base64_decode(SECRET_KEY);
-
- // Generate an initialization vector
- $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
-
- // Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector.
- $encrypted = openssl_encrypt($pwd, 'aes-256-cbc', $encryption_key, 0, $iv);
- // The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)
- return base64_encode($encrypted . '::' . $iv);
- }
- function monstroDecrypt($pwd) {
- // Remove the base64 encoding from our key
- $encryption_key = base64_decode(SECRET_KEY);
- // To decrypt, split the encrypted data from our IV - our unique separator used was "::"
- list($encrypted_data, $iv) = explode('::', base64_decode($pwd), 2);
-
- return openssl_decrypt($encrypted_data, 'aes-256-cbc', $encryption_key, 0, $iv);
- }
- function syncDown() {
- $accesses = json_decode(callAPI('GET', URL . '/api/access/v2/sync-down'));
- $localData = json_decode(file_get_contents(ACCESS));
-
- if (!$localData->locked) {
- $localData = $accesses;
- updateLocalData(json_encode($localData));
- }
- }
- function syncUp() {
- $accessesToSync = [];
- $localData = json_decode(file_get_contents(ACCESS));
- foreach ( $localData->data->visitantes as $visitante){
- if ($visitante->sync) {
- array_push($accessesToSync, $visitante);
- }
- }
- if (file_exists(LOG_ACCESS)) {
- $logAccess = json_decode(file_get_contents(LOG_ACCESS));
- unlink(LOG_ACCESS);
- }
-
- $result = callAPI('POST', URL . '/api/access/v2/sync-up', json_encode(["accesses" => $accessesToSync, "logAccess" => $logAccess]));
- debug($result);
- }
- function updateLocalData($data) {
- $handle = fopen(ACCESS,'w+');
- fwrite($handle, $data);
- fclose($handle);
- }
- function validateResident($_code, $_keyboard) {
- debug('ACCESS (resident): ' . $_code . ' | ' . $_keyboard);
- $localData = json_decode(file_get_contents(ACCESS));
- $resultAccess = [];
- if (!$localData->data || $_code == '123456') {
- $resultAccess["type"] = "ACESSO_INVALIDO";
- return $resultAccess;
- }
- //VERIFICA SE É CHAVEIRO DE MORADOR
- if (strlen($_code) > 6) {
- foreach ($localData->data->moradores as $morador) {
- foreach ($morador->rfid_keys as $rfid_key) {
- if ($_code == $rfid_key->code) {
- logAccess([
- 'user_id' => $morador->id,
- 'condominiums_id' => $localData->data->condominio->id,
- 'keyboard' => $_keyboard,
- 'type' => 2,
- 'ip' => getHostByName(getHostName())
- ]);
-
- $resultAccess["type"] = "ACESSO_MORADOR_RFID";
- return $resultAccess;
- }
- }
- }
- }
-
- //VERIFICA SE O CODIGO EXISTE PARA ALGUM MORADOR
- $_codeEncrypted = sha1($_code);
- debug($_codeEncrypted);
- foreach ($localData->data->moradores as $morador) {
- if ($_codeEncrypted == $morador->access_code) {
- logAccess([
- 'user_id' => $morador->id,
- 'condominiums_id' => $localData->data->condominio->id,
- 'keyboard' => $_keyboard,
- 'type' => 1,
- 'ip' => getHostByName(getHostName())
- ]);
- $resultAccess["type"] = "ACESSO_LIBERADO";
- return $resultAccess;
- }
- }
- $resultAccess["type"] = "ACESSO_INVALIDO";
- return $resultAccess;
- }
- function validateAccessLocal($_code, $_keyboard) {
- debug('ACCESS (offline): ' . $_code . ' | ' . $_keyboard);
- $localData = json_decode(file_get_contents(ACCESS));
- $resultAccess = [];
- if (!$localData->data || $_code == '123456') {
- $resultAccess["type"] = "ACESSO_INVALIDO";
- return $resultAccess;
- }
- //VERIFICA SE O CODIGO EXISTE PARA ALGUM VISITANTE
- foreach ($localData->data->visitantes as $visitante) {
- if ($visitante->code == $_code && validateDeadline($visitante)) {
-
- if ($visitante->status != "ativo") {
- $resultAccess["type"] = "ACESSO_INVALIDO";
- return $resultAccess;
- }
- $__keyboard = ($visitante->gates == 'null') ? NULL : $visitante->gates;
- foreach ($__keyboard as $k) {
- if ($k->gate == $_keyboard) {
- $resultAccess["type"] = "ACESSO_INVALIDO";
- return $resultAccess;
- }
- }
- //PEGA DADOS DO APARTAMENTO DO MORADOR QUE ENVIOU O ACESSO
- foreach ($localData->data->moradores as $morador) {
- if ($morador->id == $visitante->users_id) {
- $resultAccess["ramal"] = $morador->units[0]->extension_number;
- $resultAccess["call"] = $localData->data->condominio->communication_type->intercom;
- }
- }
- $newKeyboard = [
- 'gate' => $_keyboard,
- 'datetime' => date("Y-m-d H:i:s")
- ];
-
- if ($visitante->type != 'delivery') {
- if ($__keyboard) {
- array_push($__keyboard, $newKeyboard);
- $visitante->gates = $__keyboard;
- } else {
- $visitante->gates = [$newKeyboard];
- }
- $visitante->validations = $visitante->validations + 1;
- $visitante->sync = true;
-
- if (($localData->data->condominio->number_of_gates == $visitante->validations) || ($_keyboard == $localData->data->condominio->number_of_gates) || ($visitante->exit)) {
- $visitante->status = 2;
- }
- //ATUALIZA ARQUIVO
- updateLocalData(json_encode($localData));
- //VEIRIFICA SE É A PRIMEIRA VALIDAÇÃO PARA AVISAR O MORADOR
- $resultAccess["type"] = ($visitante->validations == 1) ? "ACESSO_VISITANTE" : "ACESSO_LIBERADO";
- return $resultAccess;
- } else {
- //CASO FOR DELIVERY, VERIFICA SE CONDOMINIO TEM INTERFONE
- if (!$resultAccess["call"]) {
- $resultAccess["type"] = "ACESSO_INVALIDO";
- return $resultAccess;
- }
- $visitante->gates = [$newKeyboard];
- $visitante->validations = $visitante->validations + 1;
- $visitante->sync = true;
- $visitante->status = 2;
- //ATUALIZA ARQUIVO
- updateLocalData(json_encode($localData));
-
- $resultAccess["type"] = "DELIVERY";
- return $resultAccess;
- }
- }
- }
-
- $resultAccess["type"] = "ACESSO_INVALIDO";
- return $resultAccess;
- }
- function validateDeadline($access) {
- $before = new DateTime($access->date.' '. $access->time, new DateTimeZone('America/Sao_Paulo'));
- $before->modify('-30 minutes');
- $after = new DateTime($access->date.' '. $access->time, new DateTimeZone('America/Sao_Paulo'));
- $after->modify('+3 hours');
-
- $now = new DateTime();
- $now = $now->setTimezone(new DateTimeZone('America/Sao_Paulo'));
- if ($now >= $before && $now <= $after) {
- return true;
- }
- return false;
- }
- function getToken() {
- $pwd = monstroEncrypt(PWD);
- $result = json_decode(callAPI('POST', URL . '/api/vihubox/install', ['password'=>$pwd]));
-
- if ($result->status == 'SUCCESS') {
- $handle = fopen(TOKEN,'w+');
- fwrite($handle, $result->token);
- fclose($handle);
- return true;
- }
- return $result;
- }
- //INICIO
- $code = null;
- $keyboard = null;
- $result = null;
- debug('-------------');
- debug('INIT: ' . $argv[1]);
- if (!file_exists(ACCESS)) {
- updateLocalData(json_encode([]));
- }
-
- if ($argv[1] == 'INSTALL') {
- $result = getToken();
- if ($result === true) {
- syncDown();
- echo "SUCCESS";
- } else {
- echo $result;
- }
- } else if ($argv[1] == 'ACCESS') {
-
- $code = ($argv[2]) ? $argv[2] : null;
- $keyboard = ($argv[3]) ? $argv[3] : null;
- debug('ACCESS: ' . $code . ' | ' . $keyboard);
- $result = validateResident($code, $keyboard);
- if (isConnected() == true && strlen($code) == 6 && $result['type'] == 'ACESSO_INVALIDO') {
-
- debug('ACCESS: Call API');
- $result = callAPI('GET', URL . '/api/access/v2/'.$code.'/'.$keyboard);
-
- debug('ACCESS (result): ' . $result);
- $result = base64_decode($result);
- $result = json_decode($result, true);
- } else if ($result['type'] == 'ACESSO_INVALIDO') {
- debug('ACCESS: Offline');
- $result = validateAccessLocal($code, $keyboard);
- }
- //FORMATA RESULTADO PARA ENVIAR AO VIHUBOX
- try {
- debug('ACCESS (result): ' . json_encode($result));
- $print = new ArrayObject(RESULTS[$result["type"]]);
- } catch(Exception $e) {
- debug('ACCESS (catch): ' . $e->getMessage());
- $print = new ArrayObject(RESULTS["ACESSO_INVALIDO"]);
- }
- $print["ramal"] = $result["ramal"];
- $print["call"] = (!$result["call"]) ? false : $print["call"];
- print_r(json_encode($print));
- } else if ($argv[1] == 'SYNC') {
-
- if (isConnected()) {
- syncUp();
- syncDown();
- }
- }
- ?>