shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

d_validator.php (18128B)


      1 <?php
      2 
      3 class ControllerextensionDShopunityDValidator extends Controller
      4 {
      5     protected $pack;
      6     protected $error;
      7     protected $expire;
      8     protected $module;
      9     protected $validator;
     10     protected $d_validator;
     11     protected $module_name;
     12     protected $validate_error;
     13     protected $module_codename;
     14     protected $d_opencart_patch;
     15     protected $codename = 'd_validator';
     16     protected $route = 'extension/d_shopunity/d_validator';
     17 
     18     public function __construct($registry)
     19     {
     20         parent::__construct($registry);
     21 
     22         $this->load->language($this->route);
     23         $this->d_validator = (file_exists(DIR_SYSTEM . 'library/d_shopunity/extension/d_validator.json'));
     24         $this->d_opencart_patch = (file_exists(DIR_SYSTEM . 'library/d_shopunity/extension/d_opencart_patch.json'));
     25     }
     26 
     27     public function index()
     28     {
     29         $this->installCompatibility();
     30     }
     31 
     32     public function installCompatibility()
     33     {
     34         $this->load->model('extension/d_shopunity/d_validator');
     35         $this->model_extension_d_shopunity_d_validator->installModule();
     36     }
     37 
     38     public function form()
     39     {
     40         $json = array();
     41 
     42         if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
     43             $this->load->language($this->route);
     44 
     45             $market = $this->request->post['market'];
     46             $email = $this->request->post['email'];
     47             $order_id = $this->request->post['order_id'];
     48             $codename = trim($this->request->post['codename']);
     49             $result = json_decode($this->request($market, $email, $order_id, $codename));
     50 
     51             if (isset($result->success) && isset($result->licence)) {
     52                 $key = $this->strToHex($codename);
     53 
     54                 $encrypted = base64_decode($result->licence);
     55                 $decrypted = SaferCrypto::decrypt($encrypted, $key);
     56 
     57                 if ($decrypted) {
     58                     $this->saveLicenceToFile($codename, $result->licence);
     59 
     60                     if($this->validateLicense($decrypted, $codename)){
     61                         $json['success'] = $this->language->get('license_is_valid');
     62                     }else{
     63                         $json['warning'] = $this->validate_error;
     64                     }
     65 
     66                 }else{
     67                     $json['warning'] = $this->language->get('license_is_expired');
     68                 }
     69             } else {
     70                 if (isset($result->error)) {
     71                     $json['warning'] = $result->error;
     72                 }
     73             }
     74         }else{
     75             $json['error'] = $this->error;
     76         }
     77 
     78         $this->response->addHeader('Content-Type: application/json');
     79         $this->response->setOutput(json_encode($json));
     80     }
     81 
     82     public
     83     function validate()
     84     {
     85         $fields = [
     86             'market',
     87             'email',
     88             'order_id',
     89             'codename'
     90         ];
     91 
     92         foreach ($fields as $field) {
     93             if (!$this->request->post[$field]) {
     94                 $this->error[$field] = $this->language->get('field_require');
     95             }
     96         }
     97 
     98         return !$this->error;
     99     }
    100 
    101     function strToHex($string)
    102     {
    103         $hex = '';
    104         for ($i = 0; $i < strlen($string); $i++) {
    105             $hex .= dechex(ord($string[$i]));
    106         }
    107         return $hex;
    108     }
    109 
    110     public
    111     function view(&$route, &$args, &$output)
    112     {
    113         $this->load->language($this->route);
    114         $this->load->model('extension/d_shopunity/d_validator');
    115         $this->model_extension_d_shopunity_d_validator->createTable();
    116 
    117         $this->expire = false;
    118 
    119         $url_parts = explode("/", $route);
    120 
    121         foreach ($url_parts as $url_part) {
    122             if (strpos($url_part, 'd_') !== false) {
    123                 $this->module = trim($url_part);
    124             }
    125         }
    126 
    127         if ($this->module && $this->validationFileJsonCommercialByRoute($route)) {
    128             $licence = $this->getLicenceByFile();
    129 
    130             if ($licence) {
    131                 $key = $this->strToHex($this->module_codename);
    132 
    133                 $encrypted = base64_decode($licence);
    134                 $decrypted = SaferCrypto::decrypt($encrypted, $key);
    135 
    136                 if ($decrypted) {
    137 
    138                     if(!$this->validateLicense($decrypted, $this->module_codename)){
    139                         $this->decideShowOrNot();
    140                     }
    141 
    142                 }else{
    143                     $this->decideShowOrNot();
    144                 }
    145 
    146             } else {
    147                 $this->decideShowOrNot();
    148             }
    149         }
    150 
    151         if ($this->expire) {
    152 
    153             $html = $this->expire;
    154 
    155             $html_dom = new d_simple_html_dom();
    156 
    157             $html_dom->load((string)$output, $lowercase = true, $stripRN = false, $defaultBRText = DEFAULT_BR_TEXT);
    158 
    159             $findSelector = $html_dom->find('#content>.page-header', 0);
    160 
    161             if ($findSelector) {
    162                 $html_dom->find('#content>.page-header', 0)->outertext .= $html;
    163             }
    164 
    165             $output = (string)$html_dom;
    166         }
    167     }
    168 
    169     public function validationFileJsonCommercialByRoute($route)
    170     {
    171         $this->load->config($this->codename);
    172         $modules = $this->config->get($this->codename . '_modules');
    173 
    174         foreach ($modules as $module) {
    175             if (isset($module['route']) && $module['route'] == $route) {
    176 
    177                 if (is_array($module['json'])) {
    178                     foreach ($module['json'] as $key => $json) {
    179                         $filePath = DIR_SYSTEM . "library/d_shopunity/extension/" . $json;
    180 
    181                         if (false !== ($contents = @file_get_contents($filePath, true))) {
    182                             $file = json_decode($contents);
    183                         }
    184 
    185                         if (isset($file) && isset($file->license->type) && $file->license->type == 'commercial') {
    186                             $this->module_codename = $module['codename'][$key];
    187                             $this->module_name = $file->name;
    188 
    189                             return true;
    190                         }
    191                     }
    192                 }
    193 
    194                 $filePath = DIR_SYSTEM . "library/d_shopunity/extension/" . $module['json'];
    195 
    196                 if (false !== ($contents = @file_get_contents($filePath, true))) {
    197                     $file = json_decode($contents);
    198                 }
    199 
    200                 if (isset($file) && isset($file->license->type) && $file->license->type == 'commercial') {
    201                     $this->module_codename = $module['codename'];
    202                     $this->module_name = $file->name;
    203 
    204                     return true;
    205                 }
    206             }
    207         }
    208 
    209         return false;
    210     }
    211 
    212     public function getLicenceByFile()
    213     {
    214         $filePath = DIR_SYSTEM . "library/d_shopunity/license/" . $this->module_codename . ".txt";
    215         $fileExists = (file_exists($filePath));
    216 
    217         if ($fileExists) {
    218             $content = file_get_contents($filePath);
    219 
    220             if ($content) {
    221                 return $content;
    222             }
    223         }
    224 
    225         return false;
    226     }
    227 
    228     public function validateLicense($decoded_licence, $codename)
    229     {
    230         $this->load->language($this->route);
    231 
    232         $data = json_decode($decoded_licence);
    233 
    234         $url = $this->getSiteURl();
    235 
    236         if ($data && isset($data->url) && isset($data->codename) && isset($data->date_expired)) {
    237             if ($data->url != $url){
    238                 $this->validate_error = $this->language->get('license_error_url');
    239             }
    240 
    241             if ($data->codename != $codename) {
    242                 $this->validate_error = $this->language->get('license_error_codename');
    243             }
    244 
    245             if ($this->isExpire($data->date_expired)){
    246                 $this->validate_error = $this->language->get('license_is_expired');
    247             }
    248 
    249         }else{
    250             $this->validate_error = $this->language->get('license_error');
    251         }
    252 
    253         return !$this->validate_error;
    254     }
    255 
    256     public function saveLicenceToFile($codename, $license)
    257     {
    258         $fonderPath = DIR_SYSTEM . "library/d_shopunity/license";
    259         $fileExists = (file_exists($fonderPath));
    260 
    261         if (!$fileExists) {
    262             $tags = explode('/', $fonderPath);
    263             $mkDir = "";
    264 
    265             foreach ($tags as $folder) {
    266                 $mkDir = $mkDir . $folder . "/";
    267                 if (!is_dir($mkDir)) {
    268                     mkdir($mkDir, 0777);
    269                 }
    270             }
    271         }
    272 
    273         $filePath = DIR_SYSTEM . "library/d_shopunity/license/" . $codename . ".txt";
    274         return file_put_contents($filePath, $license, LOCK_EX);
    275     }
    276 
    277     public function decideShowOrNot()
    278     {
    279         $this->load->model('extension/d_shopunity/d_validator');
    280         $result = $this->model_extension_d_shopunity_d_validator->getTimeByCodename($this->module_codename);
    281 
    282         if ($result) {
    283             if ($this->isShow($result['date_show'])) {
    284                 $view = $this->generateExpireView();
    285 
    286                 $this->expire = $view;
    287             }
    288         } else {
    289             $view = $this->generateExpireView();
    290 
    291             $this->expire = $view;
    292         }
    293     }
    294 
    295     public
    296     function generateExpireView()
    297     {
    298         $data = array();
    299 
    300         $data['module_name'] = $this->module_name;
    301         $data['codename'] = $this->module_codename;
    302 
    303         $data['text'] = sprintf($this->language->get('license_expired'), $data['module_name']);
    304         $data['help'] = $this->language->get('license_visit_text');
    305 
    306         $this->load->model('extension/d_opencart_patch/url');
    307         $data['action'] = $this->model_extension_d_opencart_patch_url->ajax($this->route . '/form');
    308         $data['action_remind'] = $this->model_extension_d_opencart_patch_url->ajax($this->route . '/remind');
    309 
    310         $this->load->model('extension/d_opencart_patch/load');
    311         $view = $this->model_extension_d_opencart_patch_load->view('extension/d_shopunity/d_validator', $data);
    312 
    313         $this->expire = $view;
    314 
    315         return $view;
    316     }
    317 
    318     public function remind()
    319     {
    320         $json = array();
    321 
    322         if (($this->request->server['REQUEST_METHOD'] == 'POST')) {
    323             $module = $this->request->post['module'];
    324 
    325             $data = array();
    326             $data['codename'] = $this->request->post['module'];
    327             $data['date_created'] = date("Y-m-d H:i:s");
    328             $data['date_show'] = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s") . " + 7 day"));
    329 
    330             $this->load->model('extension/d_shopunity/d_validator');
    331             $result = $this->model_extension_d_shopunity_d_validator->getTimeByCodename($module);
    332 
    333             if ($result) {
    334                 $result = $this->model_extension_d_shopunity_d_validator->updateTimeByCodename($module, $data);
    335             } else {
    336                 $result = $this->model_extension_d_shopunity_d_validator->insertTime($data);
    337             }
    338 
    339             $json['success'] = true;
    340         }
    341 
    342         $this->response->addHeader('Content-Type: application/json');
    343         $this->response->setOutput(json_encode($json));
    344     }
    345 
    346     public function request($market, $email, $order_id, $codename)
    347     {
    348         $url = $this->getSiteURl();
    349 
    350         $data = array(
    351             'codename' => $codename,
    352             'market' => $market,
    353             'order_id' => $order_id,
    354             'email' => $email,
    355             'url' => $url
    356         );
    357 
    358         $payload = json_encode($data);
    359 
    360         $this->load->config($this->codename);
    361         $setting = $this->config->get($this->codename . '_setting');
    362 
    363         if (isset($this->request->post['validateShopunity'])){
    364             $url = $setting['api_url_shopunity'];
    365         }else{
    366             $url = $setting['api_url'];
    367         }
    368 
    369         $ch = curl_init($url);
    370         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    371         curl_setopt($ch, CURLINFO_HEADER_OUT, true);
    372         curl_setopt($ch, CURLOPT_POST, true);
    373         curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    374 
    375         curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    376                 'Content-Type: application/json',
    377                 'Content-Length: ' . strlen($payload))
    378         );
    379 
    380         $result = curl_exec($ch);
    381         curl_close($ch);
    382 
    383         return $result;
    384     }
    385 
    386     public
    387     function isExpire($date_expire)
    388     {
    389         $now = new DateTime();
    390         $expire = new DateTime($date_expire);
    391 
    392         if ($expire > $now) {
    393             return 0;
    394         } else {
    395             return 1;
    396         }
    397     }
    398 
    399     public
    400     function isShow($date_show)
    401     {
    402         $now = new DateTime();
    403         $expire = new DateTime($date_show);
    404 
    405         if ($now > $expire) {
    406             return 1;
    407         } else {
    408             return 0;
    409         }
    410     }
    411 
    412     public function getSiteURl()
    413     {
    414         $url = null;
    415 
    416         if (defined('HTTPS_CATALOG')) {
    417             $url = HTTPS_CATALOG;
    418         } elseif (defined('HTTP_CATALOG')) {
    419             $url = HTTP_CATALOG;
    420         } else {
    421             $url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ?
    422                     "https" : "http") . "://" . $_SERVER['HTTP_HOST'];
    423         }
    424 
    425         return $url;
    426     }
    427 }
    428 
    429 
    430 class UnsafeCrypto
    431 {
    432     const METHOD = 'aes-256-ctr';
    433 
    434     /**
    435      * Encrypts (but does not authenticate) a message
    436      *
    437      * @param string $message - plaintext message
    438      * @param string $key - encryption key (raw binary expected)
    439      * @param boolean $encode - set to TRUE to return a base64-encoded
    440      * @return string (raw binary)
    441      */
    442     public static function encrypt($message, $key, $encode = false)
    443     {
    444         $nonceSize = openssl_cipher_iv_length(self::METHOD);
    445         $nonce = openssl_random_pseudo_bytes($nonceSize);
    446 
    447         $ciphertext = openssl_encrypt(
    448             $message,
    449             self::METHOD,
    450             $key,
    451             OPENSSL_RAW_DATA,
    452             $nonce
    453         );
    454 
    455         // Now let pack the IV and the ciphertext together
    456         // Naively, we can just concatenate
    457         if ($encode) {
    458             return base64_encode($nonce . $ciphertext);
    459         }
    460         return $nonce . $ciphertext;
    461     }
    462 
    463     /**
    464      * Decrypts (but does not verify) a message
    465      *
    466      * @param string $message - ciphertext message
    467      * @param string $key - encryption key (raw binary expected)
    468      * @param boolean $encoded - are we expecting an encoded string?
    469      * @return string
    470      */
    471     public static function decrypt($message, $key, $encoded = false)
    472     {
    473         if ($encoded) {
    474             $message = base64_decode($message, true);
    475             if ($message === false) {
    476                 throw new Exception('Encryption failure');
    477             }
    478         }
    479 
    480         $nonceSize = openssl_cipher_iv_length(self::METHOD);
    481         $nonce = mb_substr($message, 0, $nonceSize, '8bit');
    482         $ciphertext = mb_substr($message, $nonceSize, null, '8bit');
    483 
    484         $plaintext = openssl_decrypt(
    485             $ciphertext,
    486             self::METHOD,
    487             $key,
    488             OPENSSL_RAW_DATA,
    489             $nonce
    490         );
    491 
    492         return $plaintext;
    493     }
    494 }
    495 
    496 class SaferCrypto extends UnsafeCrypto
    497 {
    498     const HASH_ALGO = 'sha256';
    499 
    500     /**
    501      * Encrypts then MACs a message
    502      *
    503      * @param string $message - plaintext message
    504      * @param string $key - encryption key (raw binary expected)
    505      * @param boolean $encode - set to TRUE to return a base64-encoded string
    506      * @return string (raw binary)
    507      */
    508     public static function encrypt($message, $key, $encode = false)
    509     {
    510         list($encKey, $authKey) = self::splitKeys($key);
    511 
    512         // Pass to UnsafeCrypto::encrypt
    513         $ciphertext = parent::encrypt($message, $encKey);
    514 
    515         // Calculate a MAC of the IV and ciphertext
    516         $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true);
    517 
    518         if ($encode) {
    519             return base64_encode($mac . $ciphertext);
    520         }
    521         // Prepend MAC to the ciphertext and return to caller
    522         return $mac . $ciphertext;
    523     }
    524 
    525     /**
    526      * Decrypts a message (after verifying integrity)
    527      *
    528      * @param string $message - ciphertext message
    529      * @param string $key - encryption key (raw binary expected)
    530      * @param boolean $encoded - are we expecting an encoded string?
    531      * @return string (raw binary)
    532      */
    533     public static function decrypt($message, $key, $encoded = false)
    534     {
    535         list($encKey, $authKey) = self::splitKeys($key);
    536         if ($encoded) {
    537             $message = base64_decode($message, true);
    538             if ($message === false) {
    539                 throw new Exception('Encryption failure');
    540             }
    541         }
    542 
    543         // Hash Size -- in case HASH_ALGO is changed
    544         $hs = mb_strlen(hash(self::HASH_ALGO, '', true), '8bit');
    545         $mac = mb_substr($message, 0, $hs, '8bit');
    546 
    547         $ciphertext = mb_substr($message, $hs, null, '8bit');
    548 
    549         $calculated = hash_hmac(
    550             self::HASH_ALGO,
    551             $ciphertext,
    552             $authKey,
    553             true
    554         );
    555 
    556         if (!self::hashEquals($mac, $calculated)) {
    557             throw new Exception('Encryption failure');
    558         }
    559 
    560         // Pass to UnsafeCrypto::decrypt
    561         $plaintext = parent::decrypt($ciphertext, $encKey);
    562 
    563         return $plaintext;
    564     }
    565 
    566     /**
    567      * Splits a key into two separate keys; one for encryption
    568      * and the other for authenticaiton
    569      *
    570      * @param string $masterKey (raw binary)
    571      * @return array (two raw binary strings)
    572      */
    573     protected static function splitKeys($masterKey)
    574     {
    575         // You really want to implement HKDF here instead!
    576         return [
    577             hash_hmac(self::HASH_ALGO, 'ENCRYPTION', $masterKey, true),
    578             hash_hmac(self::HASH_ALGO, 'AUTHENTICATION', $masterKey, true)
    579         ];
    580     }
    581 
    582     /**
    583      * Compare two strings without leaking timing information
    584      *
    585      * @param string $a
    586      * @param string $b
    587      * @ref https://paragonie.com/b/WS1DLx6BnpsdaVQW
    588      * @return boolean
    589      */
    590     protected static function hashEquals($a, $b)
    591     {
    592         if (function_exists('hash_equals')) {
    593             return hash_equals($a, $b);
    594         }
    595         $nonce = openssl_random_pseudo_bytes(32);
    596         return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce);
    597     }
    598 }