%command.full_name% username
+HELP
+ );
+ parent::configure();
+ }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/Locks.php b/app/code/Magento/User/Controller/Adminhtml/Locks.php
new file mode 100644
index 0000000000000..5317287a97c05
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/Locks.php
@@ -0,0 +1,23 @@
+_authorization->isAllowed('Magento_User::locks');
+ }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/Locks/Grid.php b/app/code/Magento/User/Controller/Adminhtml/Locks/Grid.php
new file mode 100644
index 0000000000000..971b87791f613
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/Locks/Grid.php
@@ -0,0 +1,24 @@
+_view->loadLayout(false);
+ $this->_view->renderLayout();
+ }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/Locks/Index.php b/app/code/Magento/User/Controller/Adminhtml/Locks/Index.php
new file mode 100644
index 0000000000000..b3e9f092fd1b1
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/Locks/Index.php
@@ -0,0 +1,26 @@
+_view->loadLayout();
+ $this->_setActiveMenu('Magento_User::system_acl_locks');
+ $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Locked Users'));
+ $this->_view->renderLayout();
+ }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/Locks/MassUnlock.php b/app/code/Magento/User/Controller/Adminhtml/Locks/MassUnlock.php
new file mode 100644
index 0000000000000..b87e13d7781ae
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/Locks/MassUnlock.php
@@ -0,0 +1,40 @@
+getRequest()->getPost('unlock');
+ if ($userIds && is_array($userIds)) {
+ $affectedUsers = $this->_objectManager
+ ->get('Magento\User\Model\Resource\User')
+ ->unlock($userIds);
+ $this->getMessageManager()->addSuccess(__('Unlocked %1 user(s).', $affectedUsers));
+ }
+ } catch (\Exception $e) {
+ $this->messageManager->addError($e->getMessage());
+ }
+
+ /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+ return $resultRedirect->setPath('adminhtml/*/');
+ }
+}
diff --git a/app/code/Magento/User/Model/Backend/Observer.php b/app/code/Magento/User/Model/Backend/Observer.php
new file mode 100644
index 0000000000000..07fb1a45fd42c
--- /dev/null
+++ b/app/code/Magento/User/Model/Backend/Observer.php
@@ -0,0 +1,389 @@
+authorization = $authorization;
+ $this->backendConfig = $backendConfig;
+ $this->userResource = $userResource;
+ $this->url = $url;
+ $this->session = $session;
+ $this->authSession = $authSession;
+ $this->userFactory = $userFactory;
+ $this->encryptor = $encryptor;
+ $this->actionFlag = $actionFlag;
+ $this->messageManager = $messageManager;
+ }
+
+ /**
+ * Admin locking and password hashing upgrade logic implementation
+ *
+ * @param EventObserver $observer
+ * @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ public function adminAuthenticate($observer)
+ {
+ $password = $observer->getEvent()->getPassword();
+ $user = $observer->getEvent()->getUser();
+ $authResult = $observer->getEvent()->getResult();
+
+ if (!$authResult && $user->getId()) {
+ // update locking information regardless whether user locked or not
+ $this->_updateLockingInformation($user);
+ }
+
+ // check whether user is locked
+ $lockExpires = $user->getLockExpires();
+ if ($lockExpires) {
+ $lockExpires = new \DateTime($lockExpires);
+ if ($lockExpires > new \DateTime()) {
+ throw new UserLockedException(
+ __('You did not sign in correctly or your account is temporarily disabled.')
+ );
+ }
+ }
+
+ if (!$authResult) {
+ return;
+ }
+
+ $this->userResource->unlock($user->getId());
+
+ $latestPassword = $this->userResource->getLatestPassword($user->getId());
+ $this->_checkExpiredPassword($latestPassword);
+
+ // upgrade admin password
+ $isValidHash = $this->encryptor->isValidHashByVersion(
+ $password,
+ $user->getPassword(),
+ Encryptor::HASH_VERSION_LATEST
+ );
+ if (!$isValidHash) {
+ $this->userFactory->create()
+ ->load($user->getId())
+ ->setNewPassword($password)
+ ->setForceNewPassword(true)
+ ->save();
+ }
+ }
+
+ /**
+ * Update locking information for the user
+ *
+ * @param \Magento\User\Model\User $user
+ * @return void
+ */
+ private function _updateLockingInformation($user)
+ {
+ $now = new \DateTime();
+ $lockThreshold = $this->getAdminLockThreshold();
+ $maxFailures = (int)$this->backendConfig->getValue('admin/security/lockout_failures');
+ if (!($lockThreshold && $maxFailures)) {
+ return;
+ }
+ $failuresNum = (int)$user->getFailuresNum() + 1;
+ if ($firstFailureDate = $user->getFirstFailure()) {
+ $firstFailureDate = new \DateTime($firstFailureDate);
+ }
+
+ $updateFirstFailureDate = false;
+ $updateLockExpires = false;
+ $lockThresholdInterval = new \DateInterval('PT' . $lockThreshold.'S');
+ // set first failure date when this is first failure or last first failure expired
+ if (1 === $failuresNum || !$firstFailureDate || $now->diff($firstFailureDate) > $lockThresholdInterval) {
+ $updateFirstFailureDate = $now;
+ // otherwise lock user
+ } elseif ($failuresNum >= $maxFailures) {
+ $updateLockExpires = $now->add($lockThresholdInterval);
+ }
+ $this->userResource->updateFailure($user, $updateLockExpires, $updateFirstFailureDate);
+ }
+
+ /**
+ * Check whether the latest password is expired
+ * Side-effect can be when passwords were changed with different lifetime configuration settings
+ *
+ * @param array $latestPassword
+ * @return void
+ */
+ private function _checkExpiredPassword($latestPassword)
+ {
+ if ($latestPassword && $this->_isLatestPasswordExpired($latestPassword)) {
+ if ($this->isPasswordChangeForced()) {
+ $message = __('It\'s time to change your password.');
+ } else {
+ $myAccountUrl = $this->url->getUrl('adminhtml/system_account/');
+ $message = __('It\'s time to change your password.', $myAccountUrl);
+ }
+ $this->messageManager->addNotice($message);
+ $message = $this->messageManager->getMessages()->getLastAddedMessage();
+ if ($message) {
+ $message->setIdentifier('magento_user_password_expired')->setIsSticky(true);
+ $this->authSession->setPciAdminUserIsPasswordExpired(true);
+ }
+ }
+ }
+
+ /**
+ * Check if latest password is expired
+ *
+ * @param array $latestPassword
+ * @return bool
+ */
+ protected function _isLatestPasswordExpired($latestPassword)
+ {
+ if (!isset($latestPassword['expires']) || $this->getAdminPasswordLifetime() == 0) {
+ return false;
+ } else {
+ return (int)$latestPassword['expires'] < time();
+ }
+ }
+
+ /**
+ * Harden admin password change.
+ *
+ * New password must be minimum 7 chars length and include alphanumeric characters
+ * The password is compared to at least last 4 previous passwords to prevent setting them again
+ *
+ * @param EventObserver $observer
+ * @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ public function checkAdminPasswordChange($observer)
+ {
+ /* @var $user \Magento\User\Model\User */
+ $user = $observer->getEvent()->getObject();
+
+ if ($user->getNewPassword()) {
+ $password = $user->getNewPassword();
+ } else {
+ $password = $user->getPassword();
+ }
+
+ if ($password && !$user->getForceNewPassword() && $user->getId()) {
+ if ($this->encryptor->validateHash($password, $user->getOrigData('password'))) {
+ throw new \Magento\Framework\Exception\LocalizedException(
+ __('Sorry, but this password has already been used. Please create another.')
+ );
+ }
+
+ // check whether password was used before
+ $resource = $this->userResource;
+ $passwordHash = $this->encryptor->getHash($password, false);
+ foreach ($resource->getOldPasswords($user) as $oldPasswordHash) {
+ if ($passwordHash === $oldPasswordHash) {
+ throw new \Magento\Framework\Exception\LocalizedException(
+ __('Sorry, but this password has already been used. Please create another.')
+ );
+ }
+ }
+ }
+ }
+
+ /**
+ * Save new admin password
+ *
+ * @param EventObserver $observer
+ * @return void
+ */
+ public function trackAdminNewPassword($observer)
+ {
+ /* @var $user \Magento\User\Model\User */
+ $user = $observer->getEvent()->getObject();
+ if ($user->getId()) {
+ $password = $user->getNewPassword();
+ $passwordLifetime = $this->getAdminPasswordLifetime();
+ if ($passwordLifetime && $password && !$user->getForceNewPassword()) {
+ $resource = $this->userResource;
+ $passwordHash = $this->encryptor->getHash($password, false);
+ $resource->trackPassword($user, $passwordHash, $passwordLifetime);
+ $this->messageManager->getMessages()->deleteMessageByIdentifier('magento_user_password_expired');
+ $this->authSession->unsPciAdminUserIsPasswordExpired();
+ }
+ }
+ }
+
+ /**
+ * Get admin lock threshold from configuration
+ * @return int
+ */
+ public function getAdminLockThreshold()
+ {
+ return 60 * (int)$this->backendConfig->getValue('admin/security/lockout_threshold');
+ }
+
+ /**
+ * Get admin password lifetime
+ *
+ * @return int
+ */
+ public function getAdminPasswordLifetime()
+ {
+ return 86400 * (int)$this->backendConfig->getValue('admin/security/password_lifetime');
+ }
+
+ /**
+ * Force admin to change password
+ *
+ * @param EventObserver $observer
+ * @return void
+ */
+ public function forceAdminPasswordChange($observer)
+ {
+ if (!$this->isPasswordChangeForced()) {
+ return;
+ }
+ $session = $this->authSession;
+ if (!$session->isLoggedIn()) {
+ return;
+ }
+ $actionList = [
+ 'adminhtml_system_account_index',
+ 'adminhtml_system_account_save',
+ 'adminhtml_auth_logout',
+ ];
+ $controller = $observer->getEvent()->getControllerAction();
+ /** @var \Magento\Framework\App\RequestInterface $request */
+ $request = $observer->getEvent()->getRequest();
+ if ($this->authSession->getPciAdminUserIsPasswordExpired()) {
+ if (!in_array($request->getFullActionName(), $actionList)) {
+ if ($this->authorization->isAllowed('Magento_Backend::myaccount')) {
+ $controller->getResponse()->setRedirect($this->url->getUrl('adminhtml/system_account/'));
+ $this->actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
+ $this->actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_POST_DISPATCH, true);
+ } else {
+ /*
+ * if admin password is expired and access to 'My Account' page is denied
+ * than we need to do force logout with error message
+ */
+ $this->authSession->clearStorage();
+ $this->session->clearStorage();
+ $this->messageManager->addError(
+ __('Your password has expired; please contact your administrator.')
+ );
+ $controller->getRequest()->setDispatched(false);
+ }
+ }
+ }
+ }
+
+ /**
+ * Check whether password change is forced
+ *
+ * @return bool
+ */
+ public function isPasswordChangeForced()
+ {
+ return (bool)(int)$this->backendConfig->getValue('admin/security/password_is_forced');
+ }
+}
diff --git a/app/code/Magento/User/Model/Resource/User.php b/app/code/Magento/User/Model/Resource/User.php
index 5d8d64b7706de..9f2bf7f3d3659 100644
--- a/app/code/Magento/User/Model/Resource/User.php
+++ b/app/code/Magento/User/Model/Resource/User.php
@@ -4,8 +4,6 @@
* See COPYING.txt for license details.
*/
-// @codingStandardsIgnoreFile
-
namespace Magento\User\Model\Resource;
use Magento\Authorization\Model\Acl\Role\Group as RoleGroup;
@@ -149,7 +147,9 @@ public function hasAssigned2Role($user)
$connection = $this->getConnection();
$select = $connection->select();
- $select->from($this->getTable('authorization_role'))->where('parent_id > :parent_id')->where('user_id = :user_id');
+ $select->from($this->getTable('authorization_role'))
+ ->where('parent_id > :parent_id')
+ ->where('user_id = :user_id');
$binds = ['parent_id' => 0, 'user_id' => $userId];
@@ -476,4 +476,151 @@ public function updateRoleUsersAcl(\Magento\Authorization\Model\Role $role)
return $rowsCount > 0;
}
+
+ /**
+ * Unlock specified user record(s)
+ *
+ * @param int|int[] $userIds
+ * @return int number of affected rows
+ */
+ public function unlock($userIds)
+ {
+ if (!is_array($userIds)) {
+ $userIds = [$userIds];
+ }
+ return $this->getConnection()->update(
+ $this->getMainTable(),
+ ['failures_num' => 0, 'first_failure' => null, 'lock_expires' => null],
+ $this->getIdFieldName() . ' IN (' . $this->getConnection()->quote($userIds) . ')'
+ );
+ }
+
+ /**
+ * Lock specified user record(s)
+ *
+ * @param int|int[] $userIds
+ * @param int $exceptId
+ * @param int $lifetime
+ * @return int number of affected rows
+ */
+ public function lock($userIds, $exceptId, $lifetime)
+ {
+ if (!is_array($userIds)) {
+ $userIds = [$userIds];
+ }
+ $exceptId = (int)$exceptId;
+ return $this->getConnection()->update(
+ $this->getMainTable(),
+ ['lock_expires' => $this->dateTime->formatDate(time() + $lifetime)],
+ "{$this->getIdFieldName()} IN (" . $this->getConnection()->quote(
+ $userIds
+ ) . ")\n AND {$this->getIdFieldName()} <> {$exceptId}"
+ );
+ }
+
+ /**
+ * Increment failures count along with updating lock expire and first failure dates
+ *
+ * @param ModelUser $user
+ * @param int|false $setLockExpires
+ * @param int|false $setFirstFailure
+ * @return void
+ */
+ public function updateFailure($user, $setLockExpires = false, $setFirstFailure = false)
+ {
+ $update = ['failures_num' => new \Zend_Db_Expr('failures_num + 1')];
+ if (false !== $setFirstFailure) {
+ $update['first_failure'] = $this->dateTime->formatDate($setFirstFailure);
+ $update['failures_num'] = 1;
+ }
+ if (false !== $setLockExpires) {
+ $update['lock_expires'] = $this->dateTime->formatDate($setLockExpires);
+ }
+ $this->getConnection()->update(
+ $this->getMainTable(),
+ $update,
+ $this->getConnection()->quoteInto("{$this->getIdFieldName()} = ?", $user->getId())
+ );
+ }
+
+ /**
+ * Purge and get remaining old password hashes
+ *
+ * @param ModelUser $user
+ * @param int $retainLimit
+ * @return array
+ */
+ public function getOldPasswords($user, $retainLimit = 4)
+ {
+ $userId = (int)$user->getId();
+ $table = $this->getTable('admin_passwords');
+
+ // purge expired passwords, except that should retain
+ $retainPasswordIds = $this->getConnection()->fetchCol(
+ $this->getConnection()
+ ->select()
+ ->from($table, 'password_id')
+ ->where('user_id = :user_id')
+ ->order('expires ' . \Magento\Framework\DB\Select::SQL_DESC)
+ ->order('password_id ' . \Magento\Framework\DB\Select::SQL_DESC)
+ ->limit($retainLimit),
+ [':user_id' => $userId]
+ );
+ $where = ['user_id = ?' => $userId, 'expires <= ?' => time()];
+ if ($retainPasswordIds) {
+ $where['password_id NOT IN (?)'] = $retainPasswordIds;
+ }
+ $this->getConnection()->delete($table, $where);
+
+ // now get all remained passwords
+ return $this->getConnection()->fetchCol(
+ $this->getConnection()
+ ->select()
+ ->from($table, 'password_hash')
+ ->where('user_id = :user_id'),
+ [':user_id' => $userId]
+ );
+ }
+
+ /**
+ * Remember a password hash for further usage
+ *
+ * @param ModelUser $user
+ * @param string $passwordHash
+ * @param int $lifetime
+ * @return void
+ */
+ public function trackPassword($user, $passwordHash, $lifetime)
+ {
+ $now = time();
+ $this->getConnection()->insert(
+ $this->getTable('admin_passwords'),
+ [
+ 'user_id' => $user->getId(),
+ 'password_hash' => $passwordHash,
+ 'expires' => $now + $lifetime,
+ 'last_updated' => $now
+ ]
+ );
+ }
+
+ /**
+ * Get latest password for specified user id
+ * Possible false positive when password was changed several times with different lifetime configuration
+ *
+ * @param int $userId
+ * @return array
+ */
+ public function getLatestPassword($userId)
+ {
+ return $this->getConnection()->fetchRow(
+ $this->getConnection()
+ ->select()
+ ->from($this->getTable('admin_passwords'))
+ ->where('user_id = :user_id')
+ ->order('password_id ' . \Magento\Framework\DB\Select::SQL_DESC)
+ ->limit(1),
+ [':user_id' => $userId]
+ );
+ }
}
diff --git a/app/code/Magento/User/Model/System/Config/Source/Password.php b/app/code/Magento/User/Model/System/Config/Source/Password.php
new file mode 100644
index 0000000000000..a444a91780318
--- /dev/null
+++ b/app/code/Magento/User/Model/System/Config/Source/Password.php
@@ -0,0 +1,25 @@
+ 0, 'label' => __('Recommended')], ['value' => 1, 'label' => __('Forced')]];
+ }
+}
diff --git a/app/code/Magento/User/README.md b/app/code/Magento/User/README.md
index 7795016d23674..cbefec77d1258 100644
--- a/app/code/Magento/User/README.md
+++ b/app/code/Magento/User/README.md
@@ -3,3 +3,4 @@
**User** enables admin users to manage and assign roles to administrators and other non-customer users,
reset user passwords, and invalidate access tokens.
Different roles can be assigned to different users to define their permissions.
+For admin passwords, it enables setting lifetimes and locking them when expired or when a specified numbers of failures have occurred. It allows preventing password brute force attacks for system backend.
diff --git a/app/code/Magento/User/Setup/UpgradeSchema.php b/app/code/Magento/User/Setup/UpgradeSchema.php
new file mode 100644
index 0000000000000..27aec4b0283ea
--- /dev/null
+++ b/app/code/Magento/User/Setup/UpgradeSchema.php
@@ -0,0 +1,106 @@
+startSetup();
+ $tableAdmins = $installer->getTable('admin_user');
+
+ $installer->getConnection()->addColumn(
+ $tableAdmins,
+ 'failures_num',
+ [
+ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
+ 'nullable' => true,
+ 'default' => 0,
+ 'comment' => 'Failure Number'
+ ]
+ );
+ $installer->getConnection()->addColumn(
+ $tableAdmins,
+ 'first_failure',
+ [
+ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
+ 'comment' => 'First Failure'
+ ]
+ );
+ $installer->getConnection()->addColumn(
+ $tableAdmins,
+ 'lock_expires',
+ [
+ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
+ 'comment' => 'Expiration Lock Dates'
+ ]
+ );
+
+ /**
+ * Create table 'admin_passwords'
+ */
+ $table = $installer->getConnection()->newTable(
+ $installer->getTable('admin_passwords')
+ )->addColumn(
+ 'password_id',
+ \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
+ null,
+ ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
+ 'Password Id'
+ )->addColumn(
+ 'user_id',
+ \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
+ null,
+ ['unsigned' => true, 'nullable' => false, 'default' => '0'],
+ 'User Id'
+ )->addColumn(
+ 'password_hash',
+ \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
+ 100,
+ [],
+ 'Password Hash'
+ )->addColumn(
+ 'expires',
+ \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
+ null,
+ ['unsigned' => true, 'nullable' => false, 'default' => '0'],
+ 'Expires'
+ )->addColumn(
+ 'last_updated',
+ \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
+ null,
+ ['unsigned' => true, 'nullable' => false, 'default' => '0'],
+ 'Last Updated'
+ )->addIndex(
+ $installer->getIdxName('admin_passwords', ['user_id']),
+ ['user_id']
+ )->addForeignKey(
+ $installer->getFkName('admin_passwords', 'user_id', 'admin_user', 'user_id'),
+ 'user_id',
+ $installer->getTable('admin_user'),
+ 'user_id',
+ \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+ )->setComment(
+ 'Admin Passwords'
+ );
+ $installer->getConnection()->createTable($table);
+
+ $installer->endSetup();
+ }
+}
diff --git a/app/code/Magento/User/Test/Unit/Console/UnlockAdminAccountCommandTest.php b/app/code/Magento/User/Test/Unit/Console/UnlockAdminAccountCommandTest.php
new file mode 100644
index 0000000000000..bf1a7cf8806fa
--- /dev/null
+++ b/app/code/Magento/User/Test/Unit/Console/UnlockAdminAccountCommandTest.php
@@ -0,0 +1,48 @@
+objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ parent::setUp();
+ }
+
+ /**
+ * Test configure() method implicitly via construct invocation.
+ *
+ * @return void
+ */
+ public function testConfigure()
+ {
+ $this->command = $this->objectManager
+ ->getObject('Magento\User\Console\UnlockAdminAccountCommand');
+
+ $this->assertEquals(UnlockAdminAccountCommand::COMMAND_ADMIN_ACCOUNT_UNLOCK, $this->command->getName());
+ $this->assertEquals(UnlockAdminAccountCommand::COMMAND_DESCRIPTION, $this->command->getDescription());
+ $this->command->getDefinition()->getArgument(UnlockAdminAccountCommand::ARGUMENT_ADMIN_USERNAME);
+ $this->assertContains('This command unlocks an admin account by its username', $this->command->getHelp());
+ }
+}
diff --git a/app/code/Magento/User/Test/Unit/Helper/DataTest.php b/app/code/Magento/User/Test/Unit/Helper/DataTest.php
new file mode 100644
index 0000000000000..28f9fec77f164
--- /dev/null
+++ b/app/code/Magento/User/Test/Unit/Helper/DataTest.php
@@ -0,0 +1,67 @@
+mathRandomMock = $this->getMockBuilder('Magento\Framework\Math\Random')
+ ->disableOriginalConstructor()
+ ->setMethods([])
+ ->getMock();
+
+ $this->configMock = $this->getMockBuilder('Magento\Backend\App\ConfigInterface')
+ ->disableOriginalConstructor()
+ ->setMethods([])
+ ->getMock();
+
+ $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ $this->model = $objectManager->getObject(
+ 'Magento\User\Helper\Data',
+ [
+ 'config' => $this->configMock,
+ 'mathRandom' => $this->mathRandomMock
+ ]
+ );
+ }
+
+ public function testGenerateResetPasswordLinkToken()
+ {
+ $hash = 'hashString';
+ $this->mathRandomMock->expects($this->once())->method('getUniqueHash')->willReturn($hash);
+ $this->assertEquals($hash, $this->model->generateResetPasswordLinkToken());
+ }
+
+ public function testGetResetPasswordLinkExpirationPeriod()
+ {
+ $value = '123';
+ $this->configMock->expects($this->once())
+ ->method('getValue')
+ ->with(\Magento\User\Helper\Data::XML_PATH_ADMIN_RESET_PASSWORD_LINK_EXPIRATION_PERIOD)
+ ->willReturn($value);
+ $this->assertEquals((int) $value, $this->model->getResetPasswordLinkExpirationPeriod());
+ }
+}
diff --git a/app/code/Magento/User/Test/Unit/Model/Plugin/AuthorizationRoleTest.php b/app/code/Magento/User/Test/Unit/Model/Plugin/AuthorizationRoleTest.php
new file mode 100644
index 0000000000000..8a486e4a745b7
--- /dev/null
+++ b/app/code/Magento/User/Test/Unit/Model/Plugin/AuthorizationRoleTest.php
@@ -0,0 +1,55 @@
+userResourceModelMock = $this->getMockBuilder('Magento\User\Model\Resource\User')
+ ->disableOriginalConstructor()
+ ->setMethods([])
+ ->getMock();
+
+ $this->roleMock = $this->getMockBuilder('Magento\Authorization\Model\Role')
+ ->disableOriginalConstructor()
+ ->setMethods([])
+ ->getMock();
+
+ $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ $this->model = $objectManager->getObject(
+ 'Magento\User\Model\Plugin\AuthorizationRole',
+ [
+ 'userResourceModel' => $this->userResourceModelMock
+ ]
+ );
+ }
+
+ public function testAfterSave()
+ {
+ $this->userResourceModelMock->expects($this->once())->method('updateRoleUsersAcl')->with($this->roleMock);
+ $this->assertInstanceOf(
+ '\Magento\Authorization\Model\Role',
+ $this->model->afterSave($this->roleMock, $this->roleMock)
+ );
+ }
+}
diff --git a/app/code/Magento/User/Test/Unit/Model/UserTest.php b/app/code/Magento/User/Test/Unit/Model/UserTest.php
index 05e2f75ad8be1..1f37bd9a15524 100644
--- a/app/code/Magento/User/Test/Unit/Model/UserTest.php
+++ b/app/code/Magento/User/Test/Unit/Model/UserTest.php
@@ -16,59 +16,71 @@
class UserTest extends \PHPUnit_Framework_TestCase
{
/** @var \Magento\User\Model\User */
- protected $_model;
+ protected $model;
- /** @var \Magento\User\Helper\Data */
- protected $_userData;
+ /** @var \Magento\User\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
+ protected $userDataMock;
/** @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject */
- protected $_transportBuilderMock;
+ protected $transportBuilderMock;
/** @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject */
- protected $_contextMock;
+ protected $contextMock;
/** @var \Magento\User\Model\Resource\User|\PHPUnit_Framework_MockObject_MockObject */
- protected $_resourceMock;
+ protected $resourceMock;
/** @var \Magento\Framework\Data\Collection\AbstractDb|\PHPUnit_Framework_MockObject_MockObject */
- protected $_collectionMock;
+ protected $collectionMock;
/** @var \Magento\Framework\Mail\TransportInterface|\PHPUnit_Framework_MockObject_MockObject */
- protected $_transportMock;
+ protected $transportMock;
/** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
- protected $_storeManagerMock;
+ protected $storeManagerMock;
/** @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject */
- protected $_storetMock;
+ protected $storetMock;
- /** @var \Magento\Backend\App\ConfigInterface */
- protected $_configMock;
+ /** @var \Magento\Backend\App\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+ protected $configMock;
/** @var \Magento\Framework\Encryption\EncryptorInterface|\PHPUnit_Framework_MockObject_MockObject */
- protected $_encryptorMock;
+ protected $encryptorMock;
+
+ /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+ protected $eventManagerMock;
+
+ /** @var \Magento\Framework\Validator\DataObjectFactory|\PHPUnit_Framework_MockObject_MockObject */
+ protected $validatorObjectFactoryMock;
+
+ /** @var \Magento\User\Model\UserValidationRules|\PHPUnit_Framework_MockObject_MockObject */
+ protected $validationRulesMock;
+
+ /** @var \Magento\Authorization\Model\RoleFactory|\PHPUnit_Framework_MockObject_MockObject */
+ protected $roleFactoryMock;
/**
* Set required values
*/
protected function setUp()
{
- $this->_userData = $this->getMockBuilder(
+ $this->userDataMock = $this->getMockBuilder(
'Magento\User\Helper\Data'
)->disableOriginalConstructor()->setMethods(
[]
)->getMock();
- $this->_contextMock = $this->getMockBuilder(
+ $this->contextMock = $this->getMockBuilder(
'Magento\Framework\Model\Context'
)->disableOriginalConstructor()->setMethods(
[]
)->getMock();
- $this->_resourceMock = $this->getMockBuilder(
+ $this->resourceMock = $this->getMockBuilder(
'Magento\User\Model\Resource\User'
)->disableOriginalConstructor()->setMethods(
[]
)->getMock();
- $this->_collectionMock = $this->getMockBuilder(
+ $this->collectionMock = $this->getMockBuilder(
'Magento\Framework\Data\Collection\AbstractDb'
)->disableOriginalConstructor()->setMethods(
[]
@@ -78,69 +90,74 @@ protected function setUp()
)->disableOriginalConstructor()->setMethods(
[]
)->getMock();
- $eventManagerMock = $this->getMockBuilder(
+ $this->eventManagerMock = $this->getMockBuilder(
'Magento\Framework\Event\ManagerInterface'
)->disableOriginalConstructor()->setMethods(
- []
- )->getMock();
- $objectFactoryMock = $this->getMockBuilder(
+ ['dispatch']
+ )->getMockForAbstractClass();
+ $this->validatorObjectFactoryMock = $this->getMockBuilder(
'Magento\Framework\Validator\DataObjectFactory'
)->disableOriginalConstructor()->setMethods(
['create']
)->getMock();
- $roleFactoryMock = $this->getMockBuilder(
+ $this->roleFactoryMock = $this->getMockBuilder(
'Magento\Authorization\Model\RoleFactory'
)->disableOriginalConstructor()->setMethods(
['create']
)->getMock();
- $this->_transportMock = $this->getMockBuilder(
+ $this->transportMock = $this->getMockBuilder(
'Magento\Framework\Mail\TransportInterface'
)->disableOriginalConstructor()->setMethods(
[]
)->getMock();
- $this->_transportBuilderMock = $this->getMockBuilder(
- '\Magento\Framework\Mail\Template\TransportBuilder'
+ $this->transportBuilderMock = $this->getMockBuilder(
+ 'Magento\Framework\Mail\Template\TransportBuilder'
+ )->disableOriginalConstructor()->setMethods(
+ []
+ )->getMock();
+ $this->storetMock = $this->getMockBuilder(
+ 'Magento\Store\Model\Store'
)->disableOriginalConstructor()->setMethods(
[]
)->getMock();
- $this->_storetMock = $this->getMockBuilder(
- '\Magento\Store\Model\Store'
+ $this->storeManagerMock = $this->getMockBuilder(
+ 'Magento\Store\Model\StoreManagerInterface'
)->disableOriginalConstructor()->setMethods(
[]
)->getMock();
- $this->_storeManagerMock = $this->getMockBuilder(
- '\Magento\Store\Model\StoreManagerInterface'
+
+ $this->configMock = $this->getMockBuilder(
+ 'Magento\Backend\App\ConfigInterface'
)->disableOriginalConstructor()->setMethods(
[]
)->getMock();
- $this->_configMock = $this->getMockBuilder(
- '\Magento\Backend\App\ConfigInterface'
+ $this->validationRulesMock = $this->getMockBuilder(
+ 'Magento\User\Model\UserValidationRules'
)->disableOriginalConstructor()->setMethods(
[]
)->getMock();
- $this->_encryptorMock = $this->getMockBuilder('Magento\Framework\Encryption\EncryptorInterface')
+ $this->encryptorMock = $this->getMockBuilder('Magento\Framework\Encryption\EncryptorInterface')
->setMethods(['validateHash'])
->getMockForAbstractClass();
$helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
- $this->_model = $helper->getObject(
+ $this->model = $helper->getObject(
'Magento\User\Model\User',
[
- 'eventManager' => $eventManagerMock,
- 'userData' => $this->_userData,
- 'context' => $this->_contextMock,
+ 'eventManager' => $this->eventManagerMock,
+ 'userData' => $this->userDataMock,
'registry' => $coreRegistry,
- 'resource' => $this->_resourceMock,
- 'resourceCollection' => $this->_collectionMock,
- 'validatorObjectFactory' => $objectFactoryMock,
- 'roleFactory' => $roleFactoryMock,
- 'transportBuilder' => $this->_transportBuilderMock,
- 'storeManager' => $this->_storeManagerMock,
- 'validationRules' => new UserValidationRules(),
- 'config' => $this->_configMock,
- 'encryptor' => $this->_encryptorMock
+ 'resource' => $this->resourceMock,
+ 'resourceCollection' => $this->collectionMock,
+ 'validatorObjectFactory' => $this->validatorObjectFactoryMock,
+ 'roleFactory' => $this->roleFactoryMock,
+ 'transportBuilder' => $this->transportBuilderMock,
+ 'storeManager' => $this->storeManagerMock,
+ 'validationRules' => $this->validationRulesMock,
+ 'config' => $this->configMock,
+ 'encryptor' => $this->encryptorMock
]
);
}
@@ -152,11 +169,11 @@ public function testSendPasswordResetNotificationEmail()
$firstName = 'Foo';
$lastName = 'Bar';
- $this->_model->setEmail($email);
- $this->_model->setFirstname($firstName);
- $this->_model->setLastname($lastName);
+ $this->model->setEmail($email);
+ $this->model->setFirstname($firstName);
+ $this->model->setLastname($lastName);
- $this->_configMock->expects(
+ $this->configMock->expects(
$this->at(0)
)->method(
'getValue'
@@ -165,7 +182,7 @@ public function testSendPasswordResetNotificationEmail()
)->will(
$this->returnValue('templateId')
);
- $this->_configMock->expects(
+ $this->configMock->expects(
$this->at(1)
)->method(
'getValue'
@@ -174,17 +191,17 @@ public function testSendPasswordResetNotificationEmail()
)->will(
$this->returnValue('sender')
);
- $this->_transportBuilderMock->expects($this->once())->method('setTemplateOptions')->will($this->returnSelf());
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects($this->once())->method('setTemplateOptions')->will($this->returnSelf());
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'setTemplateVars'
)->with(
- ['user' => $this->_model, 'store' => $this->_storetMock]
+ ['user' => $this->model, 'store' => $this->storetMock]
)->will(
$this->returnSelf()
);
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'addTo'
@@ -194,7 +211,7 @@ public function testSendPasswordResetNotificationEmail()
)->will(
$this->returnSelf()
);
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'setFrom'
@@ -203,7 +220,7 @@ public function testSendPasswordResetNotificationEmail()
)->will(
$this->returnSelf()
);
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'setTemplateIdentifier'
@@ -212,26 +229,26 @@ public function testSendPasswordResetNotificationEmail()
)->will(
$this->returnSelf()
);
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'getTransport'
)->will(
- $this->returnValue($this->_transportMock)
+ $this->returnValue($this->transportMock)
);
- $this->_transportMock->expects($this->once())->method('sendMessage');
+ $this->transportMock->expects($this->once())->method('sendMessage');
- $this->_storeManagerMock->expects(
+ $this->storeManagerMock->expects(
$this->once()
)->method(
'getStore'
)->with(
$storeId
)->will(
- $this->returnValue($this->_storetMock)
+ $this->returnValue($this->storetMock)
);
- $this->assertInstanceOf('\Magento\User\Model\User', $this->_model->sendPasswordResetNotificationEmail());
+ $this->assertInstanceOf('\Magento\User\Model\User', $this->model->sendPasswordResetNotificationEmail());
}
public function testSendPasswordResetConfirmationEmail()
@@ -241,11 +258,11 @@ public function testSendPasswordResetConfirmationEmail()
$firstName = 'Foo';
$lastName = 'Bar';
- $this->_model->setEmail($email);
- $this->_model->setFirstname($firstName);
- $this->_model->setLastname($lastName);
+ $this->model->setEmail($email);
+ $this->model->setFirstname($firstName);
+ $this->model->setLastname($lastName);
- $this->_configMock->expects(
+ $this->configMock->expects(
$this->at(0)
)->method(
'getValue'
@@ -254,7 +271,7 @@ public function testSendPasswordResetConfirmationEmail()
)->will(
$this->returnValue('templateId')
);
- $this->_configMock->expects(
+ $this->configMock->expects(
$this->at(1)
)->method(
'getValue'
@@ -263,17 +280,17 @@ public function testSendPasswordResetConfirmationEmail()
)->will(
$this->returnValue('sender')
);
- $this->_transportBuilderMock->expects($this->once())->method('setTemplateOptions')->will($this->returnSelf());
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects($this->once())->method('setTemplateOptions')->will($this->returnSelf());
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'setTemplateVars'
)->with(
- ['user' => $this->_model, 'store' => $this->_storetMock]
+ ['user' => $this->model, 'store' => $this->storetMock]
)->will(
$this->returnSelf()
);
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'addTo'
@@ -283,7 +300,7 @@ public function testSendPasswordResetConfirmationEmail()
)->will(
$this->returnSelf()
);
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'setFrom'
@@ -292,7 +309,7 @@ public function testSendPasswordResetConfirmationEmail()
)->will(
$this->returnSelf()
);
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'setTemplateIdentifier'
@@ -301,40 +318,40 @@ public function testSendPasswordResetConfirmationEmail()
)->will(
$this->returnSelf()
);
- $this->_transportBuilderMock->expects(
+ $this->transportBuilderMock->expects(
$this->once()
)->method(
'getTransport'
)->will(
- $this->returnValue($this->_transportMock)
+ $this->returnValue($this->transportMock)
);
- $this->_transportMock->expects($this->once())->method('sendMessage');
+ $this->transportMock->expects($this->once())->method('sendMessage');
- $this->_storeManagerMock->expects(
+ $this->storeManagerMock->expects(
$this->once()
)->method(
'getStore'
)->with(
$storeId
)->will(
- $this->returnValue($this->_storetMock)
+ $this->returnValue($this->storetMock)
);
- $this->assertInstanceOf('\Magento\User\Model\User', $this->_model->sendPasswordResetConfirmationEmail());
+ $this->assertInstanceOf('\Magento\User\Model\User', $this->model->sendPasswordResetConfirmationEmail());
}
public function testVerifyIdentity()
{
$password = 'password';
- $this->_encryptorMock
+ $this->encryptorMock
->expects($this->once())
->method('validateHash')
- ->with($password, $this->_model->getPassword())
+ ->with($password, $this->model->getPassword())
->will($this->returnValue(true));
- $this->_model->setIsActive(true);
- $this->_resourceMock->expects($this->once())->method('hasAssigned2Role')->will($this->returnValue(true));
+ $this->model->setIsActive(true);
+ $this->resourceMock->expects($this->once())->method('hasAssigned2Role')->will($this->returnValue(true));
$this->assertTrue(
- $this->_model->verifyIdentity($password),
+ $this->model->verifyIdentity($password),
'Identity verification failed while should have passed.'
);
}
@@ -342,13 +359,13 @@ public function testVerifyIdentity()
public function testVerifyIdentityFailure()
{
$password = 'password';
- $this->_encryptorMock
+ $this->encryptorMock
->expects($this->once())
->method('validateHash')
- ->with($password, $this->_model->getPassword())
+ ->with($password, $this->model->getPassword())
->will($this->returnValue(false));
$this->assertFalse(
- $this->_model->verifyIdentity($password),
+ $this->model->verifyIdentity($password),
'Identity verification passed while should have failed.'
);
}
@@ -356,33 +373,253 @@ public function testVerifyIdentityFailure()
public function testVerifyIdentityInactiveRecord()
{
$password = 'password';
- $this->_encryptorMock
+ $this->encryptorMock
->expects($this->once())
->method('validateHash')
- ->with($password, $this->_model->getPassword())
+ ->with($password, $this->model->getPassword())
->will($this->returnValue(true));
- $this->_model->setIsActive(false);
+ $this->model->setIsActive(false);
$this->setExpectedException(
'Magento\\Framework\\Exception\\AuthenticationException',
'You did not sign in correctly or your account is temporarily disabled.'
);
- $this->_model->verifyIdentity($password);
+ $this->model->verifyIdentity($password);
}
public function testVerifyIdentityNoAssignedRoles()
{
$password = 'password';
- $this->_encryptorMock
+ $this->encryptorMock
->expects($this->once())
->method('validateHash')
- ->with($password, $this->_model->getPassword())
+ ->with($password, $this->model->getPassword())
->will($this->returnValue(true));
- $this->_model->setIsActive(true);
- $this->_resourceMock->expects($this->once())->method('hasAssigned2Role')->will($this->returnValue(false));
+ $this->model->setIsActive(true);
+ $this->resourceMock->expects($this->once())->method('hasAssigned2Role')->will($this->returnValue(false));
$this->setExpectedException(
'Magento\\Framework\\Exception\\AuthenticationException',
'You need more permissions to access this.'
);
- $this->_model->verifyIdentity($password);
+ $this->model->verifyIdentity($password);
+ }
+
+ public function testSleep()
+ {
+ $excludedProperties = [
+ '_eventManager',
+ '_cacheManager',
+ '_registry',
+ '_appState',
+ '_userData',
+ '_config',
+ '_validatorObject',
+ '_roleFactory',
+ '_encryptor',
+ '_transportBuilder',
+ '_storeManager',
+ '_validatorBeforeSave'
+ ];
+ $actualResult = $this->model->__sleep();
+ $this->assertNotEmpty($actualResult);
+ $expectedResult = array_intersect($actualResult, $excludedProperties);
+ $this->assertEmpty($expectedResult);
+ }
+
+ public function testBeforeSave()
+ {
+ $this->eventManagerMock->expects($this->any())->method('dispatch');
+ $this->model->setIsActive(1);
+ $actualData = $this->model->beforeSave()->getData();
+ $this->assertArrayHasKey('modified', $actualData);
+ $this->assertArrayHasKey('extra', $actualData);
+ $this->assertArrayHasKey('password', $actualData);
+ $this->assertArrayHasKey('is_active', $actualData);
+ }
+
+ public function testValidateOk()
+ {
+ /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */
+ $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\DataObject')
+ ->disableOriginalConstructor()
+ ->setMethods([])
+ ->getMock();
+ $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock);
+ $this->validationRulesMock->expects($this->once())
+ ->method('addUserInfoRules')
+ ->with($validatorMock);
+ $validatorMock->expects($this->once())->method('isValid')->willReturn(true);
+ $this->assertTrue($this->model->validate());
+ }
+
+ public function testValidateInvalid()
+ {
+ $messages = ['Invalid username'];
+ /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */
+ $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\DataObject')
+ ->disableOriginalConstructor()
+ ->setMethods([])
+ ->getMock();
+ $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock);
+ $this->validationRulesMock->expects($this->once())
+ ->method('addUserInfoRules')
+ ->with($validatorMock);
+ $validatorMock->expects($this->once())->method('isValid')->willReturn(false);
+ $validatorMock->expects($this->once())->method('getMessages')->willReturn($messages);
+ $this->assertEquals($messages, $this->model->validate());
+ }
+
+ public function testSaveExtra()
+ {
+ $data = [1, 2, 3];
+ $this->resourceMock->expects($this->once())->method('saveExtra')->with($this->model, serialize($data));
+ $this->assertInstanceOf('Magento\User\Model\User', $this->model->saveExtra($data));
+ }
+
+ public function testGetRoles()
+ {
+ $this->resourceMock->expects($this->once())->method('getRoles')->with($this->model)->willReturn([]);
+ $this->assertInternalType('array', $this->model->getRoles());
+ }
+
+ public function testGetRole()
+ {
+ $roles = ['role'];
+ $roleMock = $this->getMockBuilder('Magento\Authorization\Model\Role')
+ ->disableOriginalConstructor()
+ ->setMethods([])
+ ->getMock();
+ $this->roleFactoryMock->expects($this->once())->method('create')->willReturn($roleMock);
+ $this->resourceMock->expects($this->once())->method('getRoles')->with($this->model)->willReturn($roles);
+ $roleMock->expects($this->once())->method('load')->with($roles[0]);
+ $this->assertInstanceOf('Magento\Authorization\Model\Role', $this->model->getRole());
+ }
+
+ public function testDeleteFromRole()
+ {
+ $this->resourceMock->expects($this->once())->method('deleteFromRole')->with($this->model);
+ $this->assertInstanceOf('Magento\User\Model\User', $this->model->deleteFromRole());
+ }
+
+ public function testRoleUserExistsTrue()
+ {
+ $result = ['role'];
+ $this->resourceMock->expects($this->once())->method('roleUserExists')->with($this->model)->willReturn($result);
+ $this->assertTrue($this->model->roleUserExists());
+ }
+
+ public function testRoleUserExistsFalse()
+ {
+ $result = [];
+ $this->resourceMock->expects($this->once())->method('roleUserExists')->with($this->model)->willReturn($result);
+ $this->assertFalse($this->model->roleUserExists());
+ }
+
+ public function testGetAclRole()
+ {
+ $roles = ['role'];
+ $result = 1;
+ $roleMock = $this->getMockBuilder('Magento\Authorization\Model\Role')
+ ->disableOriginalConstructor()
+ ->setMethods([])
+ ->getMock();
+ $this->roleFactoryMock->expects($this->once())->method('create')->willReturn($roleMock);
+ $this->resourceMock->expects($this->once())->method('getRoles')->with($this->model)->willReturn($roles);
+ $roleMock->expects($this->once())->method('load')->with($roles[0]);
+ $roleMock->expects($this->once())->method('getId')->willReturn($result);
+ $this->assertEquals($result, $this->model->getAclRole());
+ }
+
+ /**
+ * @dataProvider authenticateDataProvider
+ */
+ public function testAuthenticate($usernameIn, $usernameOut, $expectedResult)
+ {
+ $password = 'password';
+ $config = 'config';
+
+ $data = ['id' => 1, 'is_active' => 1, 'username' => $usernameOut];
+
+ $this->configMock->expects($this->once())
+ ->method('isSetFlag')
+ ->with('admin/security/use_case_sensitive_login')
+ ->willReturn($config);
+ $this->eventManagerMock->expects($this->any())->method('dispatch');
+
+ $this->resourceMock->expects($this->any())->method('loadByUsername')->willReturn($data);
+ $this->model->setIdFieldName('id');
+
+ $this->encryptorMock->expects($this->any())->method('validateHash')->willReturn(true);
+ $this->resourceMock->expects($this->any())->method('hasAssigned2Role')->willReturn(true);
+ $this->assertEquals($expectedResult, $this->model->authenticate($usernameIn, $password));
+ }
+
+ public function authenticateDataProvider()
+ {
+ return [
+ 'success' => [
+ 'usernameIn' => 'username',
+ 'usernameOut' => 'username',
+ 'expectedResult' => true
+ ],
+ 'failedUsername' => [
+ 'usernameIn' => 'username1',
+ 'usernameOut' => 'username2',
+ 'expectedResult' => false
+ ]
+ ];
+ }
+
+ /**
+ * @expectedException \Magento\Framework\Exception\LocalizedException
+ */
+ public function testAuthenticateException()
+ {
+ $username = 'username';
+ $password = 'password';
+ $config = 'config';
+
+ $this->configMock->expects($this->once())
+ ->method('isSetFlag')
+ ->with('admin/security/use_case_sensitive_login')
+ ->willReturn($config);
+
+ $this->eventManagerMock->expects($this->any())->method('dispatch');
+ $this->resourceMock->expects($this->once())
+ ->method('loadByUsername')
+ ->willThrowException(new \Magento\Framework\Exception\LocalizedException(__()));
+ $this->model->authenticate($username, $password);
+ }
+
+ public function testChangeResetPasswordLinkToken()
+ {
+ $token = '1';
+ $this->assertInstanceOf('Magento\User\Model\User', $this->model->changeResetPasswordLinkToken($token));
+ $this->assertEquals($token, $this->model->getRpToken());
+ $this->assertInternalType('string', $this->model->getRpTokenCreatedAt());
+ }
+
+ public function testIsResetPasswordLinkTokenExpiredEmptyToken()
+ {
+ $this->assertTrue($this->model->isResetPasswordLinkTokenExpired());
+ }
+
+ public function testIsResetPasswordLinkTokenExpiredIsExpiredToken()
+ {
+ $this->model->setRpToken('1');
+ $this->model->setRpTokenCreatedAt(
+ (new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT)
+ );
+ $this->userDataMock->expects($this->once())->method('getResetPasswordLinkExpirationPeriod')->willReturn(0);
+ $this->assertTrue($this->model->isResetPasswordLinkTokenExpired());
+ }
+
+ public function testIsResetPasswordLinkTokenExpiredIsNotExpiredToken()
+ {
+ $this->model->setRpToken('1');
+ $this->model->setRpTokenCreatedAt(
+ (new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT)
+ );
+ $this->userDataMock->expects($this->once())->method('getResetPasswordLinkExpirationPeriod')->willReturn(1);
+ $this->assertFalse($this->model->isResetPasswordLinkTokenExpired());
}
}
diff --git a/app/code/Magento/User/etc/acl.xml b/app/code/Magento/User/etc/acl.xml
index 502b706e13856..261a998abc757 100644
--- a/app/code/Magento/User/etc/acl.xml
+++ b/app/code/Magento/User/etc/acl.xml
@@ -12,6 +12,7 @@
+
diff --git a/app/code/Magento/User/etc/adminhtml/di.xml b/app/code/Magento/User/etc/adminhtml/di.xml
index 26f2ed8ba4485..ad550cbf5058d 100644
--- a/app/code/Magento/User/etc/adminhtml/di.xml
+++ b/app/code/Magento/User/etc/adminhtml/di.xml
@@ -7,4 +7,9 @@
-->
+
+
+ Magento\Framework\Authorization
+
+
diff --git a/app/code/Magento/User/etc/adminhtml/events.xml b/app/code/Magento/User/etc/adminhtml/events.xml
new file mode 100644
index 0000000000000..01f8142a549d0
--- /dev/null
+++ b/app/code/Magento/User/etc/adminhtml/events.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/User/etc/adminhtml/menu.xml b/app/code/Magento/User/etc/adminhtml/menu.xml
index bac4265e50aba..9e9d9ded06c0c 100644
--- a/app/code/Magento/User/etc/adminhtml/menu.xml
+++ b/app/code/Magento/User/etc/adminhtml/menu.xml
@@ -10,5 +10,6 @@
+
diff --git a/app/code/Magento/User/etc/adminhtml/system.xml b/app/code/Magento/User/etc/adminhtml/system.xml
index c49f8f81f1ddf..8fecae6a8f95b 100644
--- a/app/code/Magento/User/etc/adminhtml/system.xml
+++ b/app/code/Magento/User/etc/adminhtml/system.xml
@@ -15,6 +15,23 @@
Magento\Config\Model\Config\Source\Email\Template
+
+
+
+ We will disable this feature if the value is empty.
+
+
+
+
+
+
+ We will disable this feature if the value is empty.
+
+
+
+ Magento\User\Model\System\Config\Source\Password
+
+
diff --git a/app/code/Magento/User/etc/config.xml b/app/code/Magento/User/etc/config.xml
index 6ef863af41a76..d8736de1b56ec 100644
--- a/app/code/Magento/User/etc/config.xml
+++ b/app/code/Magento/User/etc/config.xml
@@ -14,6 +14,12 @@
1
admin_emails_reset_password_template
+
+ 6
+ 30
+ 90
+ 1
+
diff --git a/app/code/Magento/User/etc/di.xml b/app/code/Magento/User/etc/di.xml
index 962ccc2aa632a..1973befe228e6 100644
--- a/app/code/Magento/User/etc/di.xml
+++ b/app/code/Magento/User/etc/di.xml
@@ -15,4 +15,11 @@
+
+
+
+ - Magento\User\Console\UnlockAdminAccountCommand
+
+
+
diff --git a/app/code/Magento/User/i18n/de_DE.csv b/app/code/Magento/User/i18n/de_DE.csv
index 3f27379d04352..63367a6ff3a32 100644
--- a/app/code/Magento/User/i18n/de_DE.csv
+++ b/app/code/Magento/User/i18n/de_DE.csv
@@ -95,3 +95,26 @@ Resources,Resources
"Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?","Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?"
"Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?","Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?"
"Reset Password Template","Reset Password Template"
+No,No
+Yes,Yes
+Username,Benutzername
+"Locked Users","Gesperrte Benutzer"
+"Unlocked %1 user(s).","Unlocked %1 user(s)."
+"This account is locked.","Das Konto ist gesperrt."
+"It's time to change your password.","It's time to change your password."
+"It's time to change your password.","It's time to change your password."
+"Sorry, but this password has already been used. Please create another.","Sorry, but this password has already been used. Please create another."
+"Your password has expired; please contact your administrator.","Your password has expired; please contact your administrator."
+Recommended,Empfohlen
+Forced,Dechiffriert
+"Maximum Login Failures to Lockout Account","Maximum Login Failures to Lockout Account"
+"We will disable this feature if the value is empty.","We will disable this feature if the value is empty."
+"Lockout Time (minutes)","Lockout Time (minutes)"
+"Password Lifetime (days)","Password Lifetime (days)"
+"We will disable this feature if the value is empty. ","We will disable this feature if the value is empty. "
+"Password Change","Password Change"
+"Admin Accounts Locks","Admin Kontosperrungen"
+Unlock,Entsperren
+"Last login","Letzter Login"
+Failures,Fehler
+Unlocked,"Gesperrt bis"
diff --git a/app/code/Magento/User/i18n/en_US.csv b/app/code/Magento/User/i18n/en_US.csv
index 3f27379d04352..1f56f067006fc 100644
--- a/app/code/Magento/User/i18n/en_US.csv
+++ b/app/code/Magento/User/i18n/en_US.csv
@@ -95,3 +95,26 @@ Resources,Resources
"Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?","Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?"
"Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?","Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?"
"Reset Password Template","Reset Password Template"
+No,No
+Yes,Yes
+Username,Username
+"Locked Users","Locked Users"
+"Unlocked %1 user(s).","Unlocked %1 user(s)."
+"This account is locked.","This account is locked."
+"It's time to change your password.","It's time to change your password."
+"It's time to change your password.","It's time to change your password."
+"Sorry, but this password has already been used. Please create another.","Sorry, but this password has already been used. Please create another."
+"Your password has expired; please contact your administrator.","Your password has expired; please contact your administrator."
+Recommended,Recommended
+Forced,Forced
+"Maximum Login Failures to Lockout Account","Maximum Login Failures to Lockout Account"
+"We will disable this feature if the value is empty.","We will disable this feature if the value is empty."
+"Lockout Time (minutes)","Lockout Time (minutes)"
+"Password Lifetime (days)","Password Lifetime (days)"
+"We will disable this feature if the value is empty. ","We will disable this feature if the value is empty. "
+"Password Change","Password Change"
+"Admin Accounts Locks","Admin Accounts Locks"
+Unlock,Unlock
+"Last login","Last login"
+Failures,Failures
+Unlocked,Unlocked
diff --git a/app/code/Magento/User/i18n/es_ES.csv b/app/code/Magento/User/i18n/es_ES.csv
index 3f27379d04352..4dd4f371b4af5 100644
--- a/app/code/Magento/User/i18n/es_ES.csv
+++ b/app/code/Magento/User/i18n/es_ES.csv
@@ -95,3 +95,27 @@ Resources,Resources
"Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?","Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?"
"Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?","Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?"
"Reset Password Template","Reset Password Template"
+No,No
+Yes,Yes
+Username,"Nombre de Usuario"
+"Locked Users","Usuarios bloqueados"
+"Unlocked %1 user(s).","Unlocked %1 user(s)."
+"This account is locked.","Esta cuenta está bloqueada."
+"It's time to change your password.","It's time to change your password."
+"It's time to change your password.","It's time to change your password."
+"Sorry, but this password has already been used. Please create another.","Sorry, but this password has already been used. Please create another."
+"Your password has expired; please contact your administrator.","Your password has expired; please contact your administrator."
+Recommended,Recomendado
+Forced,Forzado
+"Maximum Login Failures to Lockout Account","Maximum Login Failures to Lockout Account"
+"We will disable this feature if the value is empty.","We will disable this feature if the value is empty."
+"Lockout Time (minutes)","Lockout Time (minutes)"
+"Password Lifetime (days)","Password Lifetime (days)"
+"We will disable this feature if the value is empty. ","We will disable this feature if the value is empty. "
+"Password Change","Password Change"
+"Encryption Key Change","Cambio de clave de encriptación"
+"Admin Accounts Locks","Bloqueo de cuentas de administración"
+Unlock,Desbloquear
+"Last login","Ultimo acceso"
+Failures,Fallos
+Unlocked,"Bloqueado hasta"
diff --git a/app/code/Magento/User/i18n/fr_FR.csv b/app/code/Magento/User/i18n/fr_FR.csv
index 3f27379d04352..bbe1e63a96cbd 100644
--- a/app/code/Magento/User/i18n/fr_FR.csv
+++ b/app/code/Magento/User/i18n/fr_FR.csv
@@ -95,3 +95,27 @@ Resources,Resources
"Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?","Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?"
"Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?","Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?"
"Reset Password Template","Reset Password Template"
+No,No
+Yes,Yes
+Username,"Nom d'utilisateur"
+"Locked Users","Utilisateurs verrouillés"
+"Unlocked %1 user(s).","Unlocked %1 user(s)."
+"This account is locked.","Le compte est verrouillé."
+"It's time to change your password.","It's time to change your password."
+"It's time to change your password.","It's time to change your password."
+"Sorry, but this password has already been used. Please create another.","Sorry, but this password has already been used. Please create another."
+"Your password has expired; please contact your administrator.","Your password has expired; please contact your administrator."
+Recommended,Recommandé
+Forced,Forcé
+"Maximum Login Failures to Lockout Account","Maximum Login Failures to Lockout Account"
+"We will disable this feature if the value is empty.","We will disable this feature if the value is empty."
+"Lockout Time (minutes)","Lockout Time (minutes)"
+"Password Lifetime (days)","Password Lifetime (days)"
+"We will disable this feature if the value is empty. ","We will disable this feature if the value is empty. "
+"Password Change","Password Change"
+"Encryption Key Change","Modification Clé de Chiffrement"
+"Admin Accounts Locks","Verrous Comptes Administrateurs"
+Unlock,Déverrouiller
+"Last login","Dernière connexion"
+Failures,Echecs
+Unlocked,"Verrouillé jusqu'"
diff --git a/app/code/Magento/User/i18n/nl_NL.csv b/app/code/Magento/User/i18n/nl_NL.csv
index 3f27379d04352..91813e3a13311 100644
--- a/app/code/Magento/User/i18n/nl_NL.csv
+++ b/app/code/Magento/User/i18n/nl_NL.csv
@@ -95,3 +95,27 @@ Resources,Resources
"Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?","Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?"
"Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?","Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?"
"Reset Password Template","Reset Password Template"
+No,No
+Yes,Yes
+Username,Gebruikersnaam
+"Locked Users","Gesloten Gebruikers"
+"Unlocked %1 user(s).","Unlocked %1 user(s)."
+"This account is locked.","Dit account is geblokkeerd."
+"It's time to change your password.","It's time to change your password."
+"It's time to change your password.","It's time to change your password."
+"Sorry, but this password has already been used. Please create another.","Sorry, but this password has already been used. Please create another."
+"Your password has expired; please contact your administrator.","Your password has expired; please contact your administrator."
+Recommended,Aanbevolen
+Forced,Gedwongen
+"Maximum Login Failures to Lockout Account","Maximum Login Failures to Lockout Account"
+"We will disable this feature if the value is empty.","We will disable this feature if the value is empty."
+"Lockout Time (minutes)","Lockout Time (minutes)"
+"Password Lifetime (days)","Password Lifetime (days)"
+"We will disable this feature if the value is empty. ","We will disable this feature if the value is empty. "
+"Password Change","Password Change"
+"Encryption Key Change","Encryptie Code Veranderen"
+"Admin Accounts Locks","Beheerder Accounts Sloten"
+Unlock,Openen
+"Last login","Laatste login"
+Failures,Mislukkingen
+Unlocked,"Gesloten tot"
diff --git a/app/code/Magento/User/i18n/pt_BR.csv b/app/code/Magento/User/i18n/pt_BR.csv
index 3f27379d04352..d8d16b8cd04f7 100644
--- a/app/code/Magento/User/i18n/pt_BR.csv
+++ b/app/code/Magento/User/i18n/pt_BR.csv
@@ -95,3 +95,27 @@ Resources,Resources
"Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?","Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?"
"Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?","Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?"
"Reset Password Template","Reset Password Template"
+No,No
+Yes,Yes
+Username,"Nome do usuário"
+"Locked Users","Usuários Bloqueados"
+"Unlocked %1 user(s).","Unlocked %1 user(s)."
+"This account is locked.","Esta conta está bloqueada."
+"It's time to change your password.","It's time to change your password."
+"It's time to change your password.","It's time to change your password."
+"Sorry, but this password has already been used. Please create another.","Sorry, but this password has already been used. Please create another."
+"Your password has expired; please contact your administrator.","Your password has expired; please contact your administrator."
+Recommended,Recomendado
+Forced,Forçado
+"Maximum Login Failures to Lockout Account","Maximum Login Failures to Lockout Account"
+"We will disable this feature if the value is empty.","We will disable this feature if the value is empty."
+"Lockout Time (minutes)","Lockout Time (minutes)"
+"Password Lifetime (days)","Password Lifetime (days)"
+"We will disable this feature if the value is empty. ","We will disable this feature if the value is empty. "
+"Password Change","Password Change"
+"Encryption Key Change","Mudança na Chave de Criptografia"
+"Admin Accounts Locks","Bloqueios para Contas de Administrador"
+Unlock,Desbloquear
+"Last login","Último login"
+Failures,Falhas
+Unlocked,"Bloqueado até"
diff --git a/app/code/Magento/User/i18n/zh_CN.csv b/app/code/Magento/User/i18n/zh_CN.csv
index 3f27379d04352..1c10afb0b649b 100644
--- a/app/code/Magento/User/i18n/zh_CN.csv
+++ b/app/code/Magento/User/i18n/zh_CN.csv
@@ -95,3 +95,27 @@ Resources,Resources
"Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?","Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?"
"Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?","Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?"
"Reset Password Template","Reset Password Template"
+No,No
+Yes,Yes
+Username,用户名
+"Locked Users",锁定的用户
+"Unlocked %1 user(s).","Unlocked %1 user(s)."
+"This account is locked.",该帐户已被锁定。
+"It's time to change your password.","It's time to change your password."
+"It's time to change your password.","It's time to change your password."
+"Sorry, but this password has already been used. Please create another.","Sorry, but this password has already been used. Please create another."
+"Your password has expired; please contact your administrator.","Your password has expired; please contact your administrator."
+Recommended,推荐
+Forced,强制
+"Maximum Login Failures to Lockout Account","Maximum Login Failures to Lockout Account"
+"We will disable this feature if the value is empty.","We will disable this feature if the value is empty."
+"Lockout Time (minutes)","Lockout Time (minutes)"
+"Password Lifetime (days)","Password Lifetime (days)"
+"We will disable this feature if the value is empty. ","We will disable this feature if the value is empty. "
+"Password Change","Password Change"
+"Encryption Key Change",加密密钥已更改
+"Admin Accounts Locks",管理帐户锁定
+Unlock,解锁
+"Last login",上一次登录
+Failures,失败
+Unlocked,锁定直到
diff --git a/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_block.xml b/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_block.xml
new file mode 100644
index 0000000000000..2098d0a7e7760
--- /dev/null
+++ b/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_block.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+ lockedAdminsGrid
+ Magento\User\Model\Resource\User\Locked\Collection
+ user_id
+ 1
+
+ 1
+
+
+
+
+ user_id
+ unlock
+ 1
+
+ -
+
- Unlock
+ - */*/massUnlock
+ - 1
+
+
+
+
+
+
+ lockedAdminsGrid
+
+
+
+ ID
+ number
+ 0
+ user_id
+ user_id
+ col-id
+ col-id
+
+
+
+
+ Username
+ text
+ username
+ username
+ col-name
+ col-name
+
+
+
+
+ Last login
+ datetime
+ 0
+ last_login
+ logdate
+ col-date
+ col-date
+
+
+
+
+ Failures
+ 0
+ failures_num
+ failures_num
+
+
+
+
+ Unlocked
+ datetime
+ 0
+ lock_expires
+ lock_expires
+ col-date
+ col-date
+
+
+
+
+
+
+
diff --git a/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_grid.xml b/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_grid.xml
new file mode 100644
index 0000000000000..bce6ee8a55c66
--- /dev/null
+++ b/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_grid.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_index.xml b/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_index.xml
new file mode 100644
index 0000000000000..ac9e34a19610d
--- /dev/null
+++ b/app/code/Magento/User/view/adminhtml/layout/adminhtml_locks_index.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Widget/Model/Template/Filter.php b/app/code/Magento/Widget/Model/Template/Filter.php
index d2a9f11772deb..ea49425318740 100644
--- a/app/code/Magento/Widget/Model/Template/Filter.php
+++ b/app/code/Magento/Widget/Model/Template/Filter.php
@@ -34,6 +34,7 @@ class Filter extends \Magento\Cms\Model\Template\Filter
* @param \Magento\Framework\App\State $appState
* @param \Magento\Framework\UrlInterface $urlModel
* @param \Pelago\Emogrifier $emogrifier
+ * @param \Magento\Email\Model\Source\Variables $configVariables
* @param \Magento\Widget\Model\Resource\Widget $widgetResource
* @param \Magento\Widget\Model\Widget $widget
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -51,6 +52,7 @@ public function __construct(
\Magento\Framework\App\State $appState,
\Magento\Framework\UrlInterface $urlModel,
\Pelago\Emogrifier $emogrifier,
+ \Magento\Email\Model\Source\Variables $configVariables,
\Magento\Widget\Model\Resource\Widget $widgetResource,
\Magento\Widget\Model\Widget $widget
) {
@@ -68,7 +70,8 @@ public function __construct(
$layoutFactory,
$appState,
$urlModel,
- $emogrifier
+ $emogrifier,
+ $configVariables
);
}
diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json
index 1a9190debb3a5..936d461a2a7f8 100644
--- a/app/code/Magento/Widget/composer.json
+++ b/app/code/Magento/Widget/composer.json
@@ -7,6 +7,7 @@
"magento/module-cms": "1.0.0-beta",
"magento/module-backend": "1.0.0-beta",
"magento/module-catalog": "1.0.0-beta",
+ "magento/module-email": "1.0.0-beta",
"magento/module-theme": "1.0.0-beta",
"magento/framework": "1.0.0-beta",
"magento/module-variable": "1.0.0-beta",
diff --git a/composer.json b/composer.json
index a7cdb013bb38d..3d56ffc30ad81 100644
--- a/composer.json
+++ b/composer.json
@@ -111,6 +111,7 @@
"magento/module-downloadable": "self.version",
"magento/module-eav": "self.version",
"magento/module-email": "self.version",
+ "magento/module-encryption-key": "self.version",
"magento/module-fedex": "self.version",
"magento/module-gift-message": "self.version",
"magento/module-google-adwords": "self.version",
diff --git a/composer.lock b/composer.lock
index 16141689d88af..878cafac4f2e4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "20c37ec30731e0b8d0cd52a33c9dec89",
+ "hash": "3c94391144a4c2de663dfa465b3a2e8a",
"packages": [
{
"name": "braintree/braintree_php",
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
index 41da1ae272f38..8e1e7be037137 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
@@ -356,6 +356,10 @@ protected function getRow(array $filter, $isStrict = true)
$rowTemplate = ($isStrict) ? $this->rowTemplateStrict : $this->rowTemplate;
$rows = [];
foreach ($filter as $value) {
+ if (strpos($value, '"') !== false) {
+ $rowTemplate = str_replace('"', '', $rowTemplate);
+ $value = $this->xpathEscape($value);
+ }
$rows[] = sprintf($rowTemplate, $value);
}
$location = sprintf($this->rowPattern, implode(' and ', $rows));
@@ -453,4 +457,30 @@ public function openFirstRow()
{
$this->_rootElement->find($this->firstRowSelector, Locator::SELECTOR_XPATH)->click();
}
+
+ /**
+ * Escape single and/or double quotes in XPath selector by concat()
+ *
+ * @param string $query
+ * @param string $defaultDelim [optional]
+ * @return string
+ */
+ protected function xpathEscape($query, $defaultDelim = '"')
+ {
+ if (strpos($query, $defaultDelim) === false) {
+ return $defaultDelim . $query . $defaultDelim;
+ }
+ preg_match_all("#(?:('+)|[^']+)#", $query, $matches);
+ list($parts, $apos) = $matches;
+ $delim = '';
+ foreach ($parts as $i => &$part) {
+ $delim = $apos[$i] ? '"' : "'";
+ $part = $delim . $part . $delim;
+ }
+ if (count($parts) == 1) {
+ $parts[] = $delim . $delim;
+ }
+
+ return 'concat(' . implode(',', $parts) . ')';
+ }
}
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/Block/Adminhtml/Integration/Edit/IntegrationForm.php b/dev/tests/functional/tests/app/Magento/Integration/Test/Block/Adminhtml/Integration/Edit/IntegrationForm.php
index 875cf0fefabef..a73cfc3bd98fa 100644
--- a/dev/tests/functional/tests/app/Magento/Integration/Test/Block/Adminhtml/Integration/Edit/IntegrationForm.php
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/Block/Adminhtml/Integration/Edit/IntegrationForm.php
@@ -13,5 +13,16 @@
*/
class IntegrationForm extends FormTabs
{
- //
+ /**
+ * Get array of label => js error text.
+ *
+ * @param string $tabName
+ * @return array
+ */
+ public function getJsErrors($tabName)
+ {
+ $tab = $this->getTab($tabName);
+ $this->openTab($tabName);
+ return $tab->getJsErrors();
+ }
}
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/Block/Adminhtml/Integration/Edit/IntegrationFormPageActions.php b/dev/tests/functional/tests/app/Magento/Integration/Test/Block/Adminhtml/Integration/Edit/IntegrationFormPageActions.php
index 6afacd6b0afab..48b34514e43d0 100644
--- a/dev/tests/functional/tests/app/Magento/Integration/Test/Block/Adminhtml/Integration/Edit/IntegrationFormPageActions.php
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/Block/Adminhtml/Integration/Edit/IntegrationFormPageActions.php
@@ -15,14 +15,14 @@
class IntegrationFormPageActions extends FormPageActions
{
/**
- * Save button
+ * Save button.
*
* @var string
*/
protected $saveNewButton = '[data-ui-id="integration-edit-content-save-split-button-button"]';
/**
- * Click on "Save" with split button
+ * Click on "Save" with split button.
*
* @return void
*/
@@ -30,4 +30,35 @@ public function saveNew()
{
$this->_rootElement->find($this->saveNewButton)->click();
}
+
+ /**
+ * Check if alert is present.
+ *
+ * @return bool
+ */
+ public function isAlertPresent()
+ {
+ try {
+ $this->browser->getAlertText();
+ return true;
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Accept alert.
+ *
+ * @return void
+ */
+ public function acceptAlert()
+ {
+ try {
+ while (true) {
+ $this->browser->acceptAlert();
+ }
+ } catch (\Exception $e) {
+ return;
+ }
+ }
}
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertEmailValidationErrorGenerated.php b/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertEmailValidationErrorGenerated.php
new file mode 100644
index 0000000000000..e23e2a88a4e8e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertEmailValidationErrorGenerated.php
@@ -0,0 +1,52 @@
+getIntegrationForm()->getJsErrors("integration_info");
+ $emailJsError = false;
+ foreach ($errors as $error) {
+ if (strpos($error, 'Please enter a valid email address') !== false) {
+ $emailJsError = true;
+ break;
+ }
+ }
+ \PHPUnit_Framework_Assert::assertTrue(
+ $emailJsError,
+ 'Failed to validate email address (' . $integration->getEmail() . ') when saving integration.'
+ );
+ }
+
+ /**
+ * Returns a string representation of successful assertion.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'Email address is properly validated when saving integration.';
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertIntegrationNameDuplicationErrorMessage.php b/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertIntegrationNameDuplicationErrorMessage.php
new file mode 100644
index 0000000000000..99613bf462381
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertIntegrationNameDuplicationErrorMessage.php
@@ -0,0 +1,51 @@
+getName());
+ $actualMessage = $integrationIndexPage->getMessagesBlock()->getErrorMessages();
+ \PHPUnit_Framework_Assert::assertEquals(
+ $expectedMessage,
+ $actualMessage,
+ 'Wrong error message is displayed.'
+ . "\nExpected: " . $expectedMessage
+ . "\nActual: " . $actualMessage
+ );
+ }
+
+ /**
+ * Returns a string representation of successful assertion.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'Duplicated integration name error message is correct.';
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertIntegrationSuccessSaveMessageNotPresent.php b/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertIntegrationSuccessSaveMessageNotPresent.php
new file mode 100644
index 0000000000000..ac23f60261388
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertIntegrationSuccessSaveMessageNotPresent.php
@@ -0,0 +1,51 @@
+getMessagesBlock()->isVisible()) {
+ try {
+ $integrationIndex->getMessagesBlock()->getSuccessMessages();
+ } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
+ $noSuccessMessage = true;
+ }
+ } else {
+ $noSuccessMessage = true;
+ }
+ \PHPUnit_Framework_Assert::assertTrue(
+ $noSuccessMessage,
+ 'Integration is not saved.'
+ );
+ }
+
+ /**
+ * Returns a string representation of successful assertion.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'Integration is not saved.';
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertNoAlertPopup.php b/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertNoAlertPopup.php
new file mode 100644
index 0000000000000..9dddeed18e9e1
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/Constraint/AssertNoAlertPopup.php
@@ -0,0 +1,45 @@
+getFormPageActions()->isAlertPresent();
+ if ($isAlertPresent) {
+ $integrationNew->getFormPageActions()->acceptAlert();
+ }
+ \PHPUnit_Framework_Assert::assertFalse(
+ $isAlertPresent,
+ 'Saving an integration should not cause alert.'
+ );
+ }
+
+ /**
+ * Returns a string representation of successful assertion.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'Integration is saved with no alert.';
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/Fixture/Integration.xml b/dev/tests/functional/tests/app/Magento/Integration/Test/Fixture/Integration.xml
index f2ed1bfc1e24d..2712dcbae41d7 100644
--- a/dev/tests/functional/tests/app/Magento/Integration/Test/Fixture/Integration.xml
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/Fixture/Integration.xml
@@ -14,7 +14,7 @@
repository_class="Magento\Integration\Test\Repository\Integration"
handler_interface="Magento\Integration\Test\Handler\Integration\IntegrationInterface"
class="Magento\Integration\Test\Fixture\Integration">
-
+
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php
index b57e65919f29f..ed72ad49b1013 100644
--- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php
@@ -21,7 +21,7 @@
* 6. Perform all assertions.
*
* @group Web_API_Framework_(PS)
- * @ZephyrId MAGETWO-26009
+ * @ZephyrId MAGETWO-26009, MAGETWO-16755, MAGETWO-16819, MAGETWO-16820
*/
class CreateIntegrationEntityTest extends Injectable
{
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.xml b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.xml
index 1ac9ad966192f..a908c02ec1d8e 100644
--- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.xml
@@ -7,7 +7,7 @@
-->
-
+
Integration%isolation%
test@example.com
https://endpoint.com
@@ -17,7 +17,7 @@
-
+
Integration%isolation%
Custom
Sales/Operations/Invoices
@@ -26,12 +26,139 @@
-
+
Integration%isolation%
All
+
+ <script>alert('XSS-%isolation%')</script>
+ -
+ <script>alert('XSS')</script>
+ <script>alert('XSS')</script>
+ All
+
+
+
+
+
+
+ <IMG SRC=javascript:alert('XSS-%isolation%')>
+ -
+ <IMG SRC=javascript:alert('XSS')>
+ <IMG SRC=javascript:alert('XSS')>
+ All
+
+
+
+
+
+
+ name-%isolation%' OR 'a'='a
+ -
+ endpoint' OR 'a'='a
+ link' OR 'a'='a
+ All
+
+
+
+
+
+
+ name-%isolation%" OR "a"="a
+ -
+ endpoint" OR "a"="a
+ link" OR "a"="a
+ All
+
+
+
+
+
+
+ name-%isolation%" OR 'a"='a
+ -
+ endpoint" OR 'a"='a
+ link" OR 'a"='a
+ All
+
+
+
+
+
+
+ Integration%isolation%
+ abc.example.com
+ https://endpoint.com
+ https://testlink.com
+ All
+
+
+
+
+ Integration%isolation%
+ abc.@example.com
+ https://endpoint.com
+ https://testlink.com
+ All
+
+
+
+
+ Integration%isolation%
+ abc..123@example.com
+ https://endpoint.com
+ https://testlink.com
+ All
+
+
+
+
+ Integration%isolation%
+ a@b@c@example.com
+ https://endpoint.com
+ https://testlink.com
+ All
+
+
+
+
+ Integration%isolation%
+ a"b(c)d,e:f;g<h>i[j\k]l@example.com
+ https://endpoint.com
+ https://testlink.com
+ All
+
+
+
+
+ Integration%isolation%
+ this\ still\"not\\allowed@example.com
+ https://endpoint.com
+ https://testlink.com
+ All
+
+
+
+
+ Integration%isolation%
+ just"not"right@example.com
+ https://endpoint.com
+ https://testlink.com
+ All
+
+
+
+
+ Integration%isolation%
+ this is"not\allowed@example.com
+ https://endpoint.com
+ https://testlink.com
+ All
+
+
+
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php
new file mode 100644
index 0000000000000..e2f1411b45af1
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php
@@ -0,0 +1,83 @@
+ Extensions > Integrations
+ * 3. Click 'Add New Integration'
+ * 4. Fill in all required data
+ * 5. Click "Save" button to save Integration1
+ * 6. Click 'Add New Integration'
+ * 7. Fill in all required data and use the same name as for Integration1
+ * 8. Click "Save" button
+ * 9. Perform all assertions
+ *
+ * @group Web_API_Framework_(PS)
+ * @ZephyrId MAGETWO-16756
+ */
+class CreateIntegrationWithDuplicatedNameTest extends Injectable
+{
+ /* tags */
+ const MVP = 'yes';
+ const DOMAIN = 'PS';
+ /* end tags */
+
+ /**
+ * Integration grid page.
+ *
+ * @var IntegrationIndex
+ */
+ protected $integrationIndexPage;
+
+ /**
+ * Integration new page.
+ *
+ * @var IntegrationNew
+ */
+ protected $integrationNewPage;
+
+ /**
+ * Injection data.
+ *
+ * @param IntegrationIndex $integrationIndex
+ * @param IntegrationNew $integrationNew
+ * @return void
+ */
+ public function __inject(
+ IntegrationIndex $integrationIndex,
+ IntegrationNew $integrationNew
+ ) {
+ $this->integrationIndexPage = $integrationIndex;
+ $this->integrationNewPage = $integrationNew;
+ }
+
+ /**
+ * Create Integration Entity with existing name test.
+ *
+ * @param Integration $integration
+ * @return array
+ */
+ public function test(Integration $integration)
+ {
+ // Precondition
+ $integration->persist();
+
+ // Steps
+ $this->integrationIndexPage->open();
+ $this->integrationIndexPage->getGridPageActions()->addNew();
+ $this->integrationNewPage->getIntegrationForm()->fill($integration);
+ $this->integrationNewPage->getFormPageActions()->saveNew();
+ return ['integration' => $integration];
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.xml b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.xml
new file mode 100644
index 0000000000000..e7f54bb994ca2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ default
+
+
+
+
diff --git a/dev/tests/integration/testsuite/Magento/EncryptionKey/Block/Adminhtml/Crypt/Key/EditTest.php b/dev/tests/integration/testsuite/Magento/EncryptionKey/Block/Adminhtml/Crypt/Key/EditTest.php
new file mode 100644
index 0000000000000..76905b3097756
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/EncryptionKey/Block/Adminhtml/Crypt/Key/EditTest.php
@@ -0,0 +1,26 @@
+get(
+ 'Magento\Framework\View\LayoutInterface'
+ )->createBlock(
+ 'Magento\EncryptionKey\Block\Adminhtml\Crypt\Key\Edit'
+ );
+
+ $this->assertEquals('Encryption Key', $block->getHeaderText());
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/EncryptionKey/Block/Adminhtml/Crypt/Key/FormTest.php b/dev/tests/integration/testsuite/Magento/EncryptionKey/Block/Adminhtml/Crypt/Key/FormTest.php
new file mode 100644
index 0000000000000..7315cd9f10f3e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/EncryptionKey/Block/Adminhtml/Crypt/Key/FormTest.php
@@ -0,0 +1,54 @@
+get('Magento\Framework\View\DesignInterface')
+ ->setArea(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE)
+ ->setDefaultDesignTheme();
+
+ $block = $objectManager->get('Magento\Framework\View\LayoutInterface')
+ ->createBlock('Magento\EncryptionKey\Block\Adminhtml\Crypt\Key\Form');
+
+ $prepareFormMethod = new \ReflectionMethod(
+ 'Magento\EncryptionKey\Block\Adminhtml\Crypt\Key\Form',
+ '_prepareForm'
+ );
+ $prepareFormMethod->setAccessible(true);
+ $prepareFormMethod->invoke($block);
+
+ $form = $block->getForm();
+
+ $this->assertEquals('edit_form', $form->getId());
+ $this->assertEquals('post', $form->getMethod());
+
+ foreach (['enc_key_note', 'generate_random', 'crypt_key', 'main_fieldset'] as $id) {
+ $element = $form->getElement($id);
+ $this->assertNotNull($element);
+ }
+
+ $generateRandomField = $form->getElement('generate_random');
+ $this->assertEquals('select', $generateRandomField->getType());
+ $this->assertEquals([ 0 => 'No', 1 => 'Yes'], $generateRandomField->getOptions());
+
+ $cryptKeyField = $form->getElement('crypt_key');
+ $this->assertEquals('text', $cryptKeyField->getType());
+ $this->assertEquals('crypt_key', $cryptKeyField->getName());
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/EncryptionKey/Controller/Adminhtml/Crypt/Key/IndexTest.php b/dev/tests/integration/testsuite/Magento/EncryptionKey/Controller/Adminhtml/Crypt/Key/IndexTest.php
new file mode 100644
index 0000000000000..6d892bb9d8861
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/EncryptionKey/Controller/Adminhtml/Crypt/Key/IndexTest.php
@@ -0,0 +1,20 @@
+dispatch('backend/admin/crypt_key/index');
+
+ $body = $this->getResponse()->getBody();
+ $this->assertContains('Encryption Key
', $body);
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/EncryptionKey/Controller/Adminhtml/Crypt/Key/SaveTest.php b/dev/tests/integration/testsuite/Magento/EncryptionKey/Controller/Adminhtml/Crypt/Key/SaveTest.php
new file mode 100644
index 0000000000000..e0b0a11cd72f8
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/EncryptionKey/Controller/Adminhtml/Crypt/Key/SaveTest.php
@@ -0,0 +1,105 @@
+getRequest();
+ $request
+ ->setPostValue('generate_random', $ifGenerateRandom)
+ ->setPostValue('crypt_key', $encryptionKey);
+ $this->dispatch('backend/admin/crypt_key/save');
+ $this->assertSessionMessages(
+ $this->contains('Please enter an encryption key.'),
+ \Magento\Framework\Message\MessageInterface::TYPE_ERROR
+ );
+ }
+
+ /**
+ * Test save action with provided encryption key
+ *
+ * @magentoDbIsolation enabled
+ */
+ public function testSaveActionWithProvidedKey()
+ {
+ $this->markTestSkipped('Test is blocked by MAGETWO-33612.');
+
+ // data set with provided encryption key
+ $ifGenerateRandom = '0';
+ $encryptionKey = 'foo_encryption_key';
+
+ $request = $this->getRequest();
+ $request
+ ->setPostValue('generate_random', $ifGenerateRandom)
+ ->setPostValue('crypt_key', $encryptionKey);
+ $this->dispatch('backend/admin/crypt_key/save');
+
+ $this->assertRedirect();
+ $this->assertSessionMessages(
+ $this->contains('The encryption key has been changed.'),
+ \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS
+ );
+ }
+
+ /**
+ * Test save action with invalid encryption key
+ */
+ public function testSaveActionWithInvalidKey()
+ {
+ // data set with provided encryption key
+ $ifGenerateRandom = '0';
+ $encryptionKey = 'invalid key';
+
+ $params = [
+ 'generate_random' => $ifGenerateRandom,
+ 'crypt_key' => $encryptionKey,
+ ];
+ $this->getRequest()->setPostValue($params);
+ $this->dispatch('backend/admin/crypt_key/save');
+
+ $this->assertRedirect();
+ $this->assertSessionMessages(
+ $this->contains('The encryption key format is invalid.'),
+ \Magento\Framework\Message\MessageInterface::TYPE_ERROR
+ );
+ }
+
+ /**
+ * Test save action with randomly generated key
+ *
+ * @magentoDbIsolation enabled
+ */
+ public function testSaveActionWithRandomKey()
+ {
+ $this->markTestSkipped('Test is blocked by MAGETWO-33612.');
+
+ // data set with random encryption key
+ $ifGenerateRandom = '1';
+ $encryptionKey = '';
+
+ $request = $this->getRequest();
+ $request
+ ->setPostValue('generate_random', $ifGenerateRandom)
+ ->setPostValue('crypt_key', $encryptionKey);
+ $this->dispatch('backend/admin/crypt_key/save');
+
+ $this->assertRedirect();
+ $this->assertSessionMessages(
+ $this->contains('The encryption key has been changed.'),
+ \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS
+ );
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/EncryptionKey/Model/Resource/Key/ChangeTest.php b/dev/tests/integration/testsuite/Magento/EncryptionKey/Model/Resource/Key/ChangeTest.php
new file mode 100644
index 0000000000000..494b050594c39
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/EncryptionKey/Model/Resource/Key/ChangeTest.php
@@ -0,0 +1,98 @@
+objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage Deployment configuration file is not writable
+ */
+ public function testChangeEncryptionKeyConfigNotWritable()
+ {
+ $writerMock = $this->getMock('Magento\Framework\App\DeploymentConfig\Writer', [], [], '', false);
+ $writerMock->expects($this->once())->method('checkIfWritable')->will($this->returnValue(false));
+
+ /** @var \Magento\EncryptionKey\Model\Resource\Key\Change $keyChangeModel */
+ $keyChangeModel = $this->objectManager->create(
+ 'Magento\EncryptionKey\Model\Resource\Key\Change',
+ ['writer' => $writerMock]
+ );
+ $keyChangeModel->changeEncryptionKey();
+ }
+
+ /**
+ * @magentoDbIsolation enabled
+ * @magentoDataFixture Magento/EncryptionKey/_files/payment_info.php
+ */
+ public function testChangeEncryptionKey()
+ {
+ $testPath = 'test/config';
+ $testValue = 'test';
+
+ $writerMock = $this->getMock('Magento\Framework\App\DeploymentConfig\Writer', [], [], '', false);
+ $writerMock->expects($this->once())->method('checkIfWritable')->will($this->returnValue(true));
+
+ $structureMock = $this->getMock('Magento\Config\Model\Config\Structure', [], [], '', false);
+ $structureMock->expects($this->once())
+ ->method('getFieldPathsByAttribute')
+ ->will($this->returnValue([$testPath]));
+
+ /** @var \Magento\EncryptionKey\Model\Resource\Key\Change $keyChangeModel */
+ $keyChangeModel = $this->objectManager->create(
+ 'Magento\EncryptionKey\Model\Resource\Key\Change',
+ ['structure' => $structureMock, 'writer' => $writerMock]
+ );
+
+ $configModel = $this->objectManager->create(
+ 'Magento\Config\Model\Resource\Config'
+ );
+ $configModel->saveConfig($testPath, 'test', 'default', 0);
+ $this->assertNotNull($keyChangeModel->changeEncryptionKey());
+
+ $connection = $keyChangeModel->getConnection();
+ // Verify that the config value has been encrypted
+ $values1 = $connection->fetchPairs(
+ $connection->select()->from(
+ $keyChangeModel->getTable('core_config_data'),
+ ['config_id', 'value']
+ )->where(
+ 'path IN (?)',
+ [$testPath]
+ )->where(
+ 'value NOT LIKE ?',
+ ''
+ )
+ );
+ $this->assertNotContains($testValue, $values1);
+
+ // Verify that the credit card number has been encrypted
+ $values2 = $connection->fetchPairs(
+ $connection->select()->from(
+ $keyChangeModel->getTable('sales_order_payment'),
+ ['entity_id', 'cc_number_enc']
+ )
+ );
+ $this->assertNotContains('1111111111', $values2);
+
+ /** clean up */
+ $select = $connection->select()->from($configModel->getMainTable())->where('path=?', $testPath);
+ $this->assertNotEmpty($connection->fetchRow($select));
+ $configModel->deleteConfig($testPath, 'default', 0);
+ $this->assertEmpty($connection->fetchRow($select));
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/EncryptionKey/_files/payment_info.php b/dev/tests/integration/testsuite/Magento/EncryptionKey/_files/payment_info.php
new file mode 100644
index 0000000000000..3edd7cc9c1da8
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/EncryptionKey/_files/payment_info.php
@@ -0,0 +1,20 @@
+create('Magento\Sales\Model\Order\Payment');
+$paymentInfo->setMethod('Cc')->setData('cc_number_enc', '1111111111');
+
+/** @var \Magento\Sales\Model\Order $order */
+$order = $objectManager->create('Magento\Sales\Model\Order');
+$order->setIncrementId(
+ '100000001'
+)->setPayment(
+ $paymentInfo
+);
+$order->save();
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/ComposerInformationTest.php b/dev/tests/integration/testsuite/Magento/Framework/Composer/ComposerInformationTest.php
index 75e7b277f9308..590a553274d7d 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Composer/ComposerInformationTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/ComposerInformationTest.php
@@ -29,11 +29,6 @@ class ComposerInformationTest extends \PHPUnit_Framework_TestCase
*/
private $composerJsonFinder;
- /**
- * @var \Magento\Framework\Filesystem
- */
- private $filesystem;
-
public function setUp()
{
$this->objectManager = Bootstrap::getObjectManager();
@@ -81,8 +76,7 @@ public function testGetRequiredPhpVersion($composerDir)
'applicationFactory' => new MagentoComposerApplicationFactory(
$this->composerJsonFinder,
$this->directoryList
- ),
- 'filesystem' => $this->filesystem,
+ )
]
);
@@ -106,8 +100,7 @@ public function testGetRequiredExtensions($composerDir)
'applicationFactory' => new MagentoComposerApplicationFactory(
$this->composerJsonFinder,
$this->directoryList
- ),
- 'filesystem' => $this->filesystem,
+ )
]
);
@@ -133,8 +126,7 @@ public function testGetRootRequiredPackagesAndTypes($composerDir)
'applicationFactory' => new MagentoComposerApplicationFactory(
$this->composerJsonFinder,
$this->directoryList
- ),
- 'filesystem' => $this->filesystem,
+ )
]
);
@@ -144,41 +136,6 @@ public function testGetRootRequiredPackagesAndTypes($composerDir)
$this->assertEquals('library', $requiredPackagesAndTypes['composer/composer']);
}
- public function testGetPackagesForUpdate()
- {
- $packageName = 'magento/language-de_de';
-
- $this->setupDirectory('testSkeleton');
-
- /** @var \Magento\Framework\Composer\ComposerInformation $composerInfo */
- $composerInfo = $this->objectManager->create(
- 'Magento\Framework\Composer\ComposerInformation',
- [
- 'applicationFactory' => new MagentoComposerApplicationFactory(
- $this->composerJsonFinder,
- $this->directoryList
- ),
- 'filesystem' => $this->filesystem,
- ]
- );
-
- $requiredPackages = $composerInfo->getInstalledMagentoPackages();
- $this->assertArrayHasKey($packageName, $requiredPackages);
-
- $this->assertTrue($composerInfo->syncPackagesForUpdate());
-
- $packagesForUpdate = $composerInfo->getPackagesForUpdate();
- $this->assertArrayHasKey('packages', $packagesForUpdate);
- $this->assertArrayHasKey($packageName, $packagesForUpdate['packages']);
- $this->assertTrue(
- version_compare(
- $packagesForUpdate['packages'][$packageName]['latestVersion'],
- $requiredPackages[$packageName]['version'],
- '>'
- )
- );
- }
-
/**
* Data provider that returns directories containing different types of composer files.
*
@@ -206,8 +163,7 @@ public function testNoLock()
'applicationFactory' => new MagentoComposerApplicationFactory(
$this->composerJsonFinder,
$this->directoryList
- ),
- 'filesystem' => $this->filesystem,
+ )
]
);
}
@@ -223,8 +179,7 @@ public function testIsPackageInComposerJson()
'applicationFactory' => new MagentoComposerApplicationFactory(
$this->composerJsonFinder,
$this->directoryList
- ),
- 'filesystem' => $this->filesystem,
+ )
]
);
diff --git a/dev/tests/integration/testsuite/Magento/Setup/Controller/ComponentGridTest.php b/dev/tests/integration/testsuite/Magento/Setup/Controller/ComponentGridTest.php
index f9032e83e2e52..7fe1f34ec5c00 100644
--- a/dev/tests/integration/testsuite/Magento/Setup/Controller/ComponentGridTest.php
+++ b/dev/tests/integration/testsuite/Magento/Setup/Controller/ComponentGridTest.php
@@ -8,14 +8,20 @@
use Magento\Framework\Composer\ComposerInformation;
use Magento\Framework\Module\PackageInfo;
+use Magento\Setup\Model\UpdatePackagesCache;
class ComponentGridTest extends \PHPUnit_Framework_TestCase
{
/**
- * @var ComposerInformation
+ * @var ComposerInformation|\PHPUnit_Framework_MockObject_MockObject
*/
private $composerInformationMock;
+ /**
+ * @var UpdatePackagesCache|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $updatePackagesCacheMock;
+
/**
* Module package info
*
@@ -101,12 +107,21 @@ public function __construct()
'',
false
);
+ $this->updatePackagesCacheMock = $this->getMock(
+ 'Magento\Setup\Model\UpdatePackagesCache',
+ [],
+ [],
+ '',
+ false
+ );
+
$packageInfoFactory->expects($this->once())
->method('create')
->willReturn($this->packageInfo);
$this->controller = new ComponentGrid(
$this->composerInformationMock,
- $objectManagerProvider
+ $objectManagerProvider,
+ $this->updatePackagesCacheMock
);
}
@@ -128,7 +143,7 @@ public function testComponentsAction()
$this->composerInformationMock->expects($this->once())
->method('isPackageInComposerJson')
->willReturn(true);
- $this->composerInformationMock->expects($this->once())
+ $this->updatePackagesCacheMock->expects($this->once())
->method('getPackagesForUpdate')
->willReturn($this->lastSyncData);
$jsonModel = $this->controller->componentsAction();
@@ -153,9 +168,9 @@ public function testComponentsAction()
public function testSyncAction()
{
- $this->composerInformationMock->expects($this->once())
+ $this->updatePackagesCacheMock->expects($this->once())
->method('syncPackagesForUpdate');
- $this->composerInformationMock->expects($this->once())
+ $this->updatePackagesCacheMock->expects($this->once())
->method('getPackagesForUpdate')
->willReturn($this->lastSyncData);
$jsonModel = $this->controller->syncAction();
diff --git a/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php b/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php
new file mode 100644
index 0000000000000..2e94d3898f3d5
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php
@@ -0,0 +1,115 @@
+objectManager = Bootstrap::getObjectManager();
+ }
+
+ /**
+ * Setup DirectoryList, Filesystem, and ComposerJsonFinder to use a specified directory for reading composer files
+ *
+ * @param $composerDir string Directory under _files that contains composer files
+ */
+ private function setupDirectory($composerDir)
+ {
+ $absoluteComposerDir = realpath(__DIR__ . '/_files/' . $composerDir . '/composer.json');
+ $this->composerJsonFinder = $this->getMockBuilder('Magento\Framework\Composer\ComposerJsonFinder')
+ ->disableOriginalConstructor()
+ ->setMethods([])
+ ->getMock();
+ $this->composerJsonFinder->expects($this->any())->method('findComposerJson')->willReturn($absoluteComposerDir);
+
+ $this->directoryList = $this->objectManager->get('Magento\Framework\App\Filesystem\DirectoryList');
+ $this->filesystem = $this->objectManager->get('Magento\Framework\Filesystem');
+
+ /** @var \Magento\Framework\Composer\ComposerInformation $composerInfo */
+ $this->composerInformation = $this->objectManager->create(
+ 'Magento\Framework\Composer\ComposerInformation',
+ [
+ 'applicationFactory' => new MagentoComposerApplicationFactory(
+ $this->composerJsonFinder,
+ $this->directoryList
+ )
+ ]
+ );
+ }
+
+ public function testGetPackagesForUpdate()
+ {
+ $packageName = 'magento/module-store';
+
+ $this->setupDirectory('testSkeleton');
+
+ /** @var \Magento\Setup\Model\UpdatePackagesCache $updatePackagesCache */
+ $updatePackagesCache = $this->objectManager->create(
+ 'Magento\Setup\Model\UpdatePackagesCache',
+ [
+ 'applicationFactory' => new MagentoComposerApplicationFactory(
+ $this->composerJsonFinder,
+ $this->directoryList
+ ),
+ 'filesystem' => $this->filesystem,
+ 'dateTime' => new DateTime(),
+ 'composerInformation' => $this->composerInformation
+ ]
+ );
+
+ $requiredPackages = $this->composerInformation->getInstalledMagentoPackages();
+ $this->assertArrayHasKey($packageName, $requiredPackages);
+
+ $this->assertTrue($updatePackagesCache->syncPackagesForUpdate());
+
+ $packagesForUpdate = $updatePackagesCache->getPackagesForUpdate();
+ $this->assertArrayHasKey('packages', $packagesForUpdate);
+ $this->assertArrayHasKey($packageName, $packagesForUpdate['packages']);
+ $this->assertTrue(
+ version_compare(
+ $packagesForUpdate['packages'][$packageName]['latestVersion'],
+ $requiredPackages[$packageName]['version'],
+ '>'
+ )
+ );
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.json b/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.json
new file mode 100644
index 0000000000000..945bccecd52ed
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.json
@@ -0,0 +1,24 @@
+{
+ "version": "0.74.0-beta9",
+ "require": {
+ "magento/product-community-edition": "0.74.0-beta2",
+ "magento/sample-module-minimal" : "*"
+ },
+ "repositories": [
+ {
+ "type": "composer",
+ "url": "http://packages.magento.com/"
+ }
+ ],
+ "autoload": {
+ "psr-4": {
+ "Magento\\Framework\\": "htdocs/lib/internal/Magento/Framework/",
+ "Magento\\Setup\\": "htdocs/setup/src/Magento/Setup/"
+ }
+ },
+ "extra": {
+ "magento-root-dir": "htdocs",
+ "magento-deploystrategy": "copy"
+ },
+ "minimum-stability": "dev"
+}
diff --git a/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.lock b/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.lock
new file mode 100644
index 0000000000000..0a8ab77a1d894
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.lock
@@ -0,0 +1,6174 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "8601c8b464025318475d28dbabf9ee67",
+ "packages": [
+ {
+ "name": "composer/composer",
+ "version": "1.0.0-alpha8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/composer.git",
+ "reference": "1eb1df44a97fb2daca1bb8b007f3bee012f0aa46"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/composer/zipball/1eb1df44a97fb2daca1bb8b007f3bee012f0aa46",
+ "reference": "1eb1df44a97fb2daca1bb8b007f3bee012f0aa46",
+ "shasum": ""
+ },
+ "require": {
+ "justinrainbow/json-schema": "1.1.*",
+ "php": ">=5.3.2",
+ "seld/jsonlint": "1.*",
+ "symfony/console": "~2.3",
+ "symfony/finder": "~2.2",
+ "symfony/process": "~2.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~3.7.10"
+ },
+ "suggest": {
+ "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
+ "ext-zip": "Enabling the zip extension allows you to unzip archives, and allows gzip compression of all internet traffic"
+ },
+ "bin": [
+ "bin/composer"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Composer": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be",
+ "role": "Developer"
+ },
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Dependency Manager",
+ "homepage": "http://getcomposer.org/",
+ "keywords": [
+ "autoload",
+ "dependency",
+ "package"
+ ],
+ "time": "2014-01-06 18:39:59"
+ },
+ {
+ "name": "justinrainbow/json-schema",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/justinrainbow/json-schema.git",
+ "reference": "05ff6d8d79fe3ad190b0663d80d3f9deee79416c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/05ff6d8d79fe3ad190b0663d80d3f9deee79416c",
+ "reference": "05ff6d8d79fe3ad190b0663d80d3f9deee79416c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "JsonSchema": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "NewBSD"
+ ],
+ "authors": [
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch",
+ "homepage": "http://wiedler.ch/igor/"
+ },
+ {
+ "name": "Bruno Prieto Reis",
+ "email": "bruno.p.reis@gmail.com"
+ },
+ {
+ "name": "Justin Rainbow",
+ "email": "justin.rainbow@gmail.com"
+ },
+ {
+ "name": "Robert Schönthal",
+ "email": "robert.schoenthal@gmail.com",
+ "homepage": "http://digitalkaoz.net"
+ }
+ ],
+ "description": "A library to validate a json schema.",
+ "homepage": "https://github.com/justinrainbow/json-schema",
+ "keywords": [
+ "json",
+ "schema"
+ ],
+ "time": "2012-01-03 00:33:17"
+ },
+ {
+ "name": "magento/framework",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_framework-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "ebb865d9aae1b48e41706a7d2fe080b7735a1a0c"
+ },
+ "require": {
+ "ext-curl": "*",
+ "ext-dom": "*",
+ "ext-gd": "*",
+ "ext-hash": "*",
+ "ext-iconv": "*",
+ "ext-mcrypt": "*",
+ "ext-simplexml": "*",
+ "ext-spl": "*",
+ "lib-libxml": "*",
+ "magento/magento-composer-installer": "*",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "ext-imagick": "Use Image Magick >=3.0.0 as an optional alternative image processing library"
+ },
+ "type": "magento2-library",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Framework"
+ ]
+ ]
+ },
+ "autoload": {
+ "psr-4": {
+ "Magento\\Framework\\": ""
+ }
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/language-de_de",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_language-de_de-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "574416a036e55513a6437b287b77426c291d9051"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*"
+ },
+ "type": "magento2-language",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "magento/de_de"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "German (Germany) language"
+ },
+ {
+ "name": "magento/language-en_us",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_language-en_us-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "6246a6a773d86c078bb4f0bc5cee50e2eeab639f"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*"
+ },
+ "type": "magento2-language",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "magento/en_us"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "English (United States) language"
+ },
+ {
+ "name": "magento/language-es_es",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_language-es_es-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "da8197a083474993b935bd16d8b001160475b97e"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*"
+ },
+ "type": "magento2-language",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "magento/es_es"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "Spanish (Spain) language"
+ },
+ {
+ "name": "magento/language-fr_fr",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_language-fr_fr-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "e3d58180b96a709e0b2fb8dccaee95b3be5dadd4"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*"
+ },
+ "type": "magento2-language",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "magento/fr_fr"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "French (France) language"
+ },
+ {
+ "name": "magento/language-nl_nl",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_language-nl_nl-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "d7b29b6275aefa26e7a6d9fb4bcdb62a8ee34332"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*"
+ },
+ "type": "magento2-language",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "magento/nl_nl"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "Dutch (Netherlands) language"
+ },
+ {
+ "name": "magento/language-pt_br",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_language-pt_br-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "7b6bc50f18adc85d524cc549accd05752beb8858"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*"
+ },
+ "type": "magento2-language",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "magento/pt_br"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "Portuguese (Brazil) language"
+ },
+ {
+ "name": "magento/language-zh_cn",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_language-zh_cn-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "f9a151b4d1bbc6620289e9e91fb8bee023d14c5f"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*"
+ },
+ "type": "magento2-language",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "magento/zh_cn"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "Chinese (China) language"
+ },
+ {
+ "name": "magento/magento-composer-installer",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/magento/magento-composer-installer.git",
+ "reference": "7f03451f71e55d52c2bb07325d56a4e6df322f30"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/magento/magento-composer-installer/zipball/7f03451f71e55d52c2bb07325d56a4e6df322f30",
+ "reference": "7f03451f71e55d52c2bb07325d56a4e6df322f30",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "1.0.0"
+ },
+ "require-dev": {
+ "composer/composer": "*@dev",
+ "firegento/phpcs": "dev-patch-1",
+ "mikey179/vfsstream": "*",
+ "phpunit/phpunit": "*",
+ "phpunit/phpunit-mock-objects": "dev-master",
+ "squizlabs/php_codesniffer": "1.4.7",
+ "symfony/process": "*"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "composer-command-registry": [
+ "MagentoHackathon\\Composer\\Magento\\Command\\DeployCommand"
+ ],
+ "class": "MagentoHackathon\\Composer\\Magento\\Plugin"
+ },
+ "autoload": {
+ "psr-0": {
+ "MagentoHackathon\\Composer\\Magento": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "OSL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "Vinai Kopp",
+ "email": "vinai@netzarbeiter.com"
+ },
+ {
+ "name": "Daniel Fahlke aka Flyingmana",
+ "email": "flyingmana@googlemail.com"
+ },
+ {
+ "name": "Jörg Weller",
+ "email": "weller@flagbit.de"
+ },
+ {
+ "name": "Karl Spies",
+ "email": "karl.spies@gmx.net"
+ },
+ {
+ "name": "Tobias Vogt",
+ "email": "tobi@webguys.de"
+ },
+ {
+ "name": "David Fuhr",
+ "email": "fuhr@flagbit.de"
+ }
+ ],
+ "description": "Composer installer for Magento modules",
+ "homepage": "https://github.com/magento/magento-composer-installer",
+ "keywords": [
+ "composer-installer",
+ "magento"
+ ],
+ "time": "2015-03-05 21:40:30"
+ },
+ {
+ "name": "magento/magento2-base",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_magento2-base-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "be10c634940670ff0cecf5f952f57891c626c652"
+ },
+ "require": {
+ "magento/magento-composer-installer": "*"
+ },
+ "replace": {
+ "blueimp/jquery-file-upload": "5.6.14",
+ "colinmollenhour/cache-backend-redis": "dev-master#193d377b7fb2e88595578b282fa01a62d1185abc",
+ "colinmollenhour/credis": "dev-master#f07bbfd4117294f462f0fb19c49221d350bf396f",
+ "components/jquery": "1.11.0",
+ "components/jqueryui": "1.10.4",
+ "linkorb/jsmin-php": "1.1.2",
+ "tinymce/tinymce": "3.4.7",
+ "trentrichardson/jquery-timepicker-addon": "1.4.3",
+ "twbs/bootstrap": "3.1.0"
+ },
+ "type": "magento2-component",
+ "extra": {
+ "component_paths": {
+ "trentrichardson/jquery-timepicker-addon": "lib/web/jquery/jquery-ui-timepicker-addon.js",
+ "colinmollenhour/cache-backend-redis": "lib/internal/Cm/Cache/Backend/Redis.php",
+ "colinmollenhour/credis": "lib/internal/Credis",
+ "linkorb/jsmin-php": "lib/internal/JSMin",
+ "components/jquery": [
+ "lib/web/jquery.js",
+ "lib/web/jquery/jquery.min.js",
+ "lib/web/jquery/jquery-migrate.js",
+ "lib/web/jquery/jquery-migrate.min.js"
+ ],
+ "blueimp/jquery-file-upload": "lib/web/jquery/fileUploader",
+ "components/jqueryui": [
+ "lib/web/jquery/jquery-ui.js",
+ "lib/web/jquery/jquery-ui.min.js"
+ ],
+ "twbs/bootstrap": [
+ "lib/web/jquery/jquery.tabs.js"
+ ],
+ "tinymce/tinymce": "lib/web/tiny_mce"
+ },
+ "map": [
+ [
+ "lib/internal/Cm",
+ "lib/internal/Cm"
+ ],
+ [
+ "lib/internal/LinLibertineFont",
+ "lib/internal/LinLibertineFont"
+ ],
+ [
+ "lib/internal/Credis",
+ "lib/internal/Credis"
+ ],
+ [
+ "lib/internal/CardinalCommerce",
+ "lib/internal/CardinalCommerce"
+ ],
+ [
+ "lib/internal/JSMin",
+ "lib/internal/JSMin"
+ ],
+ [
+ "lib/.htaccess",
+ "lib/.htaccess"
+ ],
+ [
+ "lib/web/lib",
+ "lib/web/lib"
+ ],
+ [
+ "lib/web/requirejs",
+ "lib/web/requirejs"
+ ],
+ [
+ "lib/web/prototype",
+ "lib/web/prototype"
+ ],
+ [
+ "lib/web/moment.js",
+ "lib/web/moment.js"
+ ],
+ [
+ "lib/web/i18n",
+ "lib/web/i18n"
+ ],
+ [
+ "lib/web/varien",
+ "lib/web/varien"
+ ],
+ [
+ "lib/web/blank.html",
+ "lib/web/blank.html"
+ ],
+ [
+ "lib/web/scriptaculous",
+ "lib/web/scriptaculous"
+ ],
+ [
+ "lib/web/ko",
+ "lib/web/ko"
+ ],
+ [
+ "lib/web/modernizr",
+ "lib/web/modernizr"
+ ],
+ [
+ "lib/web/date-format-normalizer.js",
+ "lib/web/date-format-normalizer.js"
+ ],
+ [
+ "lib/web/spacer.gif",
+ "lib/web/spacer.gif"
+ ],
+ [
+ "lib/web/images",
+ "lib/web/images"
+ ],
+ [
+ "lib/web/matchMedia.js",
+ "lib/web/matchMedia.js"
+ ],
+ [
+ "lib/web/extjs",
+ "lib/web/extjs"
+ ],
+ [
+ "lib/web/css",
+ "lib/web/css"
+ ],
+ [
+ "lib/web/fonts",
+ "lib/web/fonts"
+ ],
+ [
+ "lib/web/jquery",
+ "lib/web/jquery"
+ ],
+ [
+ "lib/web/less",
+ "lib/web/less"
+ ],
+ [
+ "lib/web/jquery.js",
+ "lib/web/jquery.js"
+ ],
+ [
+ "lib/web/underscore.js",
+ "lib/web/underscore.js"
+ ],
+ [
+ "lib/web/legacy-build.min.js",
+ "lib/web/legacy-build.min.js"
+ ],
+ [
+ "lib/web/mage",
+ "lib/web/mage"
+ ],
+ [
+ "lib/web/tiny_mce",
+ "lib/web/tiny_mce"
+ ],
+ [
+ ".htaccess.sample",
+ ".htaccess.sample"
+ ],
+ [
+ "CONTRIBUTING.md",
+ "CONTRIBUTING.md"
+ ],
+ [
+ "package.json",
+ "package.json"
+ ],
+ [
+ "nginx.conf.sample",
+ "nginx.conf.sample"
+ ],
+ [
+ "var/.htaccess",
+ "var/.htaccess"
+ ],
+ [
+ "pub/media/downloadable/.htaccess",
+ "pub/media/downloadable/.htaccess"
+ ],
+ [
+ "pub/media/theme_customization/.htaccess",
+ "pub/media/theme_customization/.htaccess"
+ ],
+ [
+ "pub/media/customer/.htaccess",
+ "pub/media/customer/.htaccess"
+ ],
+ [
+ "pub/media/.htaccess",
+ "pub/media/.htaccess"
+ ],
+ [
+ "pub/errors",
+ "pub/errors"
+ ],
+ [
+ "pub/opt",
+ "pub/opt"
+ ],
+ [
+ "pub/get.php",
+ "pub/get.php"
+ ],
+ [
+ "pub/static/.htaccess",
+ "pub/static/.htaccess"
+ ],
+ [
+ "pub/.htaccess",
+ "pub/.htaccess"
+ ],
+ [
+ "pub/static.php",
+ "pub/static.php"
+ ],
+ [
+ "pub/cron.php",
+ "pub/cron.php"
+ ],
+ [
+ "pub/index.php",
+ "pub/index.php"
+ ],
+ [
+ ".php_cs",
+ ".php_cs"
+ ],
+ [
+ "COPYING.txt",
+ "COPYING.txt"
+ ],
+ [
+ "dev/shell",
+ "dev/shell"
+ ],
+ [
+ "dev/tools",
+ "dev/tools"
+ ],
+ [
+ "dev/tests/integration/phpunit.xml.dist",
+ "dev/tests/integration/phpunit.xml.dist"
+ ],
+ [
+ "dev/tests/integration/etc",
+ "dev/tests/integration/etc"
+ ],
+ [
+ "dev/tests/integration/tmp",
+ "dev/tests/integration/tmp"
+ ],
+ [
+ "dev/tests/integration/framework",
+ "dev/tests/integration/framework"
+ ],
+ [
+ "dev/tests/integration/testsuite/Magento",
+ "dev/tests/integration/testsuite/Magento"
+ ],
+ [
+ "dev/tests/integration/.gitignore",
+ "dev/tests/integration/.gitignore"
+ ],
+ [
+ "dev/tests/functional/composer.json",
+ "dev/tests/functional/composer.json"
+ ],
+ [
+ "dev/tests/functional/lib",
+ "dev/tests/functional/lib"
+ ],
+ [
+ "dev/tests/functional/phpunit.xml.dist",
+ "dev/tests/functional/phpunit.xml.dist"
+ ],
+ [
+ "dev/tests/functional/composer.json.dist",
+ "dev/tests/functional/composer.json.dist"
+ ],
+ [
+ "dev/tests/functional/bootstrap.php",
+ "dev/tests/functional/bootstrap.php"
+ ],
+ [
+ "dev/tests/functional/credentials.xml.dist",
+ "dev/tests/functional/credentials.xml.dist"
+ ],
+ [
+ "dev/tests/functional/tests",
+ "dev/tests/functional/tests"
+ ],
+ [
+ "dev/tests/functional/utils",
+ "dev/tests/functional/utils"
+ ],
+ [
+ "dev/tests/functional/isolation.php",
+ "dev/tests/functional/isolation.php"
+ ],
+ [
+ "dev/tests/functional/etc",
+ "dev/tests/functional/etc"
+ ],
+ [
+ "dev/tests/functional/.htaccess",
+ "dev/tests/functional/.htaccess"
+ ],
+ [
+ "dev/tests/functional/testsuites/Magento",
+ "dev/tests/functional/testsuites/Magento"
+ ],
+ [
+ "dev/tests/functional/.gitignore",
+ "dev/tests/functional/.gitignore"
+ ],
+ [
+ "dev/tests/js/run_js_tests.php",
+ "dev/tests/js/run_js_tests.php"
+ ],
+ [
+ "dev/tests/js/jsTestDriverOrder.php",
+ "dev/tests/js/jsTestDriverOrder.php"
+ ],
+ [
+ "dev/tests/js/jsTestDriver.php.dist",
+ "dev/tests/js/jsTestDriver.php.dist"
+ ],
+ [
+ "dev/tests/js/spec",
+ "dev/tests/js/spec"
+ ],
+ [
+ "dev/tests/js/framework",
+ "dev/tests/js/framework"
+ ],
+ [
+ "dev/tests/js/testsuite/lib",
+ "dev/tests/js/testsuite/lib"
+ ],
+ [
+ "dev/tests/js/testsuite/mage",
+ "dev/tests/js/testsuite/mage"
+ ],
+ [
+ "dev/tests/js/.gitignore",
+ "dev/tests/js/.gitignore"
+ ],
+ [
+ "dev/tests/api-functional/phpunit.xml.dist",
+ "dev/tests/api-functional/phpunit.xml.dist"
+ ],
+ [
+ "dev/tests/api-functional/config",
+ "dev/tests/api-functional/config"
+ ],
+ [
+ "dev/tests/api-functional/framework",
+ "dev/tests/api-functional/framework"
+ ],
+ [
+ "dev/tests/api-functional/_files",
+ "dev/tests/api-functional/_files"
+ ],
+ [
+ "dev/tests/api-functional/testsuite/Magento",
+ "dev/tests/api-functional/testsuite/Magento"
+ ],
+ [
+ "dev/tests/api-functional/.gitignore",
+ "dev/tests/api-functional/.gitignore"
+ ],
+ [
+ "dev/tests/unit/phpunit.xml.dist",
+ "dev/tests/unit/phpunit.xml.dist"
+ ],
+ [
+ "dev/tests/unit/tmp",
+ "dev/tests/unit/tmp"
+ ],
+ [
+ "dev/tests/unit/framework",
+ "dev/tests/unit/framework"
+ ],
+ [
+ "dev/tests/unit/.gitignore",
+ "dev/tests/unit/.gitignore"
+ ],
+ [
+ "dev/tests/static/phpunit-all.xml.dist",
+ "dev/tests/static/phpunit-all.xml.dist"
+ ],
+ [
+ "dev/tests/static/phpunit.xml.dist",
+ "dev/tests/static/phpunit.xml.dist"
+ ],
+ [
+ "dev/tests/static/framework",
+ "dev/tests/static/framework"
+ ],
+ [
+ "dev/tests/static/testsuite/Magento",
+ "dev/tests/static/testsuite/Magento"
+ ],
+ [
+ "dev/tests/static/.gitignore",
+ "dev/tests/static/.gitignore"
+ ],
+ [
+ "dev/tests/performance/benchmark.jmx",
+ "dev/tests/performance/benchmark.jmx"
+ ],
+ [
+ "dev/tests/performance/compare_reports.php",
+ "dev/tests/performance/compare_reports.php"
+ ],
+ [
+ "dev/tests/performance/run_scenarios.php",
+ "dev/tests/performance/run_scenarios.php"
+ ],
+ [
+ "dev/tests/performance/framework",
+ "dev/tests/performance/framework"
+ ],
+ [
+ "dev/tests/performance/testsuite/backend.jmx",
+ "dev/tests/performance/testsuite/backend.jmx"
+ ],
+ [
+ "dev/tests/performance/testsuite/product_edit.jmx",
+ "dev/tests/performance/testsuite/product_edit.jmx"
+ ],
+ [
+ "dev/tests/performance/testsuite/add_to_cart.jmx",
+ "dev/tests/performance/testsuite/add_to_cart.jmx"
+ ],
+ [
+ "dev/tests/performance/testsuite/product_view.jmx",
+ "dev/tests/performance/testsuite/product_view.jmx"
+ ],
+ [
+ "dev/tests/performance/testsuite/home_page.jmx",
+ "dev/tests/performance/testsuite/home_page.jmx"
+ ],
+ [
+ "dev/tests/performance/testsuite/reusable",
+ "dev/tests/performance/testsuite/reusable"
+ ],
+ [
+ "dev/tests/performance/testsuite/quick_search.jmx",
+ "dev/tests/performance/testsuite/quick_search.jmx"
+ ],
+ [
+ "dev/tests/performance/testsuite/fixtures",
+ "dev/tests/performance/testsuite/fixtures"
+ ],
+ [
+ "dev/tests/performance/testsuite/advanced_search.jmx",
+ "dev/tests/performance/testsuite/advanced_search.jmx"
+ ],
+ [
+ "dev/tests/performance/testsuite/checkout.jmx",
+ "dev/tests/performance/testsuite/checkout.jmx"
+ ],
+ [
+ "dev/tests/performance/testsuite/category_view.jmx",
+ "dev/tests/performance/testsuite/category_view.jmx"
+ ],
+ [
+ "dev/tests/performance/testsuite/_samples",
+ "dev/tests/performance/testsuite/_samples"
+ ],
+ [
+ "dev/tests/performance/config.php.dist",
+ "dev/tests/performance/config.php.dist"
+ ],
+ [
+ "dev/tests/performance/.gitignore",
+ "dev/tests/performance/.gitignore"
+ ],
+ [
+ "dev/.htaccess",
+ "dev/.htaccess"
+ ],
+ [
+ "Gruntfile.js",
+ "Gruntfile.js"
+ ],
+ [
+ "setup",
+ "setup"
+ ],
+ [
+ "LICENSE.txt",
+ "LICENSE.txt"
+ ],
+ [
+ ".travis.yml",
+ ".travis.yml"
+ ],
+ [
+ "app/bootstrap.php",
+ "app/bootstrap.php"
+ ],
+ [
+ "app/etc/di.xml",
+ "app/etc/di.xml"
+ ],
+ [
+ "app/.htaccess",
+ "app/.htaccess"
+ ],
+ [
+ "app/functions.php",
+ "app/functions.php"
+ ],
+ [
+ "app/autoload.php",
+ "app/autoload.php"
+ ],
+ [
+ ".htaccess",
+ ".htaccess"
+ ],
+ [
+ "php.ini.sample",
+ "php.ini.sample"
+ ],
+ [
+ "CONTRIBUTOR_LICENSE_AGREEMENT.html",
+ "CONTRIBUTOR_LICENSE_AGREEMENT.html"
+ ],
+ [
+ "index.php",
+ "index.php"
+ ],
+ [
+ "LICENSE_AFL.txt",
+ "LICENSE_AFL.txt"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "Magento 2 Base"
+ },
+ {
+ "name": "magento/module-admin-notification",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-admin-notification-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "740186bdf97b2161994c10a883211eae76b285e9"
+ },
+ "require": {
+ "lib-libxml": "*",
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/AdminNotification"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-authorization",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-authorization-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "045f8440fe82b38ce228b0be52b011bb02773214"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Authorization"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "Authorization module provides access to Magento ACL functionality."
+ },
+ {
+ "name": "magento/module-backend",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-backend-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "39ddbf62a11d9be1b16539733c0f66f46a503033"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backup": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-cron": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-developer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-reports": "0.74.0-beta2",
+ "magento/module-require-js": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-translation": "0.74.0-beta2",
+ "magento/module-user": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Backend"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-backup",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-backup-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "7188d9a41bd9d4294dfd90c7053c301876d82c48"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-cron": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Backup"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-bundle",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-bundle-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "849f7fc43f7f9b6a37a922272656c6218c681693"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-catalog-rule": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-gift-message": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-webapi": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Bundle"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-captcha",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-captcha-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "a80050a22bad3399e146b242be33f6717fe15d26"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Captcha"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-catalog",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-catalog-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "d4259a0113a3b8eece9bdf88ad24b5cdee349de0"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-catalog-rule": "0.74.0-beta2",
+ "magento/module-catalog-url-rewrite": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-indexer": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-msrp": "0.74.0-beta2",
+ "magento/module-page-cache": "0.74.0-beta2",
+ "magento/module-product-alert": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-url-rewrite": "0.74.0-beta2",
+ "magento/module-widget": "0.74.0-beta2",
+ "magento/module-wishlist": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-cookie": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Catalog"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-catalog-import-export",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-catalog-import-export-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "3a26206abf71888d300c9d72b2190ff0f66eafd2"
+ },
+ "require": {
+ "ext-ctype": "*",
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-import-export": "0.74.0-beta2",
+ "magento/module-indexer": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CatalogImportExport"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-catalog-inventory",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-catalog-inventory-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "805c2bb2fb2c2f038dd73e4030a02e1208ea23da"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-indexer": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CatalogInventory"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-catalog-rule",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-catalog-rule-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "e9fe8b0f65dea1f8feba125e7d2974d48d1e0eef"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-import-export": "0.74.0-beta2",
+ "magento/module-indexer": "0.74.0-beta2",
+ "magento/module-rule": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CatalogRule"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-catalog-search",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-catalog-search-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "e8239e3dbbdccda266347d1ca5f286c1e9a2cb4b"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-indexer": "0.74.0-beta2",
+ "magento/module-search": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CatalogSearch"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-catalog-url-rewrite",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-catalog-url-rewrite-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "c3cc582396cc97970e2d0dd92e5315190cde0971"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-import-export": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-import-export": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-url-rewrite": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CatalogUrlRewrite"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-catalog-widget",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-catalog-widget-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "7dad3ad909bc97610211f4f008fa1817f1aac22a"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-rule": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-widget": "0.74.0-beta2",
+ "magento/module-wishlist": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CatalogWidget"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-centinel",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-centinel-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "069e94cd124c0d078eeb3174afdc1e49031a7288"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Centinel"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-checkout",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-checkout-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "8161dcc6c2bba44981cb63cd24cf137900d37db7"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-gift-message": "0.74.0-beta2",
+ "magento/module-msrp": "0.74.0-beta2",
+ "magento/module-page-cache": "0.74.0-beta2",
+ "magento/module-payment": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-ui": "0.74.0-beta2",
+ "magento/module-wishlist": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-cookie": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Checkout"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-checkout-agreements",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-checkout-agreements-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "be00ed9e3c1e3e4bacf7efc00b67c7cbb2065715"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CheckoutAgreements"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-cms",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-cms-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "15ae95a27b5ff0c82fbdb43ca8570e0cee4b21f5"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-email": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-ui": "0.74.0-beta2",
+ "magento/module-variable": "0.74.0-beta2",
+ "magento/module-widget": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Cms"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-cms-url-rewrite",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-cms-url-rewrite-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "6a3775d7705efcf5b43bfbe327d6ef1db2a1c09c"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-url-rewrite": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CmsUrlRewrite"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-config",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-config-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "a4be4800b197ab3a73bbfc0d23d5a1f753a07a57"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-cron": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-email": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Config"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-configurable-import-export",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-configurable-import-export-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "bb6d242228bcbe7c35253dc244c7977994b24b8e"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-import-export": "0.74.0-beta2",
+ "magento/module-configurable-product": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-import-export": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/ConfigurableImportExport"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-configurable-product",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-configurable-product-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "fe8e4536a59f60be79211fc0072e640102d3be06"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-catalog-rule": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-webapi": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/ConfigurableProduct"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-contact",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-contact-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "b53d65b91dd1f596d0a4f7b8bacf73e6eaff98c9"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Contact"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-cookie",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-cookie-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "a8a4e29967524214fb6af5c12681d7b410a63bc6"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.4.11|~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-backend": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Cookie"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-cron",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-cron-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "0e91ec4ade457797e7db0fe1aa4794747817fa6a"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Cron"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-currency-symbol",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-currency-symbol-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "261c0a4e05295f852a7986ef2d15509e4c2ad26c"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-page-cache": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CurrencySymbol"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-customer",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-customer-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "135623f9517f12f4dc17e062280eaf5f5071e7b7"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-authorization": "0.74.0-beta2",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-integration": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-newsletter": "0.74.0-beta2",
+ "magento/module-page-cache": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-review": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-ui": "0.74.0-beta2",
+ "magento/module-wishlist": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-cookie": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Customer"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-customer-import-export",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-customer-import-export-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "9b4f6b059fecce79c7f8ce9fc163858b8a47c7ca"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-import-export": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/CustomerImportExport"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-developer",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-developer-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "1a1077d963ec6310df7080defaadc9bd87ed6e21"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Developer"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-dhl",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-dhl-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "f525d0b48189b60e2c0def9a8804933133995104"
+ },
+ "require": {
+ "lib-libxml": "*",
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-shipping": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Dhl"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-directory",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-directory-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "3cb3ed72d237966f9deab3ac0386c3b6701cf66e"
+ },
+ "require": {
+ "lib-libxml": "*",
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Directory"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-downloadable",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-downloadable-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "5bd1cabf95a5c44e329f1263f40e165b3aa6070e"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-gift-message": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-msrp": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-wishlist": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Downloadable"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-eav",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-eav-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "5594f375105dc1921f38772fbb069ff57c2e8f01"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Eav"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-email",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-email-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "8ff7affa3d22107bd5e519dc24c098acccc44bf8"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-variable": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Email"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-fedex",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-fedex-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "cdc61b901b080b14e42b10889c8fb6f639f520af"
+ },
+ "require": {
+ "lib-libxml": "*",
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-shipping": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Fedex"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-gift-message",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-gift-message-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "76ea03167970205295c95d88f871f7ce0547cdbf"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-multishipping": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/GiftMessage"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-google-adwords",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-google-adwords-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "45dfa690b1f183b0a87e6db39e6399ff0024bc66"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/GoogleAdwords"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-google-analytics",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-google-analytics-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "7460860110d6942c3375db4a05cf079134e8ab6a"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-cookie": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/GoogleAnalytics"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-google-optimizer",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-google-optimizer-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "90565d6ecc18276ef08c324caae5178ca8ba82ed"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-google-analytics": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/GoogleOptimizer"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-google-shopping",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-google-shopping-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "f86c5696c215900805df27dcc6f8d6df5bd8453a"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/GoogleShopping"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-grouped-import-export",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-grouped-import-export-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "3cbf803098dd03d361b51f730930c9c3e6a9292c"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-import-export": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-grouped-product": "0.74.0-beta2",
+ "magento/module-import-export": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/GroupedImportExport"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-grouped-product",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-grouped-product-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "8ad968c974e321d99a9bccfd04721ccfb4bfb86f"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-msrp": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/GroupedProduct"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-import-export",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-import-export-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "c16b13bdf9efb2a9d52b6423ee641ca47d60da36"
+ },
+ "require": {
+ "ext-ctype": "*",
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-indexer": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/ImportExport"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-indexer",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-indexer-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "d1c6e17c92d766f8f3f578d290da957deb5d9a7c"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-page-cache": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Indexer"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-integration",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-integration-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "8e9a7d4df606513a67a649f63abdd31557061665"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-authorization": "0.74.0-beta2",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-user": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Integration"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-layered-navigation",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-layered-navigation-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "a20af59f1ffcf9565e2fab9ead134ee129bdcc8d"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/LayeredNavigation"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-media-storage",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-media-storage-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "7c1b9232bf83b123c2a3c6b03973bd637f34e0f6"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/MediaStorage"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-msrp",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-msrp-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "16bda583d7a876262fdc740c9513a4fb1739c3eb"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-bundle": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-downloadable": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-grouped-product": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Msrp"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-multishipping",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-multishipping-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "53b01c1acc039dec9e603681264a450f708d5fb6"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-payment": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Multishipping"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-newsletter",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-newsletter-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "a9e11c0ab106ea0aec8709a5a17169be826680c3"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-cron": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-email": "0.74.0-beta2",
+ "magento/module-require-js": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-widget": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Newsletter"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-offline-payments",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-offline-payments-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "d3b7cd008994bef7456496094f397c82a9f3a8ef"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-payment": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/OfflinePayments"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-offline-shipping",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-offline-shipping-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "94f097652ea87bc0504837366a51b7065ca864d4"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-sales-rule": "0.74.0-beta2",
+ "magento/module-shipping": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/OfflineShipping"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-page-cache",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-page-cache-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "9db7b9c8d035e0eb3f619d37c8ff439b9f225e8f"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/PageCache"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-payment",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-payment-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "9da0894c984887cf2e3c6c5a32f84616867495ae"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-centinel": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Payment"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-persistent",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-persistent-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "891f5f3f5c23dd19e2f815754f4c5e8b4da6af1c"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-cron": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-page-cache": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Persistent"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-product-alert",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-product-alert-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "43292b34d4078dddc73b7bb4bcdb889292b578a6"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/ProductAlert"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-quote",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-quote-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "8c3033317c359e5fc20e9308ed796ae6760fa22f"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-authorization": "0.74.0-beta2",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-catalog-rule": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-payment": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Quote"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-reports",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-reports-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "38b1c0ddfbd756666cb0bc05e687d01ced515464"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-downloadable": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-review": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-sales-rule": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "magento/module-widget": "0.74.0-beta2",
+ "magento/module-wishlist": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Reports"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-require-js",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-require-js-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "6e94b63070fd1c174ab55c109d384d5b3bb04131"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/RequireJs"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-review",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-review-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "45385eac2767e9165bfd88bcbc6a69dccca29f38"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-newsletter": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-ui": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-cookie": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Review"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-rss",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-rss-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "0706c2102a0003e2f214c35b77c1e628519b727a"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Rss"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-rule",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-rule-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "762edf4eabfe082b589b09bcf47a3ef2ac8a7f35"
+ },
+ "require": {
+ "lib-libxml": "*",
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Rule"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-sales",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-sales-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "bf591f1f3033aa2fd3fe8bfb2732a6e7b81a499c"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-authorization": "0.74.0-beta2",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-email": "0.74.0-beta2",
+ "magento/module-gift-message": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-payment": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-reports": "0.74.0-beta2",
+ "magento/module-sales-rule": "0.74.0-beta2",
+ "magento/module-shipping": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-ui": "0.74.0-beta2",
+ "magento/module-widget": "0.74.0-beta2",
+ "magento/module-wishlist": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Sales"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-sales-rule",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-sales-rule-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "fdb556db9915f50b0bbbc3fd5f004c21fdf144ac"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-rule": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-payment": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-reports": "0.74.0-beta2",
+ "magento/module-rule": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-shipping": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-widget": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/SalesRule"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-search",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-search-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "a9605f79153be5e6206e269161ec6b0fe27b4b1a"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog-search": "0.74.0-beta2",
+ "magento/module-reports": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Search"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-sendfriend",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-sendfriend-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "3830393608a4c34ef05eb26de6543ffe3739e1f4"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Sendfriend"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-shipping",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-shipping-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "0793baf12096494d141c3e6419f53a9c57aef0df"
+ },
+ "require": {
+ "ext-gd": "*",
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-contact": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-payment": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-fedex": "0.74.0-beta2",
+ "magento/module-ups": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Shipping"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-sitemap",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-sitemap-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "55e734ce8228a6e0b39eccb1829ae617845f9e53"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-url-rewrite": "0.74.0-beta2",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Sitemap"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-store",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-store-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "b53f0f39a5eceb85e0b28bcf32d5bb68314b3027"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-ui": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Store"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-tax",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-tax-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "ed22d2db556957de4ab5406d4d0edce811855b9b"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-reports": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-shipping": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Tax"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-tax-import-export",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-tax-import-export-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "90716decbf4c0eb8fb29523530471fc2f8fbb426"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/TaxImportExport"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-theme",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-theme-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "4754e71f25664ca7d010351e63c8c017e3c649dd"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-media-storage": "0.74.0-beta2",
+ "magento/module-require-js": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-widget": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-translation": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Theme"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-translation",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-translation-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "68e633ff0380bb3d9660c17149935a0cdeda4edb"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-developer": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Translation"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-ui",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-ui-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "6edb28f5c771ccb9e747ea71922ecbea80a32391"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Ui"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-ups",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-ups-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "70a8139468124067bfb07bf1c071638484136883"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-shipping": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Ups"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-url-rewrite",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-url-rewrite-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "8e781525600ff9d43383816283807ebcff07a8bf"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-url-rewrite": "0.74.0-beta2",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-cms-url-rewrite": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/UrlRewrite"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-user",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-user-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "023375251bc6104b31984e4509d01907f6661c6b"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-authorization": "0.74.0-beta2",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-integration": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/User"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-usps",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-usps-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "22eecac7075ca9c6ecaa08e482b59f5c29ba465c"
+ },
+ "require": {
+ "lib-libxml": "*",
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-config": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-shipping": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Usps"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-variable",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-variable-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "73cb1fdc0ff84722f854736a4016e3f5fa331ec1"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-email": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.4.11|~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Variable"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-version",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-version-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "de77cb875f16d6eec9c785df117eddf469bec459"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Version"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-webapi",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-webapi-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "c189f264c1bb186e052a2ed375b4b9e00295f3a6"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-authorization": "0.74.0-beta2",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-integration": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-user": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Webapi"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-weee",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-weee-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "cc524f7211673263beb1f4c6b96bf32ffa04527b"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-directory": "0.74.0-beta2",
+ "magento/module-eav": "0.74.0-beta2",
+ "magento/module-quote": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-tax": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Weee"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-widget",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-widget-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "f23668007563d5b7f9122e3eb453359fab9d1249"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-cms": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-variable": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Widget"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/module-wishlist",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_module-wishlist-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "fca56783501ad2b8f2c583350cb038f8191634e1"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/module-backend": "0.74.0-beta2",
+ "magento/module-catalog": "0.74.0-beta2",
+ "magento/module-catalog-inventory": "0.74.0-beta2",
+ "magento/module-checkout": "0.74.0-beta2",
+ "magento/module-customer": "0.74.0-beta2",
+ "magento/module-grouped-product": "0.74.0-beta2",
+ "magento/module-rss": "0.74.0-beta2",
+ "magento/module-sales": "0.74.0-beta2",
+ "magento/module-store": "0.74.0-beta2",
+ "magento/module-theme": "0.74.0-beta2",
+ "magento/module-ui": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "suggest": {
+ "magento/module-bundle": "0.74.0-beta2",
+ "magento/module-configurable-product": "0.74.0-beta2",
+ "magento/module-cookie": "0.74.0-beta2",
+ "magento/module-downloadable": "0.74.0-beta2"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/Wishlist"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/product-community-edition",
+ "version": "0.74.0-beta2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/magento/magento2-community-edition.git",
+ "reference": "830bba759a180a97375275013b974c4606805466"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/magento/magento2-community-edition/zipball/830bba759a180a97375275013b974c4606805466",
+ "reference": "830bba759a180a97375275013b974c4606805466",
+ "shasum": ""
+ },
+ "require": {
+ "composer/composer": "1.0.0-alpha8",
+ "magento/framework": "self.version",
+ "magento/language-de_de": "self.version",
+ "magento/language-en_us": "self.version",
+ "magento/language-es_es": "self.version",
+ "magento/language-fr_fr": "self.version",
+ "magento/language-nl_nl": "self.version",
+ "magento/language-pt_br": "self.version",
+ "magento/language-zh_cn": "self.version",
+ "magento/magento-composer-installer": "*",
+ "magento/magento2-base": "self.version",
+ "magento/module-admin-notification": "self.version",
+ "magento/module-authorization": "self.version",
+ "magento/module-backend": "self.version",
+ "magento/module-backup": "self.version",
+ "magento/module-bundle": "self.version",
+ "magento/module-captcha": "self.version",
+ "magento/module-catalog": "self.version",
+ "magento/module-catalog-import-export": "self.version",
+ "magento/module-catalog-inventory": "self.version",
+ "magento/module-catalog-rule": "self.version",
+ "magento/module-catalog-search": "self.version",
+ "magento/module-catalog-url-rewrite": "self.version",
+ "magento/module-catalog-widget": "self.version",
+ "magento/module-centinel": "self.version",
+ "magento/module-checkout": "self.version",
+ "magento/module-checkout-agreements": "self.version",
+ "magento/module-cms": "self.version",
+ "magento/module-cms-url-rewrite": "self.version",
+ "magento/module-config": "self.version",
+ "magento/module-configurable-import-export": "self.version",
+ "magento/module-configurable-product": "self.version",
+ "magento/module-contact": "self.version",
+ "magento/module-cookie": "self.version",
+ "magento/module-cron": "self.version",
+ "magento/module-currency-symbol": "self.version",
+ "magento/module-customer": "self.version",
+ "magento/module-customer-import-export": "self.version",
+ "magento/module-developer": "self.version",
+ "magento/module-dhl": "self.version",
+ "magento/module-directory": "self.version",
+ "magento/module-downloadable": "self.version",
+ "magento/module-eav": "self.version",
+ "magento/module-email": "self.version",
+ "magento/module-fedex": "self.version",
+ "magento/module-gift-message": "self.version",
+ "magento/module-google-adwords": "self.version",
+ "magento/module-google-analytics": "self.version",
+ "magento/module-google-optimizer": "self.version",
+ "magento/module-google-shopping": "self.version",
+ "magento/module-grouped-import-export": "self.version",
+ "magento/module-grouped-product": "self.version",
+ "magento/module-import-export": "self.version",
+ "magento/module-indexer": "self.version",
+ "magento/module-integration": "self.version",
+ "magento/module-layered-navigation": "self.version",
+ "magento/module-media-storage": "self.version",
+ "magento/module-msrp": "self.version",
+ "magento/module-multishipping": "self.version",
+ "magento/module-newsletter": "self.version",
+ "magento/module-offline-payments": "self.version",
+ "magento/module-offline-shipping": "self.version",
+ "magento/module-page-cache": "self.version",
+ "magento/module-payment": "self.version",
+ "magento/module-persistent": "self.version",
+ "magento/module-product-alert": "self.version",
+ "magento/module-quote": "self.version",
+ "magento/module-reports": "self.version",
+ "magento/module-require-js": "self.version",
+ "magento/module-review": "self.version",
+ "magento/module-rss": "self.version",
+ "magento/module-rule": "self.version",
+ "magento/module-sales": "self.version",
+ "magento/module-sales-rule": "self.version",
+ "magento/module-search": "self.version",
+ "magento/module-sendfriend": "self.version",
+ "magento/module-shipping": "self.version",
+ "magento/module-sitemap": "self.version",
+ "magento/module-store": "self.version",
+ "magento/module-tax": "self.version",
+ "magento/module-tax-import-export": "self.version",
+ "magento/module-theme": "self.version",
+ "magento/module-translation": "self.version",
+ "magento/module-ui": "self.version",
+ "magento/module-ups": "self.version",
+ "magento/module-url-rewrite": "self.version",
+ "magento/module-user": "self.version",
+ "magento/module-usps": "self.version",
+ "magento/module-variable": "self.version",
+ "magento/module-version": "self.version",
+ "magento/module-webapi": "self.version",
+ "magento/module-weee": "self.version",
+ "magento/module-widget": "self.version",
+ "magento/module-wishlist": "self.version",
+ "magento/theme-adminhtml-backend": "self.version",
+ "magento/theme-frontend-blank": "self.version",
+ "magento/theme-frontend-luma": "self.version",
+ "magento/zendframework1": "1.12.10",
+ "monolog/monolog": "1.11.0",
+ "oyejorge/less.php": "1.7.0.3",
+ "php": "~5.5.0|~5.6.0|~7.0.0",
+ "tubalmartin/cssmin": "2.4.8-p4",
+ "zendframework/zend-code": "2.3.1",
+ "zendframework/zend-config": "2.3.1",
+ "zendframework/zend-console": "2.3.1",
+ "zendframework/zend-di": "2.3.1",
+ "zendframework/zend-eventmanager": "2.3.1",
+ "zendframework/zend-form": "2.3.1",
+ "zendframework/zend-http": "2.3.1",
+ "zendframework/zend-json": "2.3.1",
+ "zendframework/zend-log": "2.3.1",
+ "zendframework/zend-modulemanager": "2.3.1",
+ "zendframework/zend-mvc": "2.3.1",
+ "zendframework/zend-serializer": "2.3.1",
+ "zendframework/zend-server": "2.3.1",
+ "zendframework/zend-servicemanager": "2.3.1",
+ "zendframework/zend-soap": "2.3.1",
+ "zendframework/zend-stdlib": "2.3.1",
+ "zendframework/zend-text": "2.3.1",
+ "zendframework/zend-uri": "2.3.1",
+ "zendframework/zend-validator": "2.3.1",
+ "zendframework/zend-view": "2.3.1"
+ },
+ "require-dev": {
+ "ext-ctype": "*",
+ "ext-curl": "*",
+ "ext-dom": "*",
+ "ext-gd": "*",
+ "ext-hash": "*",
+ "ext-iconv": "*",
+ "ext-intl": "*",
+ "ext-mcrypt": "*",
+ "ext-simplexml": "*",
+ "ext-spl": "*",
+ "fabpot/php-cs-fixer": "~1.2",
+ "lib-libxml": "*",
+ "lusitanian/oauth": "~0.3",
+ "pdepend/pdepend": "2.0.6",
+ "phpmd/phpmd": "@stable",
+ "phpunit/phpunit": "4.1.0",
+ "sjparkinson/static-review": "~4.1",
+ "squizlabs/php_codesniffer": "1.5.3"
+ },
+ "type": "project",
+ "autoload": {
+ "psr-4": {
+ "Magento\\Framework\\": "lib/internal/Magento/Framework/",
+ "Magento\\Setup\\": "setup/src/Magento/Setup/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "eCommerce Platform for Growth (Community Edition)",
+ "time": "2015-03-27 15:47:02"
+ },
+ {
+ "name": "magento/sample-module-minimal",
+ "version": "1.0.0",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_sample-module-minimal-1.0.0.zip",
+ "reference": null,
+ "shasum": "8c8bd3ee4907a6a91bffeac177628bd4f238d6e4"
+ },
+ "require": {
+ "magento/magento-composer-installer": "*",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-module",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/SampleMinimal"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "A minimal skeleton Magento 2 module"
+ },
+ {
+ "name": "magento/theme-adminhtml-backend",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_theme-adminhtml-backend-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "d8bd8d6b70d65d6f38751f7e9f9cbbebf751c97c"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-theme",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "adminhtml/Magento/backend"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/theme-frontend-blank",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_theme-frontend-blank-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "e298ae05894e97ba3d94a87b77086dfe0c2d974a"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-theme",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "frontend/Magento/blank"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/theme-frontend-luma",
+ "version": "0.74.0-beta2",
+ "dist": {
+ "type": "zip",
+ "url": "https://packages.magento.com/_packages/magento_theme-frontend-luma-0.74.0-beta2.zip",
+ "reference": null,
+ "shasum": "82e29e8fd8d928c33f064fb431d06f3968f37327"
+ },
+ "require": {
+ "magento/framework": "0.74.0-beta2",
+ "magento/magento-composer-installer": "*",
+ "magento/theme-frontend-blank": "0.74.0-beta2",
+ "php": "~5.5.0|~5.6.0"
+ },
+ "type": "magento2-theme",
+ "extra": {
+ "map": [
+ [
+ "*",
+ "frontend/Magento/luma"
+ ]
+ ]
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "description": "N/A"
+ },
+ {
+ "name": "magento/zendframework1",
+ "version": "1.12.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/magento/zf1.git",
+ "reference": "d1e5cd8c9f83229bcdd9bb485c3ce25259c77884"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/magento/zf1/zipball/d1e5cd8c9f83229bcdd9bb485c3ce25259c77884",
+ "reference": "d1e5cd8c9f83229bcdd9bb485c3ce25259c77884",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.11"
+ },
+ "require-dev": {
+ "phpunit/dbunit": "1.3.*",
+ "phpunit/phpunit": "3.7.*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.12.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Zend_": "library/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ "library/"
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "Magento Zend Framework 1",
+ "homepage": "http://framework.zend.com/",
+ "keywords": [
+ "ZF1",
+ "framework"
+ ],
+ "time": "2015-02-06 17:25:45"
+ },
+ {
+ "name": "monolog/monolog",
+ "version": "1.11.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/monolog.git",
+ "reference": "ec3961874c43840e96da3a8a1ed20d8c73d7e5aa"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/ec3961874c43840e96da3a8a1ed20d8c73d7e5aa",
+ "reference": "ec3961874c43840e96da3a8a1ed20d8c73d7e5aa",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "psr/log": "~1.0"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0.0"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "~2.4, >2.4.8",
+ "doctrine/couchdb": "~1.0@dev",
+ "graylog2/gelf-php": "~1.0",
+ "phpunit/phpunit": "~3.7.0",
+ "raven/raven": "~0.5",
+ "ruflin/elastica": "0.90.*",
+ "videlalvaro/php-amqplib": "~2.4"
+ },
+ "suggest": {
+ "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+ "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+ "ext-mongo": "Allow sending log messages to a MongoDB server",
+ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+ "raven/raven": "Allow sending log messages to a Sentry server",
+ "rollbar/rollbar": "Allow sending log messages to Rollbar",
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
+ "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.11.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Monolog\\": "src/Monolog"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+ "homepage": "http://github.com/Seldaek/monolog",
+ "keywords": [
+ "log",
+ "logging",
+ "psr-3"
+ ],
+ "time": "2014-09-30 13:30:58"
+ },
+ {
+ "name": "oyejorge/less.php",
+ "version": "v1.7.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/oyejorge/less.php.git",
+ "reference": "6e08ecb07e6f6d9170c23e8744c58fdd822ad0de"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/oyejorge/less.php/zipball/6e08ecb07e6f6d9170c23e8744c58fdd822ad0de",
+ "reference": "6e08ecb07e6f6d9170c23e8744c58fdd822ad0de",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2"
+ },
+ "bin": [
+ "bin/lessc"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Less": "lib/"
+ },
+ "classmap": [
+ "lessc.inc.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Matt Agar",
+ "homepage": "https://github.com/agar"
+ },
+ {
+ "name": "Martin Jantošovič",
+ "homepage": "https://github.com/Mordred"
+ },
+ {
+ "name": "Josh Schmidt",
+ "homepage": "https://github.com/oyejorge"
+ }
+ ],
+ "description": "PHP port of the Javascript version of LESS http://lesscss.org",
+ "homepage": "http://lessphp.gpeasy.com",
+ "keywords": [
+ "css",
+ "less",
+ "less.js",
+ "lesscss",
+ "php",
+ "stylesheet"
+ ],
+ "time": "2015-03-10 18:12:59"
+ },
+ {
+ "name": "psr/log",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "bf2c13de4300e227d7b2fd08027673a79c519987"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/bf2c13de4300e227d7b2fd08027673a79c519987",
+ "reference": "bf2c13de4300e227d7b2fd08027673a79c519987",
+ "shasum": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2015-03-26 14:39:45"
+ },
+ {
+ "name": "seld/jsonlint",
+ "version": "1.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/jsonlint.git",
+ "reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/863ae85c6d3ef60ca49cb12bd051c4a0648c40c4",
+ "reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "bin": [
+ "bin/jsonlint"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Seld\\JsonLint\\": "src/Seld/JsonLint/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "JSON Linter",
+ "keywords": [
+ "json",
+ "linter",
+ "parser",
+ "validator"
+ ],
+ "time": "2015-01-04 21:18:15"
+ },
+ {
+ "name": "symfony/console",
+ "version": "2.8.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Console.git",
+ "reference": "7e857a2b52b5833ed27d78a6b1b846bd440ee8bd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Console/zipball/7e857a2b52b5833ed27d78a6b1b846bd440ee8bd",
+ "reference": "7e857a2b52b5833ed27d78a6b1b846bd440ee8bd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
+ "symfony/phpunit-bridge": "~2.7|~3.0.0",
+ "symfony/process": "~2.1|~3.0.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Console Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "2.8.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Finder.git",
+ "reference": "fd26bdbb67bc8753884eff5767a4f1ee90e2284b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Finder/zipball/fd26bdbb67bc8753884eff5767a4f1ee90e2284b",
+ "reference": "fd26bdbb67bc8753884eff5767a4f1ee90e2284b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7|~3.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Finder\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Finder Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
+ },
+ {
+ "name": "symfony/process",
+ "version": "2.8.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Process.git",
+ "reference": "daf96f1491cf0b8d8de60e6d3b5fda8e502b3798"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Process/zipball/daf96f1491cf0b8d8de60e6d3b5fda8e502b3798",
+ "reference": "daf96f1491cf0b8d8de60e6d3b5fda8e502b3798",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7|~3.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Process Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
+ },
+ {
+ "name": "tubalmartin/cssmin",
+ "version": "v2.4.8-p4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port.git",
+ "reference": "fe84d71e8420243544c0ce3bd0f5d7c1936b0f90"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/tubalmartin/YUI-CSS-compressor-PHP-port/zipball/fe84d71e8420243544c0ce3bd0f5d7c1936b0f90",
+ "reference": "fe84d71e8420243544c0ce3bd0f5d7c1936b0f90",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.0.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "cssmin.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Túbal Martín",
+ "homepage": "http://tubalmartin.me/"
+ }
+ ],
+ "description": "A PHP port of the YUI CSS compressor",
+ "homepage": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port",
+ "keywords": [
+ "compress",
+ "compressor",
+ "css",
+ "minify",
+ "yui"
+ ],
+ "time": "2014-09-22 08:08:50"
+ },
+ {
+ "name": "zendframework/zend-code",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-code.git",
+ "reference": "a64e90c9ee8c939335ee7e21e39e3342c0e54526"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-code/zipball/a64e90c9ee8c939335ee7e21e39e3342c0e54526",
+ "reference": "a64e90c9ee8c939335ee7e21e39e3342c0e54526",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-eventmanager": "self.version"
+ },
+ "require-dev": {
+ "doctrine/common": ">=2.1",
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "suggest": {
+ "doctrine/common": "Doctrine\\Common >=2.1 for annotation features",
+ "zendframework/zend-stdlib": "Zend\\Stdlib component"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Code\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "provides facilities to generate arbitrary code using an object oriented interface",
+ "homepage": "https://github.com/zendframework/zend-code",
+ "keywords": [
+ "code",
+ "zf2"
+ ],
+ "time": "2014-04-15 14:47:18"
+ },
+ {
+ "name": "zendframework/zend-config",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-config.git",
+ "reference": "698c139707380b29fd09791ec1c21b837e9a3f15"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-config/zipball/698c139707380b29fd09791ec1c21b837e9a3f15",
+ "reference": "698c139707380b29fd09791ec1c21b837e9a3f15",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-filter": "self.version",
+ "zendframework/zend-i18n": "self.version",
+ "zendframework/zend-json": "self.version",
+ "zendframework/zend-servicemanager": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-filter": "Zend\\Filter component",
+ "zendframework/zend-i18n": "Zend\\I18n component",
+ "zendframework/zend-json": "Zend\\Json to use the Json reader or writer classes",
+ "zendframework/zend-servicemanager": "Zend\\ServiceManager for use with the Config Factory to retrieve reader and writer instances"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Config\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "provides a nested object property based user interface for accessing this configuration data within application code",
+ "homepage": "https://github.com/zendframework/zend-config",
+ "keywords": [
+ "config",
+ "zf2"
+ ],
+ "time": "2014-04-15 13:59:53"
+ },
+ {
+ "name": "zendframework/zend-console",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-console.git",
+ "reference": "4253efd75a022d97ef326eac38a06c8eebb48a37"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-console/zipball/4253efd75a022d97ef326eac38a06c8eebb48a37",
+ "reference": "4253efd75a022d97ef326eac38a06c8eebb48a37",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "suggest": {
+ "zendframework/zend-filter": "To support DefaultRouteMatcher usage",
+ "zendframework/zend-validator": "To support DefaultRouteMatcher usage"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Console\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-console",
+ "keywords": [
+ "console",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-di",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-di.git",
+ "reference": "7502db10f8023bfd4e860ce83c9cdeda0db42c31"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-di/zipball/7502db10f8023bfd4e860ce83c9cdeda0db42c31",
+ "reference": "7502db10f8023bfd4e860ce83c9cdeda0db42c31",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-code": "self.version",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-servicemanager": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-servicemanager": "Zend\\ServiceManager component"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Di\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-di",
+ "keywords": [
+ "di",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-escaper",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-escaper.git",
+ "reference": "2b2fcb6141cc2a2c6cc0c596e82771c72ef4ddc1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/2b2fcb6141cc2a2c6cc0c596e82771c72ef4ddc1",
+ "reference": "2b2fcb6141cc2a2c6cc0c596e82771c72ef4ddc1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Escaper\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-escaper",
+ "keywords": [
+ "escaper",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-eventmanager",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-eventmanager.git",
+ "reference": "ec158e89d0290f988a29ccd6bf179b561efbb702"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/ec158e89d0290f988a29ccd6bf179b561efbb702",
+ "reference": "ec158e89d0290f988a29ccd6bf179b561efbb702",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\EventManager\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-event-manager",
+ "keywords": [
+ "eventmanager",
+ "zf2"
+ ],
+ "time": "2014-04-15 13:59:53"
+ },
+ {
+ "name": "zendframework/zend-filter",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-filter.git",
+ "reference": "307fe694659e08ffd710c70e4db8bc60187bcc84"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/307fe694659e08ffd710c70e4db8bc60187bcc84",
+ "reference": "307fe694659e08ffd710c70e4db8bc60187bcc84",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-crypt": "self.version",
+ "zendframework/zend-servicemanager": "self.version",
+ "zendframework/zend-uri": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-crypt": "Zend\\Crypt component",
+ "zendframework/zend-i18n": "Zend\\I18n component",
+ "zendframework/zend-servicemanager": "Zend\\ServiceManager component",
+ "zendframework/zend-uri": "Zend\\Uri component for UriNormalize filter"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Filter\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "provides a set of commonly needed data filters",
+ "homepage": "https://github.com/zendframework/zend-filter",
+ "keywords": [
+ "filter",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-form",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-form.git",
+ "reference": "d7a1f5bc4626b1df990391502a868b28c37ba65d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-form/zipball/d7a1f5bc4626b1df990391502a868b28c37ba65d",
+ "reference": "d7a1f5bc4626b1df990391502a868b28c37ba65d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-inputfilter": "self.version",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-captcha": "self.version",
+ "zendframework/zend-code": "self.version",
+ "zendframework/zend-eventmanager": "self.version",
+ "zendframework/zend-filter": "self.version",
+ "zendframework/zend-i18n": "self.version",
+ "zendframework/zend-servicemanager": "self.version",
+ "zendframework/zend-validator": "self.version",
+ "zendframework/zend-view": "self.version",
+ "zendframework/zendservice-recaptcha": "*"
+ },
+ "suggest": {
+ "zendframework/zend-captcha": "Zend\\Captcha component",
+ "zendframework/zend-code": "Zend\\Code component",
+ "zendframework/zend-eventmanager": "Zend\\EventManager component",
+ "zendframework/zend-filter": "Zend\\Filter component",
+ "zendframework/zend-i18n": "Zend\\I18n component",
+ "zendframework/zend-servicemanager": "Zend\\ServiceManager component",
+ "zendframework/zend-validator": "Zend\\Validator component",
+ "zendframework/zend-view": "Zend\\View component",
+ "zendframework/zendservice-recaptcha": "ZendService\\ReCaptcha component"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Form\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-form",
+ "keywords": [
+ "form",
+ "zf2"
+ ],
+ "time": "2014-04-15 14:36:41"
+ },
+ {
+ "name": "zendframework/zend-http",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-http.git",
+ "reference": "869ce7bdf60727e14d85c305d2948fbe831c3534"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-http/zipball/869ce7bdf60727e14d85c305d2948fbe831c3534",
+ "reference": "869ce7bdf60727e14d85c305d2948fbe831c3534",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-loader": "self.version",
+ "zendframework/zend-stdlib": "self.version",
+ "zendframework/zend-uri": "self.version",
+ "zendframework/zend-validator": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Http\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests",
+ "homepage": "https://github.com/zendframework/zend-http",
+ "keywords": [
+ "http",
+ "zf2"
+ ],
+ "time": "2014-04-15 13:59:53"
+ },
+ {
+ "name": "zendframework/zend-inputfilter",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-inputfilter.git",
+ "reference": "abca740015a856d03542f5b6c535b8874f84b622"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-inputfilter/zipball/abca740015a856d03542f5b6c535b8874f84b622",
+ "reference": "abca740015a856d03542f5b6c535b8874f84b622",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-filter": "self.version",
+ "zendframework/zend-stdlib": "self.version",
+ "zendframework/zend-validator": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-servicemanager": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-servicemanager": "To support plugin manager support"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\InputFilter\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-input-filter",
+ "keywords": [
+ "inputfilter",
+ "zf2"
+ ],
+ "time": "2014-04-15 13:59:53"
+ },
+ {
+ "name": "zendframework/zend-json",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-json.git",
+ "reference": "5284687fc3aeab27961d2e17ada08973ae6daafe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-json/zipball/5284687fc3aeab27961d2e17ada08973ae6daafe",
+ "reference": "5284687fc3aeab27961d2e17ada08973ae6daafe",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-http": "self.version",
+ "zendframework/zend-server": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-http": "Zend\\Http component",
+ "zendframework/zend-server": "Zend\\Server component",
+ "zendframework/zendxml": "To support Zend\\Json\\Json::fromXml() usage"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Json\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP",
+ "homepage": "https://github.com/zendframework/zend-json",
+ "keywords": [
+ "json",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-loader",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-loader.git",
+ "reference": "5e0bd7e28c644078685f525cf8ae03d9a01ae292"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/5e0bd7e28c644078685f525cf8ae03d9a01ae292",
+ "reference": "5e0bd7e28c644078685f525cf8ae03d9a01ae292",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Loader\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-loader",
+ "keywords": [
+ "loader",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-log",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-log.git",
+ "reference": "217611433f5cb56d4420a1db8f164e5db85d815d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-log/zipball/217611433f5cb56d4420a1db8f164e5db85d815d",
+ "reference": "217611433f5cb56d4420a1db8f164e5db85d815d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-servicemanager": "self.version",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-console": "self.version",
+ "zendframework/zend-db": "self.version",
+ "zendframework/zend-escaper": "self.version",
+ "zendframework/zend-mail": "self.version",
+ "zendframework/zend-validator": "self.version"
+ },
+ "suggest": {
+ "ext-mongo": "*",
+ "zendframework/zend-console": "Zend\\Console component",
+ "zendframework/zend-db": "Zend\\Db component",
+ "zendframework/zend-escaper": "Zend\\Escaper component, for use in the XML formatter",
+ "zendframework/zend-mail": "Zend\\Mail component",
+ "zendframework/zend-validator": "Zend\\Validator component"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Log\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "component for general purpose logging",
+ "homepage": "https://github.com/zendframework/zend-log",
+ "keywords": [
+ "log",
+ "logging",
+ "zf2"
+ ],
+ "time": "2014-04-15 13:59:53"
+ },
+ {
+ "name": "zendframework/zend-math",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-math.git",
+ "reference": "63225fcebb196fc6e20094f5f01e9354779ec31e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-math/zipball/63225fcebb196fc6e20094f5f01e9354779ec31e",
+ "reference": "63225fcebb196fc6e20094f5f01e9354779ec31e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "suggest": {
+ "ext-bcmath": "If using the bcmath functionality",
+ "ext-gmp": "If using the gmp functionality",
+ "ircmaxell/random-lib": "Fallback random byte generator for Zend\\Math\\Rand if OpenSSL/Mcrypt extensions are unavailable",
+ "zendframework/zend-servicemanager": ">= current version, if using the BigInteger::factory functionality"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Math\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-math",
+ "keywords": [
+ "math",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-modulemanager",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-modulemanager.git",
+ "reference": "d4591b958e40b8f5ae8110d9b203331437aa19f2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-modulemanager/zipball/d4591b958e40b8f5ae8110d9b203331437aa19f2",
+ "reference": "d4591b958e40b8f5ae8110d9b203331437aa19f2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-eventmanager": "self.version",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-config": "self.version",
+ "zendframework/zend-console": "self.version",
+ "zendframework/zend-loader": "self.version",
+ "zendframework/zend-mvc": "self.version",
+ "zendframework/zend-servicemanager": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-config": "Zend\\Config component",
+ "zendframework/zend-console": "Zend\\Console component",
+ "zendframework/zend-loader": "Zend\\Loader component",
+ "zendframework/zend-mvc": "Zend\\Mvc component",
+ "zendframework/zend-servicemanager": "Zend\\ServiceManager component"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\ModuleManager\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-module-manager",
+ "keywords": [
+ "modulemanager",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-mvc",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-mvc.git",
+ "reference": "ee76ddd009ecb0c507bb8ab396fbe719aea8f1ff"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-mvc/zipball/ee76ddd009ecb0c507bb8ab396fbe719aea8f1ff",
+ "reference": "ee76ddd009ecb0c507bb8ab396fbe719aea8f1ff",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-eventmanager": "self.version",
+ "zendframework/zend-form": "self.version",
+ "zendframework/zend-servicemanager": "self.version",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-authentication": "self.version",
+ "zendframework/zend-console": "self.version",
+ "zendframework/zend-di": "self.version",
+ "zendframework/zend-filter": "self.version",
+ "zendframework/zend-form": "self.version",
+ "zendframework/zend-http": "self.version",
+ "zendframework/zend-i18n": "self.version",
+ "zendframework/zend-inputfilter": "self.version",
+ "zendframework/zend-json": "self.version",
+ "zendframework/zend-log": "self.version",
+ "zendframework/zend-modulemanager": "self.version",
+ "zendframework/zend-serializer": "self.version",
+ "zendframework/zend-session": "self.version",
+ "zendframework/zend-text": "self.version",
+ "zendframework/zend-uri": "self.version",
+ "zendframework/zend-validator": "self.version",
+ "zendframework/zend-version": "self.version",
+ "zendframework/zend-view": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-authentication": "Zend\\Authentication component for Identity plugin",
+ "zendframework/zend-config": "Zend\\Config component",
+ "zendframework/zend-console": "Zend\\Console component",
+ "zendframework/zend-di": "Zend\\Di component",
+ "zendframework/zend-filter": "Zend\\Filter component",
+ "zendframework/zend-form": "Zend\\Form component",
+ "zendframework/zend-http": "Zend\\Http component",
+ "zendframework/zend-i18n": "Zend\\I18n component for translatable segments",
+ "zendframework/zend-inputfilter": "Zend\\Inputfilter component",
+ "zendframework/zend-json": "Zend\\Json component",
+ "zendframework/zend-log": "Zend\\Log component",
+ "zendframework/zend-modulemanager": "Zend\\ModuleManager component",
+ "zendframework/zend-serializer": "Zend\\Serializer component",
+ "zendframework/zend-session": "Zend\\Session component for FlashMessenger, PRG, and FPRG plugins",
+ "zendframework/zend-stdlib": "Zend\\Stdlib component",
+ "zendframework/zend-text": "Zend\\Text component",
+ "zendframework/zend-uri": "Zend\\Uri component",
+ "zendframework/zend-validator": "Zend\\Validator component",
+ "zendframework/zend-version": "Zend\\Version component",
+ "zendframework/zend-view": "Zend\\View component"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Mvc\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-mvc",
+ "keywords": [
+ "mvc",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-serializer",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-serializer.git",
+ "reference": "22f73b0d0ff1158216bd5bcacf6bd00f7be1a0f6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-serializer/zipball/22f73b0d0ff1158216bd5bcacf6bd00f7be1a0f6",
+ "reference": "22f73b0d0ff1158216bd5bcacf6bd00f7be1a0f6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-json": "self.version",
+ "zendframework/zend-math": "self.version",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-servicemanager": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-servicemanager": "To support plugin manager support"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Serializer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "provides an adapter based interface to simply generate storable representation of PHP types by different facilities, and recover",
+ "homepage": "https://github.com/zendframework/zend-serializer",
+ "keywords": [
+ "serializer",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-server",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-server.git",
+ "reference": "bc5fb97f4ac48a5dc54bd18dded21a3e1eea552c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-server/zipball/bc5fb97f4ac48a5dc54bd18dded21a3e1eea552c",
+ "reference": "bc5fb97f4ac48a5dc54bd18dded21a3e1eea552c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-code": "self.version",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Server\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-server",
+ "keywords": [
+ "server",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-servicemanager",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-servicemanager.git",
+ "reference": "7a428b595a1fcd4c2a8026ee5d5f89a56036f682"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/7a428b595a1fcd4c2a8026ee5d5f89a56036f682",
+ "reference": "7a428b595a1fcd4c2a8026ee5d5f89a56036f682",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-di": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-di": "Zend\\Di component"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\ServiceManager\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-service-manager",
+ "keywords": [
+ "servicemanager",
+ "zf2"
+ ],
+ "time": "2014-04-15 13:59:53"
+ },
+ {
+ "name": "zendframework/zend-soap",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-soap.git",
+ "reference": "fab9f5309be04cacf01af54f694aed5102592c5c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-soap/zipball/fab9f5309be04cacf01af54f694aed5102592c5c",
+ "reference": "fab9f5309be04cacf01af54f694aed5102592c5c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-server": "self.version",
+ "zendframework/zend-stdlib": "self.version",
+ "zendframework/zend-uri": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-http": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-http": "Zend\\Http component"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Soap\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-soap",
+ "keywords": [
+ "soap",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-stdlib",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-stdlib.git",
+ "reference": "6079302963d57f36a9ba92ed3f38b992997aa78d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/6079302963d57f36a9ba92ed3f38b992997aa78d",
+ "reference": "6079302963d57f36a9ba92ed3f38b992997aa78d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-eventmanager": "self.version",
+ "zendframework/zend-filter": "self.version",
+ "zendframework/zend-serializer": "self.version",
+ "zendframework/zend-servicemanager": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-eventmanager": "To support aggregate hydrator usage",
+ "zendframework/zend-filter": "To support naming strategy hydrator usage",
+ "zendframework/zend-serializer": "Zend\\Serializer component",
+ "zendframework/zend-servicemanager": "To support hydrator plugin manager usage"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Stdlib\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-stdlib",
+ "keywords": [
+ "stdlib",
+ "zf2"
+ ],
+ "time": "2014-04-15 13:59:53"
+ },
+ {
+ "name": "zendframework/zend-text",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-text.git",
+ "reference": "e9b3fffcc6241f7cfdb33282ed10979cd8ba9b90"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-text/zipball/e9b3fffcc6241f7cfdb33282ed10979cd8ba9b90",
+ "reference": "e9b3fffcc6241f7cfdb33282ed10979cd8ba9b90",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-servicemanager": "self.version",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Text\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "homepage": "https://github.com/zendframework/zend-text",
+ "keywords": [
+ "text",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-uri",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-uri.git",
+ "reference": "0de6ba8c166a235588783ff8e88a19b364630d89"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/0de6ba8c166a235588783ff8e88a19b364630d89",
+ "reference": "0de6ba8c166a235588783ff8e88a19b364630d89",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-escaper": "self.version",
+ "zendframework/zend-validator": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Uri\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "a component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)",
+ "homepage": "https://github.com/zendframework/zend-uri",
+ "keywords": [
+ "uri",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-validator",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-validator.git",
+ "reference": "a5f97f6c3a27a27b1235f724ad0048715459f013"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/a5f97f6c3a27a27b1235f724ad0048715459f013",
+ "reference": "a5f97f6c3a27a27b1235f724ad0048715459f013",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-db": "self.version",
+ "zendframework/zend-filter": "self.version",
+ "zendframework/zend-i18n": "self.version",
+ "zendframework/zend-math": "self.version",
+ "zendframework/zend-servicemanager": "self.version",
+ "zendframework/zend-session": "self.version",
+ "zendframework/zend-uri": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-db": "Zend\\Db component",
+ "zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator",
+ "zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages as well as to use the various Date validators",
+ "zendframework/zend-math": "Zend\\Math component",
+ "zendframework/zend-resources": "Translations of validator messages",
+ "zendframework/zend-servicemanager": "Zend\\ServiceManager component to allow using the ValidatorPluginManager and validator chains",
+ "zendframework/zend-session": "Zend\\Session component",
+ "zendframework/zend-uri": "Zend\\Uri component, required by the Uri and Sitemap\\Loc validators"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\Validator\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "provides a set of commonly needed validators",
+ "homepage": "https://github.com/zendframework/zend-validator",
+ "keywords": [
+ "validator",
+ "zf2"
+ ],
+ "time": "2014-04-14 19:50:30"
+ },
+ {
+ "name": "zendframework/zend-view",
+ "version": "2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zendframework/zend-view.git",
+ "reference": "e308d498fa7851f26bd639bfe3ebbfba397c47bc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zendframework/zend-view/zipball/e308d498fa7851f26bd639bfe3ebbfba397c47bc",
+ "reference": "e308d498fa7851f26bd639bfe3ebbfba397c47bc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.23",
+ "zendframework/zend-eventmanager": "self.version",
+ "zendframework/zend-loader": "self.version",
+ "zendframework/zend-stdlib": "self.version"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "1.7.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "dev-master",
+ "zendframework/zend-authentication": "self.version",
+ "zendframework/zend-escaper": "self.version",
+ "zendframework/zend-feed": "self.version",
+ "zendframework/zend-filter": "self.version",
+ "zendframework/zend-http": "self.version",
+ "zendframework/zend-i18n": "self.version",
+ "zendframework/zend-json": "self.version",
+ "zendframework/zend-mvc": "self.version",
+ "zendframework/zend-navigation": "self.version",
+ "zendframework/zend-paginator": "self.version",
+ "zendframework/zend-permissions-acl": "self.version",
+ "zendframework/zend-servicemanager": "self.version",
+ "zendframework/zend-uri": "self.version"
+ },
+ "suggest": {
+ "zendframework/zend-authentication": "Zend\\Authentication component",
+ "zendframework/zend-escaper": "Zend\\Escaper component",
+ "zendframework/zend-feed": "Zend\\Feed component",
+ "zendframework/zend-filter": "Zend\\Filter component",
+ "zendframework/zend-http": "Zend\\Http component",
+ "zendframework/zend-i18n": "Zend\\I18n component",
+ "zendframework/zend-json": "Zend\\Json component",
+ "zendframework/zend-mvc": "Zend\\Mvc component",
+ "zendframework/zend-navigation": "Zend\\Navigation component",
+ "zendframework/zend-paginator": "Zend\\Paginator component",
+ "zendframework/zend-permissions-acl": "Zend\\Permissions\\Acl component",
+ "zendframework/zend-servicemanager": "Zend\\ServiceManager component",
+ "zendframework/zend-uri": "Zend\\Uri component"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev",
+ "dev-develop": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Zend\\View\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "provides a system of helpers, output filters, and variable escaping",
+ "homepage": "https://github.com/zendframework/zend-view",
+ "keywords": [
+ "view",
+ "zf2"
+ ],
+ "time": "2014-04-15 14:36:41"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "dev",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": []
+}
diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/Locks/GridTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/Locks/GridTest.php
new file mode 100644
index 0000000000000..766d95a7a1bb2
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/Locks/GridTest.php
@@ -0,0 +1,35 @@
+dispatch('backend/admin/locks/grid');
+
+ $body = $this->getResponse()->getBody();
+ $this->assertContains('data-column="username"', $body);
+ $this->assertContains('data-column="last_login"', $body);
+ $this->assertContains('data-column="last_login"', $body);
+ $this->assertContains('data-column="failures_num"', $body);
+ $this->assertContains('data-column="lock_expires"', $body);
+ $this->assertRegExp(
+ '/\s*adminUser1\s*<\/td>/',
+ $body
+ );
+ $this->assertRegExp(
+ '/ | \s*adminUser2\s*<\/td>/',
+ $body
+ );
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/Locks/IndexTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/Locks/IndexTest.php
new file mode 100644
index 0000000000000..c11802cc69c5b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/Locks/IndexTest.php
@@ -0,0 +1,31 @@
+dispatch('backend/admin/locks/index');
+
+ $body = $this->getResponse()->getBody();
+ $this->assertContains('Locked Users', $body);
+ $this->assertRegExp(
+ '/ | \s*adminUser1\s*<\/td>/',
+ $body
+ );
+ $this->assertRegExp(
+ '/ | \s*adminUser2\s*<\/td>/',
+ $body
+ );
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/Locks/MassUnlockTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/Locks/MassUnlockTest.php
new file mode 100644
index 0000000000000..a0bb3e09004d5
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/Locks/MassUnlockTest.php
@@ -0,0 +1,38 @@
+create('Magento\User\Model\User');
+ $userIds[] = $model->loadByUsername('adminUser1')->getId();
+ $userIds[] = $model->loadByUsername('adminUser2')->getId();
+
+ $request = $this->getRequest();
+ $request->setPostValue(
+ 'unlock',
+ $userIds
+ );
+ $this->dispatch('backend/admin/locks/massunlock');
+
+ $this->assertSessionMessages(
+ $this->contains((string)__('Unlocked %1 user(s).', count($userIds))),
+ \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS
+ );
+ $this->assertRedirect();
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/User/_files/locked_users.php b/dev/tests/integration/testsuite/Magento/User/_files/locked_users.php
new file mode 100644
index 0000000000000..51a2f82c36873
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/User/_files/locked_users.php
@@ -0,0 +1,51 @@
+create('Magento\User\Model\User');
+$model->setFirstname("John")
+ ->setLastname("Doe")
+ ->setUsername('adminUser1')
+ ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD)
+ ->setEmail('adminUser1@example.com')
+ ->setRoleType('G')
+ ->setResourceId('Magento_Adminhtml::all')
+ ->setPrivileges("")
+ ->setAssertId(0)
+ ->setRoleId(1)
+ ->setPermission('allow');
+$model->save();
+$userIds[] = $model->getDataByKey('user_id');
+
+/** @var $model \Magento\User\Model\User */
+$model = $objectManager->create('Magento\User\Model\User');
+$model->setFirstname("John")
+ ->setLastname("Doe")
+ ->setUsername('adminUser2')
+ ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD)
+ ->setEmail('adminUser2@example.com')
+ ->setRoleType('G')
+ ->setResourceId('Magento_Adminhtml::all')
+ ->setPrivileges("")
+ ->setAssertId(0)
+ ->setRoleId(1)
+ ->setPermission('allow');
+$model->save();
+$userIds[] = $model->getDataByKey('user_id');
+
+$defaultAdminUserId = 1;
+$lockLifetime = 86400;
+
+/** @var $modelLockedUsers \Magento\User\Model\Resource\User */
+$modelLockedUsers = $objectManager->create('Magento\User\Model\Resource\User');
+$modelLockedUsers->lock($userIds, $defaultAdminUserId, $lockLifetime);
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php
index 58aafb9b588fa..c756aa6b43d76 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php
@@ -7,7 +7,7 @@
'admin_assert' => 'Magento\Backend',
'authorization_role' => 'Magento\Authorization',
'authorization_rule' => 'Magento\Authorization',
- 'admin_user' => 'Magento\Backend',
+ 'admin_user' => 'Magento\User',
'adminnotification_inbox' => 'Magento\AdminNotification',
'catalog_category_entity_datetime' => 'Magento\Catalog',
'catalog_category_entity_decimal' => 'Magento\Catalog',
@@ -193,6 +193,7 @@
'oauth_nonce' => 'Magento\Integration',
'oauth_token' => 'Magento\Integration',
'authorizenet_debug' => 'Magento\Authorizenet',
+ 'admin_passwords' => 'Magento\User',
'paypal_cert' => 'Magento\Paypal',
'paypal_payment_transaction' => 'Magento\Paypal',
'paypal_settlement_report' => 'Magento\Paypal',
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/connection/blacklist/files_list.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/connection/blacklist/files_list.php
index 1e9233cee49d8..7b4ddc53272ae 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/connection/blacklist/files_list.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/connection/blacklist/files_list.php
@@ -12,5 +12,7 @@
'/app/code/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricing.php',
'/app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php',
'/app/code/Magento/CatalogImportExport/Model/Export/Product.php',
+ '/app/code/Magento/EncryptionKey/Controller/Adminhtml/Crypt/Key/Index.php',
+ '/app/code/Magento/EncryptionKey/Model/Resource/Key/Change.php',
//example '/app/code/Magento/Backend/Model/View.php',
];
diff --git a/lib/internal/Magento/Framework/Composer/ComposerInformation.php b/lib/internal/Magento/Framework/Composer/ComposerInformation.php
index 39d87457b90e6..40af109990d5b 100755
--- a/lib/internal/Magento/Framework/Composer/ComposerInformation.php
+++ b/lib/internal/Magento/Framework/Composer/ComposerInformation.php
@@ -6,17 +6,11 @@
namespace Magento\Framework\Composer;
-use Composer\Factory as ComposerFactory;
use Composer\Package\Link;
use Composer\Package\CompletePackageInterface;
-use Composer\Package\Version\VersionParser;
-use Magento\Framework\App\Filesystem\DirectoryList;
-use Magento\Framework\Filesystem;
-use Magento\Framework\Stdlib\DateTime;
/**
* Class ComposerInformation uses Composer to determine dependency information.
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ComposerInformation
{
@@ -79,21 +73,6 @@ class ComposerInformation
*/
private $locker;
- /**
- * @var \Magento\Framework\Filesystem\Directory\Write
- */
- private $directory;
-
- /**
- * @var \Magento\Framework\Stdlib\DateTime
- */
- private $dateTime;
-
- /**
- * @var string
- */
- private $pathToCacheFile = 'update_composer_packages.json';
-
/** @var array */
private static $packageTypes = [
self::THEME_PACKAGE_TYPE,
@@ -108,20 +87,14 @@ class ComposerInformation
* Constructor
*
* @param MagentoComposerApplicationFactory $applicationFactory
- * @param \Magento\Framework\Filesystem $filesystem
- * @param \Magento\Framework\Stdlib\DateTime $dateTime
* @throws \Exception
*/
public function __construct(
- MagentoComposerApplicationFactory $applicationFactory,
- Filesystem $filesystem,
- DateTime $dateTime
+ MagentoComposerApplicationFactory $applicationFactory
) {
$this->application = $applicationFactory->create();
$this->composer = $this->application->createComposer();
$this->locker = $this->composer->getLocker();
- $this->directory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
- $this->dateTime = $dateTime;
}
/**
@@ -238,53 +211,6 @@ public function getInstalledMagentoPackages()
return $packages;
}
- /**
- * Sync and cache list of available for update versions for packages
- *
- * @return bool
- */
- public function syncPackagesForUpdate()
- {
- $availableVersions = [];
- foreach ($this->getInstalledMagentoPackages() as $package) {
- $latestProductVersion = $this->getLatestNonDevVersion($package['name']);
- if ($latestProductVersion && version_compare($latestProductVersion, $package['version'], '>')) {
- $packageName = $package['name'];
- $availableVersions[$packageName] = [
- 'name' => $packageName,
- 'latestVersion' => $latestProductVersion
- ];
- }
- }
- return $this->savePackagesForUpdateToCache($availableVersions) ? true : false;
- }
-
- /**
- * Sync and cache list of available for update versions for packages
- *
- * @return bool|array
- */
- public function getPackagesForUpdate()
- {
- $actualUpdatePackages = [];
- $updatePackagesInfo = $this->loadPackagesForUpdateFromCache();
- if (!$updatePackagesInfo) {
- return false;
- }
- $updatePackages = $updatePackagesInfo['packages'];
- $availablePackages = $this->getInstalledMagentoPackages();
- foreach ($updatePackages as $package) {
- $packageName = $package['name'];
- if (array_key_exists($packageName, $availablePackages)) {
- if (version_compare($availablePackages[$packageName]['version'], $package['latestVersion'], '<')) {
- $actualUpdatePackages[$packageName] = $package;
- }
- }
- }
- $updatePackagesInfo['packages'] = $actualUpdatePackages;
- return $updatePackagesInfo;
- }
-
/**
* Checks if the passed packaged is system package
*
@@ -299,50 +225,6 @@ public function isSystemPackage($packageName = '')
return false;
}
- /**
- * Retrieve the latest available stable version for a package
- *
- * @param string $package
- * @return string
- */
- private function getLatestNonDevVersion($package)
- {
- $versionParser = new VersionParser();
- foreach ($this->getPackageAvailableVersions($package) as $version) {
- if ($versionParser->parseStability($version) != 'dev') {
- return $version;
- }
- }
- return '';
- }
-
- /**
- * Retrieve all available versions for a package
- *
- * @param string $package
- * @return array
- * @throws \RuntimeException
- */
- private function getPackageAvailableVersions($package)
- {
- $versionsPattern = '/^versions\s*\:\s(.+)$/m';
-
- $commandParams = [
- self::PARAM_COMMAND => self::COMPOSER_SHOW,
- self::PARAM_PACKAGE => $package,
- self::PARAM_AVAILABLE => true
- ];
- $result = $this->application->runComposerCommand($commandParams);
- $matches = [];
- preg_match($versionsPattern, $result, $matches);
- if (!isset($matches[1])) {
- throw new \RuntimeException(
- sprintf('Couldn\'t get available versions for package %s', $commandParams[self::PARAM_PACKAGE])
- );
- }
- return explode(', ', $matches[1]);
- }
-
/**
* Determines if Magento is the root package or it is included as a requirement.
*
@@ -355,43 +237,6 @@ private function isMagentoRoot()
return preg_match('/magento\/magento2.e/', $rootPackage->getName());
}
- /**
- * Save composer packages available for update to cache
- *
- * @param array $availableVersions
- * @return bool|string
- */
- private function savePackagesForUpdateToCache($availableVersions)
- {
- $syncInfo = [];
- $syncInfo['lastSyncDate'] = str_replace('-', '/', $this->dateTime->formatDate(true));
- $syncInfo['packages'] = $availableVersions;
- $data = json_encode($syncInfo, JSON_UNESCAPED_SLASHES);
- try {
- $this->directory->writeFile($this->pathToCacheFile, $data);
- } catch (\Magento\Framework\Exception\FileSystemException $e) {
- return false;
- }
- return $data;
- }
-
- /**
- * Load composer packages available for update from cache
- *
- * @return bool|string
- */
- private function loadPackagesForUpdateFromCache()
- {
- if ($this->directory->isExist($this->pathToCacheFile) && $this->directory->isReadable($this->pathToCacheFile)) {
- try {
- $data = $this->directory->readFile($this->pathToCacheFile);
- return json_decode($data, true);
- } catch (\Magento\Framework\Exception\FileSystemException $e) {
- }
- }
- return false;
- }
-
/**
* Check if a package is inside the root composer or not
*
diff --git a/lib/internal/Magento/Framework/Encryption/Encryptor.php b/lib/internal/Magento/Framework/Encryption/Encryptor.php
index 9a5204b02f17d..cc8c28feae760 100644
--- a/lib/internal/Magento/Framework/Encryption/Encryptor.php
+++ b/lib/internal/Magento/Framework/Encryption/Encryptor.php
@@ -149,14 +149,27 @@ public function hash($data, $version = self::HASH_VERSION_LATEST)
* @param string $password
* @param string $hash
* @return bool
+ * @deprecated
*/
public function validateHash($password, $hash)
{
- return $this->validateHashByVersion(
+ return $this->isValidHash($password, $hash);
+ }
+
+ /**
+ * Validate hash against hashing method (with or without salt)
+ *
+ * @param string $password
+ * @param string $hash
+ * @return bool
+ */
+ public function isValidHash($password, $hash)
+ {
+ return $this->isValidHashByVersion(
$password,
$hash,
self::HASH_VERSION_SHA256
- ) || $this->validateHashByVersion(
+ ) || $this->isValidHashByVersion(
$password,
$hash,
self::HASH_VERSION_MD5
@@ -171,7 +184,7 @@ public function validateHash($password, $hash)
* @param int $version
* @return bool
*/
- public function validateHashByVersion($password, $hash, $version = self::HASH_VERSION_LATEST)
+ public function isValidHashByVersion($password, $hash, $version)
{
// look for salt
$hashArr = explode(':', $hash, 2);
diff --git a/lib/internal/Magento/Framework/Encryption/EncryptorInterface.php b/lib/internal/Magento/Framework/Encryption/EncryptorInterface.php
index b9d98dc2e845b..1e72deaed4502 100644
--- a/lib/internal/Magento/Framework/Encryption/EncryptorInterface.php
+++ b/lib/internal/Magento/Framework/Encryption/EncryptorInterface.php
@@ -40,9 +40,30 @@ public function hash($data);
* @param string $hash
* @return bool
* @throws \Exception
+ * @deprecated
*/
public function validateHash($password, $hash);
+ /**
+ * Validate hash against hashing method (with or without salt)
+ *
+ * @param string $password
+ * @param string $hash
+ * @return bool
+ * @throws \Exception
+ */
+ public function isValidHash($password, $hash);
+
+ /**
+ * Validate hash by specified version
+ *
+ * @param string $password
+ * @param string $hash
+ * @param int $version
+ * @return bool
+ */
+ public function isValidHashByVersion($password, $hash, $version);
+
/**
* Encrypt a string
*
diff --git a/setup/src/Magento/Setup/Controller/ComponentGrid.php b/setup/src/Magento/Setup/Controller/ComponentGrid.php
index 426a096951e39..e94f06c941833 100644
--- a/setup/src/Magento/Setup/Controller/ComponentGrid.php
+++ b/setup/src/Magento/Setup/Controller/ComponentGrid.php
@@ -12,6 +12,7 @@
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\JsonModel;
use Zend\View\Model\ViewModel;
+use Magento\Setup\Model\UpdatePackagesCache;
/**
* Controller for component grid tasks
@@ -30,17 +31,25 @@ class ComponentGrid extends AbstractActionController
*/
private $packageInfo;
+ /**
+ * @var UpdatePackagesCache
+ */
+ private $updatePackagesCache;
+
/**
* @param ComposerInformation $composerInformation
* @param ObjectManagerProvider $objectManagerProvider
+ * @param UpdatePackagesCache $updatePackagesCache
*/
public function __construct(
ComposerInformation $composerInformation,
- ObjectManagerProvider $objectManagerProvider
+ ObjectManagerProvider $objectManagerProvider,
+ UpdatePackagesCache $updatePackagesCache
) {
$this->composerInformation = $composerInformation;
$this->packageInfo = $objectManagerProvider->get()
->get('Magento\Framework\Module\PackageInfoFactory')->create();
+ $this->updatePackagesCache = $updatePackagesCache;
}
/**
@@ -63,7 +72,7 @@ public function indexAction()
*/
public function componentsAction()
{
- $lastSyncData = $this->composerInformation->getPackagesForUpdate();
+ $lastSyncData = $this->updatePackagesCache->getPackagesForUpdate();
$components = $this->composerInformation->getInstalledMagentoPackages();
foreach ($components as $component) {
$components[$component['name']]['update'] = false;
@@ -103,8 +112,8 @@ public function componentsAction()
*/
public function syncAction()
{
- $this->composerInformation->syncPackagesForUpdate();
- $lastSyncData = $this->composerInformation->getPackagesForUpdate();
+ $this->updatePackagesCache->syncPackagesForUpdate();
+ $lastSyncData = $this->updatePackagesCache->getPackagesForUpdate();
return new JsonModel(
[
'success' => true,
diff --git a/setup/src/Magento/Setup/Model/UpdatePackagesCache.php b/setup/src/Magento/Setup/Model/UpdatePackagesCache.php
new file mode 100644
index 0000000000000..2d7f68694a47f
--- /dev/null
+++ b/setup/src/Magento/Setup/Model/UpdatePackagesCache.php
@@ -0,0 +1,203 @@
+application = $applicationFactory->create();
+ $this->directory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
+ $this->dateTime = $dateTime;
+ $this->composerInformation = $composerInformation;
+ }
+
+ /**
+ * Sync and cache list of available for update versions for packages
+ *
+ * @return bool
+ */
+ public function syncPackagesForUpdate()
+ {
+ $availableVersions = [];
+ foreach ($this->composerInformation->getInstalledMagentoPackages() as $package) {
+ $latestProductVersion = $this->getLatestNonDevVersion($package['name']);
+ if ($latestProductVersion && version_compare($latestProductVersion, $package['version'], '>')) {
+ $packageName = $package['name'];
+ $availableVersions[$packageName] = [
+ 'name' => $packageName,
+ 'latestVersion' => $latestProductVersion
+ ];
+ }
+ }
+ return $this->savePackagesForUpdateToCache($availableVersions) ? true : false;
+ }
+
+ /**
+ * Sync and cache list of available for update versions for packages
+ *
+ * @return bool|array
+ */
+ public function getPackagesForUpdate()
+ {
+ $actualUpdatePackages = [];
+ $updatePackagesInfo = $this->loadPackagesForUpdateFromCache();
+ if (!$updatePackagesInfo) {
+ return false;
+ }
+ $updatePackages = $updatePackagesInfo['packages'];
+ $availablePackages = $this->composerInformation->getInstalledMagentoPackages();
+ foreach ($updatePackages as $package) {
+ $packageName = $package['name'];
+ if (array_key_exists($packageName, $availablePackages)) {
+ if (version_compare($availablePackages[$packageName]['version'], $package['latestVersion'], '<')) {
+ $actualUpdatePackages[$packageName] = $package;
+ }
+ }
+ }
+ $updatePackagesInfo['packages'] = $actualUpdatePackages;
+ return $updatePackagesInfo;
+ }
+
+ /**
+ * Retrieve the latest available stable version for a package
+ *
+ * @param string $package
+ * @return string
+ */
+ private function getLatestNonDevVersion($package)
+ {
+ $versionParser = new VersionParser();
+ foreach ($this->getPackageAvailableVersions($package) as $version) {
+ if ($versionParser->parseStability($version) != 'dev') {
+ return $version;
+ }
+ }
+ return '';
+ }
+
+ /**
+ * Retrieve all available versions for a package
+ *
+ * @param string $package
+ * @return array
+ * @throws \RuntimeException
+ */
+ private function getPackageAvailableVersions($package)
+ {
+ $versionsPattern = '/^versions\s*\:\s(.+)$/m';
+
+ $commandParams = [
+ self::PARAM_COMMAND => self::COMPOSER_SHOW,
+ self::PARAM_PACKAGE => $package,
+ self::PARAM_AVAILABLE => true
+ ];
+ $result = $this->application->runComposerCommand($commandParams);
+ $matches = [];
+ preg_match($versionsPattern, $result, $matches);
+ if (!isset($matches[1])) {
+ throw new \RuntimeException(
+ sprintf('Couldn\'t get available versions for package %s', $commandParams[self::PARAM_PACKAGE])
+ );
+ }
+ return explode(', ', $matches[1]);
+ }
+
+ /**
+ * Save composer packages available for update to cache
+ *
+ * @param array $availableVersions
+ * @return bool|string
+ */
+ private function savePackagesForUpdateToCache($availableVersions)
+ {
+ $syncInfo = [];
+ $syncInfo['lastSyncDate'] = str_replace('-', '/', $this->dateTime->formatDate(true));
+ $syncInfo['packages'] = $availableVersions;
+ $data = json_encode($syncInfo, JSON_UNESCAPED_SLASHES);
+ try {
+ $this->directory->writeFile($this->pathToCacheFile, $data);
+ } catch (\Magento\Framework\Exception\FileSystemException $e) {
+ return false;
+ }
+ return $data;
+ }
+
+ /**
+ * Load composer packages available for update from cache
+ *
+ * @return bool|string
+ */
+ private function loadPackagesForUpdateFromCache()
+ {
+ if ($this->directory->isExist($this->pathToCacheFile) && $this->directory->isReadable($this->pathToCacheFile)) {
+ try {
+ $data = $this->directory->readFile($this->pathToCacheFile);
+ return json_decode($data, true);
+ } catch (\Magento\Framework\Exception\FileSystemException $e) {
+ }
+ }
+ return false;
+ }
+}
|