Skip to content

Commit

Permalink
Merge branch '5.0' into 5.0.4-to-5.x
Browse files Browse the repository at this point in the history
  • Loading branch information
escopecz committed Apr 16, 2024
2 parents 27968c7 + 4676457 commit 7402b89
Show file tree
Hide file tree
Showing 23 changed files with 572 additions and 25 deletions.
16 changes: 12 additions & 4 deletions app/bundles/AssetBundle/Form/Type/AssetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Url;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
Expand Down Expand Up @@ -84,10 +85,17 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'remotePath',
TextType::class,
[
'label' => 'mautic.asset.asset.form.remotePath',
'label_attr' => ['class' => 'control-label'],
'attr' => ['class' => 'form-control'],
'required' => false,
'label' => 'mautic.asset.asset.form.remotePath',
'label_attr' => ['class' => 'control-label'],
'attr' => ['class' => 'form-control'],
'required' => false,
'constraints' => [
new Url(
[
'message' => 'mautic.asset.validation.error.url',
]
),
],
]
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ public function testCreateNewRemoteAsset(): void
$this->assertNotNull($response['asset']['size']);
}

public function testCreateNewRemoteAssetWithVulnerableFile(): void
{
$payload = [
'file' => 'file:///etc/passwd',
'storageLocation' => 'remote',
'title' => 'title',
];
$this->client->request('POST', 'api/assets/new', $payload);
$clientResponse = $this->client->getResponse();
$this->assertSame(400, $clientResponse->getStatusCode(), $clientResponse->getContent());
$this->assertEquals('{"errors":[{"code":400,"message":"remotePath: The remote should be a valid URL.","details":{"remotePath":["The remote should be a valid URL."]}}]}', $clientResponse->getContent());
}

public function testCreateNewLocalAsset(): void
{
$assetsPath = $this->client->getKernel()->getContainer()->getParameter('mautic.upload_dir');
Expand Down
3 changes: 2 additions & 1 deletion app/bundles/AssetBundle/Translations/en_US/validators.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ mautic.asset.asset.error.missing.title="Assset Title is required."
mautic.asset.asset.error.missing.remote.path="A remote URL must be specified when remote storage is selected."
mautic.asset.asset.error.file.size="Upload failed as the file is %fileSize% MB which exceeds the maximum allowed file size of %maxSize% MB. This setting can be changed in the Configuration."
mautic.asset.asset.error.file.extension="Upload failed as the file extension, %fileExtension%, is not in the list of allowed extensions (%extensions%). This setting can be changed in the Configuration."
mautic.asset.asset.error.file.extension.js="Upload failed as the file extension is not in the list of allowed extensions (%extensions%). This setting can be changed in the Configuration."
mautic.asset.asset.error.file.extension.js="Upload failed as the file extension is not in the list of allowed extensions (%extensions%). This setting can be changed in the Configuration."
mautic.asset.validation.error.url="The remote should be a valid URL."
11 changes: 11 additions & 0 deletions app/bundles/FormBundle/Controller/Api/FormApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,15 @@ protected function processForm(Request $request, $entity, $parameters = null, $m

return parent::processForm($request, $entity, $parameters, $method);
}

public function newEntityAction(Request $request): Response
{
$parameters = $request->request->all();

if (!isset($parameters['postAction'])) {
$request->request->add(['postAction' => 'return']);
}

return parent::newEntityAction($request);
}
}
7 changes: 6 additions & 1 deletion app/bundles/LeadBundle/Controller/CompanyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ public function contactsListAction(Request $request, $objectId, $page = 1)
return $this->accessDenied();
}

// set some permissions
$permissions = $this->security->isGranted(
[
'lead:leads:viewown',
Expand Down Expand Up @@ -820,13 +819,19 @@ public function mergeAction(Request $request, $objectId)
// set some permissions
$permissions = $this->security->isGranted(
[
'lead:leads:viewown',
'lead:leads:viewother',
'lead:leads:create',
'lead:leads:editother',
'lead:leads:deleteother',
],
'RETURN_ARRAY'
);

if (!$permissions['lead:leads:viewown'] && !$permissions['lead:leads:viewother']) {
return $this->accessDenied();
}

/** @var CompanyModel $model */
$model = $this->getModel('lead.company');
$secondaryCompany = $model->getEntity($objectId);
Expand Down
25 changes: 25 additions & 0 deletions app/bundles/LeadBundle/Controller/LeadController.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,27 @@ public function indexAction(

public function quickAddAction(Request $request): Response
{
// set some permissions
$permissions = $this->security->isGranted(
[
'lead:leads:viewown',
'lead:leads:viewother',
'lead:leads:create',
'lead:leads:editown',
'lead:leads:editother',
],
'RETURN_ARRAY'
);

if (
!$permissions['lead:leads:viewown']
&& !$permissions['lead:leads:viewother']
&& !$permissions['lead:leads:create']
&& !$permissions['lead:leads:editown']
&& !$permissions['lead:leads:editother']
) {
return $this->accessDenied();
}
/** @var \Mautic\LeadBundle\Model\LeadModel $model */
$model = $this->getModel('lead.lead');

Expand Down Expand Up @@ -1851,6 +1872,10 @@ public function batchStagesAction(Request $request, $objectId = 0)
*/
public function batchOwnersAction(Request $request, $objectId = 0)
{
if (!$this->security->isGranted('user:users:view')) {
return $this->accessDenied();
}

if ('POST' == $request->getMethod()) {
/** @var \Mautic\LeadBundle\Model\LeadModel $model */
$model = $this->getModel('lead');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace Mautic\LeadBundle\Tests\Functional\Controller;

use Mautic\CoreBundle\Test\MauticMysqlTestCase;
use Mautic\UserBundle\Entity\Role;
use Mautic\UserBundle\Entity\User;

class CompanyControllerTest extends MauticMysqlTestCase
{
public const USERNAME = 'jhony';

public function testMergeAction(): void
{
$this->client->request('GET', '/s/companies/merge/1');
$clientResponse = $this->client->getResponse();
$this->assertEquals(200, $clientResponse->getStatusCode());
}

public function testMergeActionWithoutPermission(): void
{
$this->createAndLoginUser();
$this->client->request('GET', '/s/companies/merge/1');
$clientResponse = $this->client->getResponse();
$this->assertEquals(403, $clientResponse->getStatusCode());
}

private function createAndLoginUser(): User
{
// Create non-admin role
$role = $this->createRole();
// Create non-admin user
$user = $this->createUser($role);

$this->em->flush();
$this->em->detach($role);

$this->loginUser(self::USERNAME);
$this->client->setServerParameter('PHP_AUTH_USER', self::USERNAME);
$this->client->setServerParameter('PHP_AUTH_PW', 'mautic');

return $user;
}

private function createRole(bool $isAdmin = false): Role
{
$role = new Role();
$role->setName('Role');
$role->setIsAdmin($isAdmin);

$this->em->persist($role);

return $role;
}

private function createUser(Role $role): User
{
$user = new User();
$user->setFirstName('Jhony');
$user->setLastName('Doe');
$user->setUsername(self::USERNAME);
$user->setEmail('[email protected]');
$encoder = self::$container->get('security.encoder_factory')->getEncoder($user);
$user->setPassword($encoder->encodePassword('mautic', null));
$user->setRole($role);

$this->em->persist($user);

return $user;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
use Mautic\LeadBundle\Command\ContactScheduledExportCommand;
use Mautic\LeadBundle\Entity\ContactExportScheduler;
use Mautic\LeadBundle\Entity\Lead;
use Mautic\UserBundle\Entity\Role;
use Mautic\UserBundle\Entity\User;
use PHPUnit\Framework\Assert;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class LeadControllerTest extends MauticMysqlTestCase
{
public const USERNAME = 'jhony';
/**
* @var array<string>
*/
Expand Down Expand Up @@ -101,4 +104,83 @@ private function checkContactExportScheduler(int $count): array

return $allRows;
}

public function testAccessContactQuickAddWithPermission(): void
{
$this->setAdminUser();
$this->client->request(Request::METHOD_GET, '/s/contacts/quickAdd');
$this->assertResponseStatusCodeSame(200, (string) $this->client->getResponse()->getStatusCode());
}

private function setAdminUser(): void
{
$this->loginUser('admin');
$this->client->setServerParameter('PHP_AUTH_USER', 'admin');
$this->client->setServerParameter('PHP_AUTH_PW', 'mautic');
}

public function testAccessContactQuickAddWithNoPermission(): void
{
$this->createAndLoginUser();
$this->client->request(Request::METHOD_GET, '/s/contacts/quickAdd');
$this->assertResponseStatusCodeSame(403, (string) $this->client->getResponse()->getStatusCode());
}

public function testAccessContactBatchOwnersNoPermission(): void
{
$this->createAndLoginUser();
$this->client->request(Request::METHOD_GET, '/s/contacts/batchOwners');
$this->assertResponseStatusCodeSame(403, (string) $this->client->getResponse()->getStatusCode());
}

public function testAccessContactBatchOwnersPermission(): void
{
$this->setAdminUser();
$this->client->request(Request::METHOD_GET, '/s/contacts/batchOwners');
$this->assertResponseStatusCodeSame(200, (string) $this->client->getResponse()->getStatusCode());
}

private function createAndLoginUser(): User
{
// Create non-admin role
$role = $this->createRole();
// Create non-admin user
$user = $this->createUser($role);

$this->em->flush();
$this->em->detach($role);

$this->loginUser(self::USERNAME);
$this->client->setServerParameter('PHP_AUTH_USER', self::USERNAME);
$this->client->setServerParameter('PHP_AUTH_PW', 'mautic');

return $user;
}

private function createRole(bool $isAdmin = false): Role
{
$role = new Role();
$role->setName('Role');
$role->setIsAdmin($isAdmin);

$this->em->persist($role);

return $role;
}

private function createUser(Role $role): User
{
$user = new User();
$user->setFirstName('Jhony');
$user->setLastName('Doe');
$user->setUsername(self::USERNAME);
$user->setEmail('[email protected]');
$encoder = self::$container->get('security.encoder_factory')->getEncoder($user);
$user->setPassword($encoder->encodePassword('mautic', null));
$user->setRole($role);

$this->em->persist($user);

return $user;
}
}
9 changes: 9 additions & 0 deletions app/bundles/PluginBundle/Config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
declare(strict_types=1);

use Mautic\CoreBundle\DependencyInjection\MauticCoreExtension;
use Mautic\PluginBundle\EventListener\CampaignSubscriber;
use Mautic\PluginBundle\EventListener\FormSubscriber;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

use function Symfony\Component\DependencyInjection\Loader\Configurator\service;

return function (ContainerConfigurator $configurator): void {
$services = $configurator->services()
->defaults()
Expand All @@ -24,4 +28,9 @@

$services->alias('mautic.plugin.model.plugin', \Mautic\PluginBundle\Model\PluginModel::class);
$services->alias('mautic.plugin.model.integration_entity', \Mautic\PluginBundle\Model\IntegrationEntityModel::class);

$services->set(FormSubscriber::class)
->call('setIntegrationHelper', [service('mautic.helper.integration')]);
$services->set(CampaignSubscriber::class)
->call('setIntegrationHelper', [service('mautic.helper.integration')]);
};
Loading

0 comments on commit 7402b89

Please sign in to comment.