Updating from Prestashop 1.6 MD5 encryption to 1.7 - encryption

I am updating my PS 1.6 to 1.7. I know PS 1.6 uses this encryption method md5(_COOKIE_KEY_.$passwd) but we converted it to md5($passwd) previously for having compatibility with our previous shop not-prestashop.
Now we want to update to 1.7 and we see that the encryption method has changed to hash(). We have achieved to log in previous users changing this function: getByEmail(), but now we want the register to work well (saving the password as md5($plaintextpassword)). We know that the new encryption method is much more secure and is not recommended to use md5($plaintextpassword) but now we cannot change that.
We have changed in Classes/Customer.php all lines from:
$this->passwd = $crypto->hash($password);
to:
$this->passwd = md5($password);
But with all this changes when we register a new user, it's saved as the hash() method in this format $2y$10$VPm9ygay2ldd0Vu0J4ttQuOdD/mIytURV/nXCXKs4GcB4AkIWtaQm instead of this: bcef5cffa6f4bb0abb94cf6fa7a7cb2f. I don't find where I have to change to save in the desired format?

You have to override PrestaShop and add new additional password checker:
if(!loginWithOriginalMethod($password)) {
loginWithAdditionalMethod($password);
}
By using this way, both your new and old customers can login to your store

If you could import the previous 1.6 hash as is directly in the DB and you kept the same cookie key, the function is backward compatible.
But if like me the 1.6 hash have been re-hashed with a new cookie key as I imported using the csv functionality, you need to update src/Core/Crypto/Hashing.php, replace the last function by:
Ensure to replace <your 1.6 cookie key> by the cookie key from Prestashop 1.6
private function initHashMethods()
{
$this->hashMethods = array(
'bcrypt' => array(
'option' => array(),
'hash' => function ($passwd, $staticSalt, $option) {
return password_hash($passwd, PASSWORD_BCRYPT);
},
'verify' => function ($passwd, $hash, $staticSalt) {
/*
* Prevent enumeration because nothing happens
* when there is no, or an invalid hash.
* Also, change the password to be sure it's not maching
* the new hash.
* The new hash is equal to 'test' in BCRYPT context.
*/
if (empty($hash)) {
$hash = '$2y$10$azRqq.pN0OlWjeVfVMZXOOwqYAx1hMfme6ZnDV.27grGOEZvG.uAO';
$passwd = 'wrongPassword';
}
return password_verify($passwd, $hash);
},
),
'md5' => array(
'option' => array(),
'hash' => function ($passwd, $staticSalt, $option) {
return md5($staticSalt . $passwd);
},
'verify' => function ($passwd, $hash, $staticSalt) {
return md5($staticSalt . $passwd) === $hash;
},
),
'bcryptmd5' => array(
'option' => array(),
'hash' => function ($passwd, $staticSalt, $option) {
return password_hash(md5('<your 1.6 cookie key>' . $passwd), PASSWORD_BCRYPT);
},
'verify' => function ($passwd, $hash, $staticSalt) {
/*
* Prevent enumeration because nothing happens
* when there is no, or an invalid hash.
* Also, change the password to be sure it's not maching
* the new hash.
* The new hash is equal to 'test' in BCRYPT context.
*/
if (empty($hash)) {
$hash = '$2y$10$azRqq.pN0OlWjeVfVMZXOOwqYAx1hMfme6ZnDV.27grGOEZvG.uAO';
$passwd = 'wrongPassword';
}
return password_verify(md5('<your 1.6 cookie key>' . $passwd), $hash);
},
),
);
}

Related

401(woocommerce_api_user_cannot_read_product) response--Woocommerce REST API

the API works when ck_ and cs_ keys are for Admin and returns the std class object but when keys are for a different user returns You do not have permission to read this product 401(woocommerce_api_user_cannot_read_product) Error response: even when user has read/write privileges. but goes ahead to create the product in the database. Any help on this issue is highly appreciated
require_once( 'lib/woocommerce-api.php' );
$options = array(
'debug' => true,
'return_as_array' => false,
'validate_url' => false,
'timeout' => 30,
'ssl_verify' => false,
);
try {
$client = new WC_API_Client( $the_url, 'ck_xxxx', 'cs_xxxx', $options);
Try adding into your $options array:
$options['query_string_auth'] = true;
As noted in the documentation this will "Force Basic Authentication as query string true" in other words it will append your consumer key and consumer secret to your request URL as a query string. This is only supported on HTTPS.

FMElfinderBundle 5 - how to set temp folder for upload

I am using FMElfinderBundle v.5 (for some reasons I cannot use latest version) with Symfony 2.8.12. I followed documentation and it worked fine, until there was request to allow upload large files (up to 20MB). I changed upload_max_size parameter to 20M and it was ok, but during upload files are split to 2MB chunks and elfinder tries to store them in temp directory. Problem is, that it has no access there. It does not read settings from virtual host definition, it always uses system temp folder.
Reading documentation I have found that there can be used two parameters for configuring elfinder temp dir - upload_temp_path and common_temp_path. But i didn't have luck with setting them. Every time I run in PHPStorm console command s cache: clear --no-warmup I get InvalidConfigurationException.
I tried to put parameters somewhere else in config structure under fm_elfinder key, but still the same exception.
This is my configuration in config.yml:
fm_elfinder:
instances:
default:
locale: %locale%
editor: ckeditor
fullscreen: true
theme: smoothness
include_assets: true
relative_path: false
connector:
roots:
uploads:
driver: LocalFileSystem
path: uploads
upload_max_size: 20M
Anyone please can help me, how to set temp dir?
Ok, some detailed info:
I took ElFinderConfigurationReader from ElFinder bundle and saved it into my project under name ElFinderConfigurationCustomReader. Then this class i defined as a service:
service.custom_fm_elfinder.configurator:
class: CSBN\SVJBundle\Component\ElFinder\ElFinderConfigurationCustomReader
arguments: ['%fm_elfinder%', '#request_stack', '#service_container', '%elfinder_temporary_path%']
variable elfinder_temporary_path is set in parameters.yml.
in config.yml i set my own configuration reader:
fm_elfinder:
configuration_provider: service.custom_fm_elfinder.configurator
And in my newly created file ElFinderConfigurationCustomReader i just in method getConfiguration added one row:
$options['uploadTempPath'] = $this->temporaryPath;
which is taken from service parameters in constructor.
Hope this helps you.
Edit: full function copy:
/**
* #param $instance
*
* #return array
*/
public function getConfiguration($instance)
{
$request = $this->requestStack->getCurrentRequest();
$efParameters = $this->parameters;
$parameters = $efParameters['instances'][$instance];
$options = array();
$options['corsSupport'] = $parameters['cors_support'];
$options['debug'] = $parameters['connector']['debug'];
$options['bind'] = $parameters['connector']['binds'];
$options['plugins'] = $parameters['connector']['plugins'];
$options['uploadTempPath'] = $this->temporaryPath;
$options['roots'] = array();
foreach ($parameters['connector']['roots'] as $parameter) {
$path = $parameter['path'];
$homeFolder = $request->attributes->get('homeFolder');
if ($homeFolder !== '') {
$homeFolder = '/'.$homeFolder.'/';
}
$driver = $this->container->has($parameter['driver']) ? $this->container->get($parameter['driver']) : null;
$driverOptions = array(
'driver' => $parameter['driver'],
'service' => $driver,
'glideURL' => $parameter['glide_url'],
'glideKey' => $parameter['glide_key'],
'plugin' => $parameter['plugins'],
'path' => $path.$homeFolder, //removed slash for Flysystem compatibility
'startPath' => $parameter['start_path'],
'URL' => $this->getURL($parameter, $request, $homeFolder, $path),
'alias' => $parameter['alias'],
'mimeDetect' => $parameter['mime_detect'],
'mimefile' => $parameter['mimefile'],
'imgLib' => $parameter['img_lib'],
'tmbPath' => $parameter['tmb_path'],
'tmbPathMode' => $parameter['tmb_path_mode'],
'tmbUrl' => $parameter['tmb_url'],
'tmbSize' => $parameter['tmb_size'],
'tmbCrop' => $parameter['tmb_crop'],
'tmbBgColor' => $parameter['tmb_bg_color'],
'copyOverwrite' => $parameter['copy_overwrite'],
'copyJoin' => $parameter['copy_join'],
'copyFrom' => $parameter['copy_from'],
'copyTo' => $parameter['copy_to'],
'uploadOverwrite' => $parameter['upload_overwrite'],
'uploadAllow' => $parameter['upload_allow'],
'uploadDeny' => $parameter['upload_deny'],
'uploadMaxSize' => $parameter['upload_max_size'],
'defaults' => $parameter['defaults'],
'attributes' => $parameter['attributes'],
'acceptedName' => $parameter['accepted_name'],
'disabled' => $parameter['disabled_commands'],
'treeDeep' => $parameter['tree_deep'],
'checkSubfolders' => $parameter['check_subfolders'],
'separator' => $parameter['separator'],
'timeFormat' => $parameter['time_format'],
'archiveMimes' => $parameter['archive_mimes'],
'archivers' => $parameter['archivers'],
);
if ($parameter['volume_id'] > 0) {
$driverOptions['id'] = $parameter['volume_id'];
}
if (!$parameter['show_hidden']) {
$driverOptions['accessControl'] = array($this, 'access');
};
$options['roots'][] = array_merge($driverOptions, $this->configureDriver($parameter));
}
return $options;
}
Ok, i have found solution. It is necessary to make yoour own custom configuration reader and replace the original one. Configuration class must implement ElFinderConfigurationProviderInterface. See [https://github.com/helios-ag/FMElfinderBundle/blob/master/Resources/doc/advanced-configuration.md#custom-configuration-provider][1] for more details.

How to generate sip address on browser using asterisk

I need to generate a dynamic sip address on browsers so that my asterisk server can place a call on the same sip address.
This way my web browser will become a sip client which can receive call.
I can see that webrtc is the way but I don't know how can I generate sip address on my browser?
Thanks
You need to create sip user in asterisk like in any other case and register to it via WebRTC, but first you have to enable it in configuration. Hear you have tutorial that I use to start.
In case you want to create dynamic sip users you have to use realtime in asterisk, then your configuration will be read from database. Useful links how to start with realtime: https://wiki.asterisk.org/wiki/display/AST/Realtime+Database+Configuration
https://wiki.asterisk.org/wiki/display/AST/SIP+Realtime,+MySQL+table+structure
You can check my post on Asterisk 12 + Realtime + WebRTC : Websocket connection fails with asterisk 11
On top of that, add a WebService to insert a peer into the table sippeers. This Webservice would be called by your system to create the peer instantly available for a registration using SIP or whatever (SIP over WS/WSS, WebRTC...)
If you're working on Unix and need a .Net WebService, you can use NUSOAP and something like this : (sudo nano /var/html/www/mywebservice.php`. This is a basic implementation I used for testing.
<?php
require_once("nusoap.php");
$namespace = "http://yourdomain.com";
// create a new soap server
$server = new soap_server();
// configure your WSDL
$server->configureWSDL("AsteriskRealtime");
// set your namespace
$server->wsdl->schemaTargetNamespace = $namespace;
// register your WebMethod
$server->register(
// method name:
'HelloWorld',
// parameter list:
array('name'=>'xsd:string'),
// return value(s):
array('return'=>'xsd:string'),
// namespace:
$namespace,
// soapaction: (use default)
false,
// style: rpc or document
'rpc',
// use: encoded or literal
'encoded',
// description: documentation for the method
'A simple hello world');
$server->wsdl->addComplexType(
'AsteriskExtensions',
'complexType',
'struct',
'all','',
array(
'name' => array('name' => 'name', 'type' => 'xsd:string'),
'custom_id' => array('name' => 'custom_id', 'type' => 'xsd:string')
)
);
$server->wsdl->addComplexType(
'AsteriskExtensionsArray',
'complexType',
'array','',
'SOAP-ENC:Array',array(),
array(
array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:AsteriskExtensions[]')
),
'tns:AsteriskExtensions'
);
$server->register(
// method name:
'GetRegisteredExtensions',
// parameter list:
array(),
// return value(s):
array('AsteriskExtensions' => 'tns:AsteriskExtensionsArray'),
// namespace:
$namespace,
// soapaction: (use default)
false,
// style: rpc or document
'rpc',
// use: encoded or literal
'encoded',
// description: documentation for the method
'List the extensions registered in AsteriskRealtime database.');
$server->register(
// method name:
'AddUpdateExtension',
// parameter list:
array('name' => 'xsd:string', 'password' => 'xsd:string', 'custom_id' => 'xsd:string'),
// return value(s):
array('return' => 'xsd:string'),
// namespace:
$namespace,
// soapaction: (use default)
false,
// style: rpc or document
'rpc',
// use: encoded or literal
'encoded',
// description: documentation for the method
'Add or Update an extension in AsteriskRealtime database. NAME is the PRIMARY KEY. Returns OK for success or ERR for failure.');
$server->register(
// method name:
'DeleteExtension',
// parameter list:
array('name' => 'xsd:string'),
// return value(s):
array('return' => 'xsd:string'),
// namespace:
$namespace,
// soapaction: (use default)
false,
// style: rpc or document
'rpc',
// use: encoded or literal
'encoded',
// description: documentation for the method
'Delete an extension registered in AsteriskRealtime database. Returns OK for success or ERR for failure. ');
$server->register(
// method name:
'GetByCustomId',
// parameter list:
array('name' => 'xsd:string'),
// return value(s):
array('AsteriskExtensions' => 'tns:AsteriskExtensionsArray'),
// namespace:
$namespace,
// soapaction: (use default)
false,
// style: rpc or document
'rpc',
// use: encoded or literal
'encoded',
// description: documentation for the method
'Gets an extension or a list of extensions for a CustomID. ');
function HelloWorld($sName)
{
return 'Hello ' . $sName . '! Hello world!';
}
function GetRegisteredExtensions()
{
$conn=odbc_connect('your-asterisk-connector-as-in-odbcinst.ini','your-mysql-user','your-mysql-password');
$result = array();
$req="SELECT * FROM `sippeers`";
$res=odbc_exec($conn,$req);
while($obj=odbc_fetch_object($res)) {
$result[] = array( 'name' => $obj->name, 'custom_id' => $obj->custom_id);
}
return $result;
}
function AddUpdateExtension($name,$password,$custom_id)
{
$conn=odbc_connect('your-asterisk-connector-as-in-odbcinst.ini','your-mysql-user','your-mysql-password');
$req="DELETE FROM `sippeers` WHERE `name` = '" . $name . "'";
$res=odbc_exec($conn,$req);
$req="insert into `sippeers` (`name`, `ipaddr`, `port`, `regseconds`, `defaultuser`, `fullcontact`, `regserver`, `useragent`, `lastms`, `host`, `type`, `context`, `permit`, `deny`, `secret`, `md5secret`, `remotesecret`, `transport`, `dtmfmode`, `directmedia`, `nat`, `callgroup`, `pickupgroup`, `language`, `disallow`, `allow`, `insecure`, `trustrpid`, `progressinband`, `promiscredir`, `useclientcode`, `accountcode`, `setvar`, `callerid`, `amaflags`, `callcounter`, `busylevel`, `allowoverlap`, `allowsubscribe`, `videosupport`, `maxcallbitrate`, `rfc2833compensate`, `mailbox`, `session-timers`, `session-expires`, `session-minse`, `session-refresher`, `t38pt_usertpsource`, `regexten`, `fromdomain`, `fromuser`, `qualify`, `defaultip`, `rtptimeout`, `rtpholdtimeout`, `sendrpid`, `outboundproxy`, `callbackextension`, `timert1`, `timerb`, `qualifyfreq`, `constantssrc`, `contactpermit`, `contactdeny`, `usereqphone`, `textsupport`, `faxdetect`, `buggymwi`, `auth`, `fullname`, `trunkname`, `cid_number`, `callingpres`, `mohinterpret`, `mohsuggest`, `parkinglot`, `hasvoicemail`, `subscribemwi`, `vmexten`, `autoframing`, `rtpkeepalive`, `call-limit`, `g726nonstandard`, `ignoresdpversion`, `allowtransfer`, `dynamic`, `path`, `supportpath`, `avpf`, `encryption`, `dtlsenable`, `dtlsverify`, `dtlscertfile`, `dtlsprivatekey`, `dtlssetup`, `force_avp`, `custom_id`) values('" . $name . "',NULL,NULL,NULL,'" . $name . "','','',NULL,'0','dynamic','friend','default',NULL,NULL,'" . $password . "',NULL,NULL,'udp,ws,wss','auto','no',NULL,NULL,NULL,NULL,NULL,'ulaw,alaw,g729,h264,g719,opus,vp8,gsm',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'no',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'yes','',NULL,'yes','yes','yes','no','/etc/asterisk/keys/asterisk.pem','/etc/asterisk/keys/asterisk.pem','actpass','yes','" . $custom_id . "')";
$res=odbc_exec($conn,$req);
return 'OK';
}
function DeleteExtension($name)
{
$conn=odbc_connect('your-asterisk-connector-as-in-odbcinst.ini','your-mysql-user','your-mysql-password');
$req="DELETE FROM `sippeers` WHERE `name` = '" . $name . "'";
$res=odbc_exec($conn,$req);
return 'OK';
}
function GetByCustomId($name)
{
$conn=odbc_connect('your-asterisk-connector-as-in-odbcinst.ini','your-mysql-user','your-mysql-password');
$result = array();
$req="SELECT * FROM `sippeers` WHERE `custom_id` = '" . $name . "'";
$res=odbc_exec($conn,$req);
while($obj=odbc_fetch_object($res)) {
$result[] = array( 'name' => $obj->name, 'custom_id' => $obj->custom_id);
}
return $result;
}
// Get our posted data if the service is being consumed
// otherwise leave this data blank.
$POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
// pass our posted data (or nothing) to the soap service
$server->service($POST_DATA);
exit();
?>

Edit include/mail.inc, add my own SMTP setting there

The following function is contained in include/mail.inc of Drupal6, it uses the default SMTP settings buried in a file named "php.ini" to send mail.
function drupal_mail_send($message) {
// Allow for a custom mail backend.
if (variable_get('smtp_library', '') && file_exists(variable_get('smtp_library', ''))) {
include_once './'. variable_get('smtp_library', '');
return drupal_mail_wrapper($message);
}
else {
$mimeheaders = array();
foreach ($message['headers'] as $name => $value) {
$mimeheaders[] = $name .': '. mime_header_encode($value);
}
return mail(
$message['to'],
mime_header_encode($message['subject']),
// Note: e-mail uses CRLF for line-endings, but PHP's API requires LF.
// They will appear correctly in the actual e-mail that is sent.
str_replace("\r", '', $message['body']),
// For headers, PHP's API suggests that we use CRLF normally,
// but some MTAs incorrecly replace LF with CRLF. See #234403.
join("\n", $mimeheaders)
);
}
}
but I use shared host, therefore i can't edit php.ini, i want to edit the above function "drupal_mail_send", add the codes below into that function so that it can bypass the PHP mail() function and send email directly to my favorite SMTP server.
include('Mail.php');
$recipients = array( 'someone#example.com' ); # Can be one or more emails
$headers = array (
'From' => 'someone#example.com',
'To' => join(', ', $recipients),
'Subject' => 'Testing email from project web',
);
$body = "This was sent via php from project web!\n";
$mail_object =& Mail::factory('smtp',
array(
'host' => 'prwebmail',
'auth' => true,
'username' => 'YOUR_PROJECT_NAME',
'password' => 'PASSWORD', # As set on your project's config page
#'debug' => true, # uncomment to enable debugging
));
$mail_object->send($recipients, $headers, $body);
Could you write down the modified code for my reference?
The code in drupal_mail_send is part o the Drupal core functionality and should not be changed directly as your changes may be overwritten when you update Drupal.
Modifications of Drupal core files is often referred to by the Drupal community as "hacking core" and is largely discouraged.
Drupal already has a number of modules available which may help you. See:
http://drupal.org/project/phpmailer module:
Adds SMTP support for sending e-mails using the PHPMailer library.
Comes with detailed configuration instructions for how to use Google
Mail as mail server.
http://drupal.org/project/smtp module:
This module allows Drupal to bypass the PHP mail() function and send
email directly to an SMTP server.

Testing File uploads in Symfony2

In the Symfony2 documentation it gives the simple example of:
$client->request('POST', '/submit', array('name' => 'Fabien'), array('photo' => '/path/to/photo'));
To simulate a file upload.
However in all my tests I am getting nothing in the $request object in the app and nothing in the $_FILES array.
Here is a simple WebTestCase which is failing. It is self contained and tests the request that the $client constructs based on the parameters you pass in. It's not testing the app.
class UploadTest extends WebTestCase {
public function testNewPhotos() {
$client = $this->createClient();
$client->request(
'POST',
'/submit',
array('name' => 'Fabien'),
array('photo' => __FILE__)
);
$this->assertEquals(1, count($client->getRequest()->files->all()));
}
}
Just to be clear. This is not a question about how to do file uploads, that I can do. It is about how to test them in Symfony2.
Edit
I'm convinced I'm doing it right. So I've created a test for the Framework and made a pull request.
https://github.com/symfony/symfony/pull/1891
This was an error in the documentation.
Fixed here:
use Symfony\Component\HttpFoundation\File\UploadedFile;
$photo = new UploadedFile('/path/to/photo.jpg', 'photo.jpg', 'image/jpeg', 123);
// or
$photo = array('tmp_name' => '/path/to/photo.jpg', 'name' => 'photo.jpg', 'type' => 'image/jpeg', 'size' => 123, 'error' => UPLOAD_ERR_OK);
$client = static::createClient();
$client->request('POST', '/submit', array('name' => 'Fabien'), array('photo' => $photo));
Documentation here
Here is a code which works with Symfony 2.3 (I didn't tried with another version):
I created an photo.jpg image file and put it in Acme\Bundle\Tests\uploads.
Here is an excerpt from Acme\Bundle\Tests\Controller\AcmeTest.php:
function testUpload()
{
// Open the page
...
// Select the file from the filesystem
$image = new UploadedFile(
// Path to the file to send
dirname(__FILE__).'/../uploads/photo.jpg',
// Name of the sent file
'filename.jpg',
// MIME type
'image/jpeg',
// Size of the file
9988
);
// Select the form (adapt it for your needs)
$form = $crawler->filter('input[type=submit]...')->form();
// Put the file in the upload field
$form['... name of your field ....']->upload($image);
// Send it
$crawler = $this->client->submit($form);
// Check that the file has been successfully sent
// (in my case the filename is displayed in a <a> link so I check
// that it appears on the page)
$this->assertEquals(
1,
$crawler->filter('a:contains("filename.jpg")')->count()
);
}
Even if the question is related to Symfony2, it appears in the top results when searching for Symfony4 in Google.
Instancing an UploadedFile works, but the shortest way I found was also actually in the official documentation:
$crawler = $client->request('GET', '/post/hello-world');
$buttonCrawlerNode = $crawler->selectButton('submit');
$form = $buttonCrawlerNode->form();
$form['photo']->upload('/path/to/lucas.jpg');
https://symfony.com/doc/current/testing.html#forms
I found this article, https://coderwall.com/p/vp52ew/symfony2-unit-testing-uploaded-file, and works perfect.
Regards
if you want to mock a UploadedFile without a client request, you can use:
$path = 'path/to/file.test';
$originalName = 'original_name.test';
$file = new UploadedFile($path, $originalName, null, UPLOAD_ERR_OK, true);
$testSubject->method($file);

Resources