Issues (71)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Console/Command/SeederShell.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
App::uses('ShellModelTruncator', 'FakeSeeder.Lib');
4
App::uses('Folder', 'Utility');
5
6
/**
7
 * SeederShell
8
 *
9
 * Can either be used to invoke seeder shell tasks directly
10
 * or as base class for seeder suites (logically groups of seeders) to base upon.
11
 *
12
 * @todo Evaluate if it's sensible to split this class into two (shell and base class)
13
 */
14
class SeederShell extends AppShell {
15
16
	/**
17
	 * Defined the seeder tasks names without 'SeederTask' suffix to execute in this suite in in sequential order
18
	 *
19
	 * @var array
20
	 * @todo Consider allowing to set the records per seeder, as sub array
21
	 */
22
	protected $_seeders = array();
23
24
	/**
25
	 * Additional models to truncate
26
	 *
27
	 * @var array
28
	 */
29
	protected $_modelsToTruncate = array();
30
31
	/**
32
	 * Initialize seeder shell, make sure it's OK to seed
33
	 *
34
	 * @return void
35
	 */
36
	public function initialize() {
37
		parent::initialize();
38
39
		$this->_checkSeedable();
40
	}
41
42
	/**
43
	 * Check if seeding the database is allowed
44
	 *
45
	 * @return void
46
	 * ¦todo Consider making this over writable by a CLI parameter, e.g. --force or --ignore-check
47
	 */
48
	protected function _checkSeedable() {
49
		if (Configure::read('FakeSeeder.seedable') !== true) {
50
			$this->_stop(__('Seeding is not activated in configuration in "FakeSeeder.seedable"!'));
51
		}
52
		if (Configure::read('debug') < 1) {
53
			$this->_stop(__('Seeding is allowed only in debug mode!'));
54
		}
55
	}
56
57
	/**
58
	 * Get the Console Option Parser
59
	 *
60
	 * @return ConsoleOptionParser The Console Option Parser.
61
	 */
62
	public function getOptionParser() {
63
		$parser = parent::getOptionParser();
64
65
		$parser->description(array(
66
			__('A shell to seed your database with fake and/or fixed data.'),
67
			__(''),
68
			__('Uses Faker to generate the fake data.'),
69
			__('Uses shell tasks for implementing specific seeders.'),
70
			__('Organizes logical groups of seeders in custom seeder shells/suites.'),
71
		));
72
		$parser->addArguments(array(
73
			'model' => array(
74
				'help' => "The name of a seeder shell task without 'SeederTask' suffix.\n" .
75
					"For example 'Article' for 'ArticleSeederTask'.\n" .
76
					"Alternatively the name of a model.\n" .
77
					"It will try to guess the field formatters then.",
78
				'required' => false,
79
			)
80
		));
81
		$parser->addOptions(array(
82
			'mode' => array(
83
				'help' => "The seeding mode.\n" .
84
					"'manual' = No Field formatters are guessed.\n" .
85
					"'auto' = All field formatters are guessed.\n" .
86
					"'mixed' = Only missing field formatters are guessed.\n",
87
				'short' => 'm',
88
				'choices' => array('manual', 'auto', 'mixed'),
89
				'default' => '',
90
			),
91
			'locale' => array(
92
				'help' => 'The locale to use for Faker.',
93
				'short' => 'l',
94
				'default' => '',
95
			),
96
			'records' => array(
97
				'help' => 'The amount of records to seed.',
98
				'short' => 'r',
99
				'default' => '',
100
			),
101
			'validate' => array(
102
				'help' => 'Whether or not to validate when saving the seeding data.',
103
				'choices' => array('first', true, false),
104
				'default' => '',
105
			),
106
			'seed' => array(
107
				'help' => 'Set the seed number for Faker to use.',
108
				'short' => 's',
109
				'default' => '',
110
			),
111
			'no-truncate' => array(
112
				'help' => 'Prevents that the model gets truncated before seeding.',
113
				'boolean' => true,
114
			),
115
		));
116
		$parser->epilog(array(
117
			__('All shell options can be set through:'),
118
			__('1. CLI parameter, e.g. "--records"'),
119
			__('2. The seeder specific configuration, e.g. "FakeSeeder.Article.records"'),
120
			__('3. The general seeder configuration, e.g "FakeSeeder.records"'),
121
			__('4. The seeder shell task class properties, e.g. "$_records"'),
122
			__('The values are checked in that order. The first value found is taken.'),
123
			__('If no value is set, it will fall back to an optional default value.'),
124
			__(''),
125
			__('When no seeders are set (e.g. in a custom seeder suite) and if called without arguments, ' .
126
				'it will prompt to execute one of the seeder shell tasks available.'),
127
		));
128
129
		return $parser;
130
	}
131
132
	/**
133
	 * Main Seeder method
134
	 *
135
	 * If invoked with a seeder name an argument, it executes this single seeder shell task.
136
	 * If invoked without seeder name as argument, it prompts for a seeder shell to execute.
137
	 *
138
	 * @return void
139
	 * @todo Consider using DB transaction(s)
140
	 */
141
	public function main() {
142
		// TODO Disable FK constraints
143
144
		if (!empty($this->args[0])) {
145
			// Either execute the given seeder task
146
			$seederName = $this->args[0];
147
			$this->out(__('Execute %s seeder...', $seederName));
148
			$this->_executeSeederTask($seederName, $this->params['no-truncate']);
149
		} elseif (!empty($this->_seeders)) {
150
			// Execute all seeders set in $_seeders (only applies for subclasses)
151
			if ($this->params['no-truncate'] === false) {
152
				$this->_truncateModels();
153
			}
154
			$this->_callSeeders();
155
		} else {
156
			// Prompt for a seeder shell task to execute
157
			$this->_promptForSeeder();
158
		}
159
160
		// TODO Enable FK constraints, if necessary
161
	}
162
163
	/**
164
	 * Truncate the models
165
	 *
166
	 * Merges all the models from all seeders with the additionally configured  models.
167
	 *
168
	 * @return void
169
	 * @see ShellModelTruncator::truncateModels
170
	 */
171
	protected function _truncateModels() {
172
		$this->out(__('Truncating models...'));
173
174
		// Get all models from all seeders
175
		$modelsToTruncate = array();
176
		foreach ($this->_seeders as $seederName) {
177
			$modelsToTruncate = array_merge(
178
				$modelsToTruncate,
179
				$this->_getModelsToTruncateFromSeederTask($seederName)
180
			);
181
		}
182
183
		$modelsToTruncate = array_merge($modelsToTruncate, $this->_modelsToTruncate);
184
		$modelsToTruncate = array_unique($modelsToTruncate);
185
186
		$modelTruncator = $this->_getModelTruncator();
187
		$modelTruncator->truncateModels($modelsToTruncate);
188
189
		$this->out(__('Finished truncating models.'));
190
	}
191
192
	/**
193
	 * Get an instance of the ShellModelTruncator, for delegating the model truncation
194
	 *
195
	 * @return ShellModelTruncator The shell model truncator instance.
196
	 */
197
	protected function _getModelTruncator() {
198
		return new ShellModelTruncator($this);
199
	}
200
201
	/**
202
	 * Get the models to truncate from the seeder task
203
	 *
204
	 * @param string $seederName The name of the seeder task.
205
	 * @return array The models to truncate.
206
	 */
207
	protected function _getModelsToTruncateFromSeederTask($seederName) {
208
		$seederName = $seederName . 'Seeder';
209
		$seederTask = $this->Tasks->load($seederName);
210
211
		$models = $seederTask->getModelsToTruncate();
212
		return $models;
213
	}
214
215
	/**
216
	 * Call the seeders of the suite
217
	 *
218
	 * Does not execute the data truncation in the seeders as we've done that already.
219
	 *
220
	 * @return void
221
	 */
222
	protected function _callSeeders() {
223
		$this->out(__('Execute seeders...'));
224
225
		foreach ($this->_seeders as $seederName) {
226
			$this->out(__('Execute %s seeder...', $seederName));
227
			$this->_executeSeederTask($seederName, true);
228
229
		}
230
		$this->out(__('Finished executing seeders.'));
231
	}
232
233
	/**
234
	 * Prompts the user with a list of available seeder shell tasks
235
	 *
236
	 * Only supports app based seeder shell tasks, at the moment.
237
	 *
238
	 * @return void
239
	 */
240
	protected function _promptForSeeder() {
241
		$seederTasks = $this->_getSeederTasks();
242
243
		$this->out(__('Choose one seeder shell task to execute:'));
244
		$taskCount = count($seederTasks);
245
		for ($i = 0; $i < $taskCount; $i++) {
246
			$this->out(sprintf("%d. %s", $i + 1, $seederTasks[$i]));
247
		}
248
249
		$chosenSeeder = $this->in(__("Enter a number from the list above,\n" .
250
			"type in the name of another seeder shell task,\n" .
251
			"type in the name of a model,\n" .
252
			"or 'q' to exit"), null, 'q');
253
254
		if ($chosenSeeder === 'q') {
255
			$this->_stop();
256
			return;
257
		}
258
259
		if (!$chosenSeeder || (int)$chosenSeeder > $taskCount) {
260
			$this->err(__d('cake_console', "The seeder shell task name you supplied was empty,\n" .
261
				"or the number you selected was not a valid option. Please try again."));
262
			$this->_stop();
263
			return;
264
		}
265
		if ((int)$chosenSeeder > 0 && (int)$chosenSeeder <= $taskCount) {
266
			$chosenSeeder = $seederTasks[(int)$chosenSeeder - 1];
267
		}
268
269
		$this->out(__('Execute %s seeder...', $chosenSeeder));
270
		// Add seeder to argument list, in case it is a model
271
		$this->args[0] = $chosenSeeder;
272
		$this->_executeSeederTask($chosenSeeder, $this->params['no-truncate']);
273
	}
274
275
	/**
276
	 * Get the available seeder shell tasks
277
	 *
278
	 * Checks for *SeederTask.php files in
279
	 * app/Console/Command/Task/.
280
	 *
281
	 * @return array The available seeder shell tasks.
282
	 * @todo Also support plugin shell tasks.
283
	 * @todo Improve testability by getting the Folder object from externally.
284
	 */
285
	protected function _getSeederTasks() {
286
		$taskDir = ROOT . DS . APP_DIR . DS . 'Console' . DS . 'Command' . DS . 'Task' . DS;
287
		$dir = new Folder($taskDir);
288
		$files = $dir->find('(.*)SeederTask\.php');
289
		$seedTasks = array();
290
		foreach ($files as $file) {
291
			$seedTasks[] = substr(basename($file), 0, -14);
292
		}
293
		sort($seedTasks);
294
		return $seedTasks;
295
	}
296
297
	/**
298
	 * Execute a seeder Task
299
	 *
300
	 * Loads a task and make sure it is initialized properly
301
	 *
302
	 * @param string $seederName The name of the seeder task, without SeederTask.
303
	 * @param bool $noTruncate Prevents that the model gets truncated before seeding, defaults to true.
304
	 * @return void
305
	 */
306
	protected function _executeSeederTask($seederName, $noTruncate = true) {
307
		$seederNameSuffixed = $seederName . 'Seeder';
308
		try {
309
			$seederTask = $this->Tasks->load($seederNameSuffixed);
310
		} catch (MissingTaskException $e) {
0 ignored issues
show
The class MissingTaskException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
311
			$this->out(__(
312
				"No seeder shell tasks named '%s' found. Trying to find a '%s' model.",
313
				$seederNameSuffixed,
314
				$seederName
315
			));
316
317
			// Make sure the table/model exists
318
			$model = $this->_loadSeederModel($seederName);
319
			if ($model === false) {
320
				$this->out(__("No model '%s' found , aborting.", $seederName));
321
				return;
322
			}
323
324
			// Execute the DynamicModelSeeder if the model exists
325
			$seederTask = $this->Tasks->load('FakeSeeder.DynamicModelSeeder');
326
		}
327
		// Copy given arguments & parameters
328
		$seederTask->args =& $this->args;
329
		$seederTask->params =& $this->params;
330
		// Overwrite no-truncate to make ake sure a task does not truncates again
331
		// when executed as a site
332
		$seederTask->params['no-truncate'] = $noTruncate;
333
334
		$seederTask->initialize();
335
336
		$seederTask->execute();
337
	}
338
339
	/**
340
	 * Load a model to seed
341
	 *
342
	 * @param string $seederName The model to load
343
	 * @return
344
	 */
345
	protected function _loadSeederModel($seederName) {
346
		return ClassRegistry::init($seederName);
347
	}
348
}
349