Skip to content

Commit bab395a

Browse files
authored
Merge pull request #7099 from magento-l3/PR-2021-20-08
L3 PR-2021-20-09
2 parents 60637c2 + d6388e5 commit bab395a

File tree

46 files changed

+1718
-187
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1718
-187
lines changed

app/code/Magento/Backend/App/Action/Plugin/Authentication.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ public function __construct(
102102
}
103103

104104
/**
105+
* Ensures user is authenticated before accessing backend action controllers.
106+
*
105107
* @param \Magento\Backend\App\AbstractAction $subject
106108
* @param \Closure $proceed
107109
* @param \Magento\Framework\App\RequestInterface $request
@@ -225,10 +227,9 @@ protected function _redirectIfNeededAfterLogin(\Magento\Framework\App\RequestInt
225227

226228
// Checks, whether secret key is required for admin access or request uri is explicitly set
227229
if ($this->_url->useSecretKey()) {
228-
$requestParts = explode('/', trim($request->getRequestUri(), '/'), 3);
229-
$baseUrlPath = trim(parse_url($this->backendUrl->getBaseUrl(), PHP_URL_PATH), '/');
230-
$routeIndex = empty($baseUrlPath) ? 0 : 1;
231-
$requestUri = $this->_url->getUrl($requestParts[$routeIndex]);
230+
// The requested URL has an invalid secret key and therefore redirecting to this URL
231+
// will cause a security vulnerability.
232+
$requestUri = $this->_url->getUrl($this->_url->getStartupPageUrl());
232233
} elseif ($request) {
233234
$requestUri = $request->getRequestUri();
234235
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminAssertNoErrorMessageActionGroup">
12+
<dontSeeElement selector="{{AdminMessagesSection.error}}" stepKey="dontSeeErrorMessage"/>
13+
</actionGroup>
14+
</actionGroups>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminClickLogoutActionGroup">
12+
<grabAttributeFrom selector="{{AdminHeaderSection.signOut}}" userInput="href" stepKey="logoutUrl"/>
13+
<amOnPage url="{$logoutUrl}" stepKey="logout2"/>
14+
</actionGroup>
15+
</actionGroups>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminLoginWithCustomUrlActionGroup" extends="AdminLoginActionGroup">
12+
<annotations>
13+
<description>Login to specific backend URL.</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="customUrl" type="string"/>
17+
</arguments>
18+
19+
<amOnPage url="{{customUrl}}" stepKey="navigateToAdmin"/>
20+
</actionGroup>
21+
</actionGroups>

app/code/Magento/Backend/Test/Mftf/Section/AdminHeaderSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
<element name="pageHeading" type="text" selector=".page-content .page-heading"/>
1818
<!-- Used for page not found error -->
1919
<element name="pageNotFoundTitle" type="text" selector=".page-title span"/>
20+
<element name="signOut" type="button" selector=".page-header .account-signout"/>
2021
</section>
2122
</sections>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="AdminRedirectToStartupPageAfterLoginIfSecretKeyEnabledTest">
12+
<annotations>
13+
<features value="Backend"/>
14+
<stories value="Login on the Admin Backend"/>
15+
<title value="Admin should not be redirected to the requested page after login if secret key is enabled"/>
16+
<description value="Admin should not be redirected to the requested page after login if secret key is enabled"/>
17+
<severity value="AVERAGE"/>
18+
<testCaseId value="AC-1145"/>
19+
<useCaseId value="MC-43161"/>
20+
<group value="backend"/>
21+
</annotations>
22+
<before>
23+
<!-- Add Secret Key to URLs -->
24+
<magentoCLI command="config:set admin/security/use_form_key 1" stepKey="enableUrlSecretKeys"/>
25+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
26+
</before>
27+
<after>
28+
<magentoCLI command="config:set admin/security/use_form_key 0" stepKey="disableUrlSecretKeys"/>
29+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/>
30+
</after>
31+
32+
<!-- Assert succesful login without any error message -->
33+
<actionGroup ref="AdminAssertNoErrorMessageActionGroup" stepKey="dontSeeErrorMessage1"/>
34+
<!-- Assert current page is dashboard -->
35+
<seeCurrentUrlMatches regex="~\/admin\/dashboard\/~" stepKey="seeCurrentUrlMatchesDashboardUrl"/>
36+
<!-- Navigate to web configuration -->
37+
<actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToFindPartnersAndExtensions">
38+
<argument name="menuUiId" value="magento-backend-stores"/>
39+
<argument name="submenuUiId" value="magento-config-system-config"/>
40+
</actionGroup>
41+
<actionGroup ref="AdminOpenConfigNavItemActionGroup" stepKey="navigateToWebConfig">
42+
<argument name="navItem" value="Web" />
43+
</actionGroup>
44+
<!-- Grab current URL -->
45+
<grabFromCurrentUrl stepKey="webConfigurationUrl"/>
46+
<!-- Logout -->
47+
<actionGroup ref="AdminClickLogoutActionGroup" stepKey="logout2"/>
48+
<!-- Login with directt url -->
49+
<actionGroup ref="AdminLoginWithCustomUrlActionGroup" stepKey="loginAndRedirectToRequestedPage">
50+
<argument name="customUrl" value="$webConfigurationUrl"/>
51+
</actionGroup>
52+
<!-- Assert succesful login without any error message -->
53+
<actionGroup ref="AdminAssertNoErrorMessageActionGroup" stepKey="dontSeeErrorMessage2"/>
54+
<!-- Assert current page is dashboard -->
55+
<seeCurrentUrlMatches regex="~\/admin\/dashboard\/~" stepKey="seeCurrentUrlMatchesDashboardUrl2"/>
56+
</test>
57+
</tests>

app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ private function processMediaAttribute(
550550
* @param array $clearImages
551551
* @param array $newImages
552552
* @param array $existImages
553+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
553554
*/
554555
private function processMediaAttributeLabel(
555556
Product $product,
@@ -571,6 +572,9 @@ private function processMediaAttributeLabel(
571572

572573
if (in_array($attrData, array_keys($existImages)) && isset($existImages[$attrData]['label'])) {
573574
$product->setData($mediaAttrCode . '_label', $existImages[$attrData]['label']);
575+
if ($existImages[$attrData]['label'] == null) {
576+
$resetLabel = true;
577+
}
574578
}
575579

576580
if ($attrData === 'no_selection' && !empty($product->getData($mediaAttrCode . '_label'))) {

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use Magento\CatalogGraphQl\DataProvider\Product\SearchCriteriaBuilder;
1111
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ProductSearch;
12+
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Search\QueryPopularity;
1213
use Magento\CatalogGraphQl\Model\Resolver\Products\SearchResult;
1314
use Magento\CatalogGraphQl\Model\Resolver\Products\SearchResultFactory;
1415
use Magento\Framework\Api\Search\SearchCriteriaInterface;
@@ -22,6 +23,8 @@
2223

2324
/**
2425
* Full text search for catalog using given search criteria.
26+
*
27+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2528
*/
2629
class Search implements ProductQueryInterface
2730
{
@@ -60,6 +63,11 @@ class Search implements ProductQueryInterface
6063
*/
6164
private $searchCriteriaBuilder;
6265

66+
/**
67+
* @var QueryPopularity
68+
*/
69+
private $queryPopularity;
70+
6371
/**
6472
* @param SearchInterface $search
6573
* @param SearchResultFactory $searchResultFactory
@@ -68,6 +76,7 @@ class Search implements ProductQueryInterface
6876
* @param ProductSearch $productsProvider
6977
* @param SearchCriteriaBuilder $searchCriteriaBuilder
7078
* @param ArgumentsProcessorInterface|null $argsSelection
79+
* @param QueryPopularity|null $queryPopularity
7180
*/
7281
public function __construct(
7382
SearchInterface $search,
@@ -76,16 +85,17 @@ public function __construct(
7685
FieldSelection $fieldSelection,
7786
ProductSearch $productsProvider,
7887
SearchCriteriaBuilder $searchCriteriaBuilder,
79-
ArgumentsProcessorInterface $argsSelection = null
88+
ArgumentsProcessorInterface $argsSelection = null,
89+
QueryPopularity $queryPopularity = null
8090
) {
8191
$this->search = $search;
8292
$this->searchResultFactory = $searchResultFactory;
8393
$this->pageSizeProvider = $pageSize;
8494
$this->fieldSelection = $fieldSelection;
8595
$this->productsProvider = $productsProvider;
8696
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
87-
$this->argsSelection = $argsSelection ?: ObjectManager::getInstance()
88-
->get(ArgumentsProcessorInterface::class);
97+
$this->argsSelection = $argsSelection ?: ObjectManager::getInstance()->get(ArgumentsProcessorInterface::class);
98+
$this->queryPopularity = $queryPopularity ?: ObjectManager::getInstance()->get(QueryPopularity::class);
8999
}
90100

91101
/**
@@ -124,6 +134,11 @@ public function getResult(
124134

125135
$totalPages = $realPageSize ? ((int)ceil($searchResults->getTotalCount() / $realPageSize)) : 0;
126136

137+
// add query statistics data
138+
if (!empty($args['search'])) {
139+
$this->queryPopularity->execute($context, $args['search'], (int) $searchResults->getTotalCount());
140+
}
141+
127142
$productArray = [];
128143
/** @var \Magento\Catalog\Model\Product $product */
129144
foreach ($searchResults->getItems() as $product) {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Products\Query\Search;
9+
10+
use Magento\Framework\Stdlib\StringUtils as StdlibString;
11+
use Magento\Framework\Exception\NoSuchEntityException;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\GraphQl\Model\Query\ContextInterface;
14+
use Magento\Search\Model\QueryFactory;
15+
16+
/**
17+
* Query statics handler
18+
*/
19+
class QueryPopularity
20+
{
21+
/**
22+
* @var QueryFactory
23+
*/
24+
private $queryFactory;
25+
26+
/**
27+
* @var StdlibString
28+
*/
29+
private $string;
30+
31+
/**
32+
* @param QueryFactory $queryFactory
33+
* @param StdlibString $string
34+
*/
35+
public function __construct(
36+
QueryFactory $queryFactory,
37+
StdlibString $string
38+
) {
39+
$this->queryFactory = $queryFactory;
40+
$this->string = $string;
41+
}
42+
43+
/**
44+
* Fill the query popularity
45+
*
46+
* @param ContextInterface $context
47+
* @param string $queryText
48+
* @param int $numResults
49+
* @return void
50+
* @throws NoSuchEntityException
51+
* @throws LocalizedException
52+
*/
53+
public function execute(ContextInterface $context, string $queryText, int $numResults) : void
54+
{
55+
$query = $this->queryFactory->create();
56+
$maxQueryLength = (int) $query->getMaxQueryLength();
57+
if ($maxQueryLength && $this->string->strlen($queryText) > $maxQueryLength) {
58+
$queryText = $this->string->substr($queryText, 0, $maxQueryLength);
59+
}
60+
$query->setQueryText($queryText);
61+
$store = $context->getExtensionAttributes()->getStore();
62+
$query->setStoreId($store->getId());
63+
$query->saveIncrementalPopularity();
64+
$query->saveNumResults($numResults);
65+
}
66+
}

0 commit comments

Comments
 (0)