This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the Superdesk Web Publisher MultiTenancyBundle. |
||
5 | * |
||
6 | * Copyright 2016 Sourcefabric z.u. and contributors. |
||
7 | * |
||
8 | * For the full copyright and license information, please see the |
||
9 | * AUTHORS and LICENSE files distributed with this source code. |
||
10 | * |
||
11 | * @copyright 2016 Sourcefabric z.ú |
||
12 | * @license http://www.superdesk.org/license |
||
13 | */ |
||
14 | |||
15 | namespace SWP\Bundle\MultiTenancyBundle\Command; |
||
16 | |||
17 | use Doctrine\Common\Persistence\ObjectManager; |
||
18 | use SWP\Component\MultiTenancy\Factory\TenantFactoryInterface; |
||
19 | use SWP\Component\MultiTenancy\Model\OrganizationInterface; |
||
20 | use SWP\Component\MultiTenancy\Model\TenantInterface; |
||
21 | use SWP\Component\MultiTenancy\Repository\OrganizationRepositoryInterface; |
||
22 | use SWP\Component\MultiTenancy\Repository\TenantRepositoryInterface; |
||
23 | use Symfony\Component\Console\Command\Command; |
||
24 | use Symfony\Component\Console\Input\InputArgument; |
||
25 | use Symfony\Component\Console\Input\InputInterface; |
||
26 | use Symfony\Component\Console\Input\InputOption; |
||
27 | use Symfony\Component\Console\Output\OutputInterface; |
||
28 | use Symfony\Component\Console\Question\Question; |
||
29 | |||
30 | class CreateTenantCommand extends Command |
||
31 | { |
||
32 | protected static $defaultName = 'swp:tenant:create'; |
||
33 | |||
34 | protected $arguments = ['domain', 'subdomain', 'name', 'organization code']; |
||
35 | |||
36 | private $swpDomain; |
||
37 | |||
38 | private $tenantFactory; |
||
39 | |||
40 | private $tenantObjectManager; |
||
41 | |||
42 | private $tenantRepository; |
||
43 | |||
44 | private $organizationRepository; |
||
45 | |||
46 | public function __construct( |
||
47 | string $swpDomain, |
||
48 | TenantFactoryInterface $tenantFactory, |
||
49 | ObjectManager $tenantObjectManager, |
||
50 | TenantRepositoryInterface $tenantRepository, |
||
51 | OrganizationRepositoryInterface $organizationRepository |
||
52 | ) { |
||
53 | parent::__construct(); |
||
54 | |||
55 | $this->swpDomain = $swpDomain; |
||
56 | $this->tenantFactory = $tenantFactory; |
||
57 | $this->tenantObjectManager = $tenantObjectManager; |
||
58 | $this->tenantRepository = $tenantRepository; |
||
59 | $this->organizationRepository = $organizationRepository; |
||
60 | } |
||
61 | |||
62 | protected function configure(): void |
||
63 | { |
||
64 | $this |
||
65 | ->setName('swp:tenant:create') |
||
66 | ->setDescription('Creates a new tenant.') |
||
67 | ->setDefinition([ |
||
68 | new InputArgument($this->arguments[3], InputArgument::OPTIONAL, 'Organization code'), |
||
69 | new InputArgument($this->arguments[0], InputArgument::OPTIONAL, 'Domain name'), |
||
70 | new InputArgument($this->arguments[2], InputArgument::OPTIONAL, 'Tenant name'), |
||
71 | new InputArgument($this->arguments[1], InputArgument::OPTIONAL, 'Subdomain name', null), |
||
72 | new InputOption('disabled', null, InputOption::VALUE_NONE, 'Set the tenant as a disabled'), |
||
73 | new InputOption('default', null, InputOption::VALUE_NONE, 'Creates the default tenant'), |
||
74 | ]) |
||
75 | ->setHelp( |
||
76 | <<<'EOT' |
||
77 | The <info>%command.name%</info> command creates a new tenant. |
||
78 | EOT |
||
79 | ); |
||
80 | } |
||
81 | |||
82 | protected function execute(InputInterface $input, OutputInterface $output): int |
||
83 | { |
||
84 | $domain = $input->getArgument($this->arguments[0]); |
||
85 | $subdomain = $input->getArgument($this->arguments[1]); |
||
86 | $name = $input->getArgument($this->arguments[2]); |
||
87 | $organizationCode = $input->getArgument($this->arguments[3]); |
||
88 | $default = $input->getOption('default'); |
||
89 | $disabled = $input->getOption('disabled'); |
||
90 | |||
91 | if ($default) { |
||
92 | $name = TenantInterface::DEFAULT_TENANT_NAME; |
||
93 | $domain = $this->swpDomain; |
||
94 | $organization = $this->organizationRepository->findOneByName(OrganizationInterface::DEFAULT_NAME); |
||
95 | if (null === $organization) { |
||
96 | throw new \InvalidArgumentException('Default organization doesn\'t exist!'); |
||
97 | } |
||
98 | } else { |
||
99 | $organization = $this->organizationRepository->findOneByCode($organizationCode); |
||
0 ignored issues
–
show
|
|||
100 | |||
101 | if (null === $organization) { |
||
102 | throw new \InvalidArgumentException(sprintf('Organization with "%s" code doesn\'t exist!', $organizationCode)); |
||
103 | } |
||
104 | } |
||
105 | |||
106 | if (null !== $subdomain) { |
||
107 | $tenant = $this->tenantRepository->findOneBySubdomainAndDomain($subdomain, $domain); |
||
0 ignored issues
–
show
It seems like
$subdomain defined by $input->getArgument($this->arguments[1]) on line 85 can also be of type array<integer,string> ; however, SWP\Component\MultiTenan...eBySubdomainAndDomain() does only seem to accept string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() It seems like
$domain defined by $input->getArgument($this->arguments[0]) on line 84 can also be of type array<integer,string> or null ; however, SWP\Component\MultiTenan...eBySubdomainAndDomain() does only seem to accept string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
108 | } else { |
||
109 | $tenant = $this->tenantRepository->findOneByDomain($domain); |
||
0 ignored issues
–
show
It seems like
$domain defined by $input->getArgument($this->arguments[0]) on line 84 can also be of type array<integer,string> or null ; however, SWP\Component\MultiTenan...face::findOneByDomain() does only seem to accept string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
110 | } |
||
111 | |||
112 | if (null !== $tenant) { |
||
113 | throw new \InvalidArgumentException(sprintf('Tenant with domain %s and subdomain "%s" already exists!', $domain, $subdomain)); |
||
114 | } |
||
115 | |||
116 | $tenant = $this->createTenant($domain, $subdomain, $name, $disabled, $organization); |
||
0 ignored issues
–
show
It seems like
$domain defined by $input->getArgument($this->arguments[0]) on line 84 can also be of type array<integer,string> or null ; however, SWP\Bundle\MultiTenancyB...Command::createTenant() does only seem to accept string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
117 | if ($default) { |
||
118 | $tenant->setCode(TenantInterface::DEFAULT_TENANT_CODE); |
||
119 | } |
||
120 | $this->tenantObjectManager->persist($tenant); |
||
121 | $this->tenantObjectManager->flush(); |
||
122 | |||
123 | $output->writeln( |
||
124 | sprintf( |
||
125 | 'Tenant <info>%s</info> (code: <info>%s</info>) has been created and <info>%s</info>!', |
||
126 | $name, |
||
127 | $tenant->getCode(), |
||
128 | $tenant->isEnabled() ? 'enabled' : 'disabled' |
||
129 | ) |
||
130 | ); |
||
131 | |||
132 | return 1; |
||
133 | } |
||
134 | |||
135 | protected function interact(InputInterface $input, OutputInterface $output): void |
||
136 | { |
||
137 | foreach ($this->arguments as $value) { |
||
138 | $this->askAndValidateInteract($input, $output, $value); |
||
139 | } |
||
140 | } |
||
141 | |||
142 | protected function askAndValidateInteract(InputInterface $input, OutputInterface $output, $name): void |
||
143 | { |
||
144 | $default = $input->getOption('default'); |
||
145 | if (!$input->getArgument($name) && !$default) { |
||
146 | $question = new Question(sprintf('<question>Please enter %s:</question>', $name)); |
||
147 | $question->setValidator(function ($argument) use ($name) { |
||
148 | if (empty($argument) && $name !== $this->arguments[1]) { |
||
149 | throw new \RuntimeException(sprintf('The %s can not be empty', $name)); |
||
150 | } |
||
151 | |||
152 | return $argument; |
||
153 | }); |
||
154 | |||
155 | $question->setMaxAttempts(3); |
||
156 | |||
157 | $argument = $this->getHelper('question')->ask($input, $output, $question); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Symfony\Component\Console\Helper\HelperInterface as the method ask() does only exist in the following implementations of said interface: Symfony\Component\Console\Helper\QuestionHelper , Symfony\Component\Consol...r\SymfonyQuestionHelper .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
158 | |||
159 | $input->setArgument($name, $argument); |
||
160 | } |
||
161 | } |
||
162 | |||
163 | protected function createTenant(string $domain, ?string $subdomain, string $name, bool $disabled, OrganizationInterface $organization): TenantInterface |
||
164 | { |
||
165 | /** @var TenantInterface $tenant */ |
||
166 | $tenant = $this->tenantFactory->create(); |
||
167 | $tenant->setSubdomain($subdomain); |
||
168 | $tenant->setDomainName($domain); |
||
169 | $tenant->setName($name); |
||
170 | $tenant->setEnabled(!$disabled); |
||
171 | $tenant->setOrganization($organization); |
||
172 | |||
173 | return $tenant; |
||
174 | } |
||
175 | } |
||
176 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.