PageRenderTime 27ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Fisma/Cli/GenerateIncidents.php

https://bitbucket.org/areeves42/openfisma
PHP | 231 lines | 150 code | 33 blank | 48 comment | 9 complexity | 74f952e9c7f04cec420a210fac8087be MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright (c) 2011 Endeavor Systems, Inc.
  4. *
  5. * This file is part of OpenFISMA.
  6. *
  7. * OpenFISMA is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
  8. * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
  9. * version.
  10. *
  11. * OpenFISMA is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
  12. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  13. * details.
  14. *
  15. * You should have received a copy of the GNU General Public License along with OpenFISMA. If not, see
  16. * {@link http://www.gnu.org/licenses/}.
  17. */
  18. /**
  19. * Class description
  20. *
  21. * @author Mark E. Haase <mhaase@endeavorystems.com>
  22. * @copyright (c) Endeavor Systems, Inc. 2011 {@link http://www.endeavorsystems.com}
  23. * @license http://www.openfisma.org/content/license GPLv3
  24. * @package Fisma
  25. * @subpackage Fisma_Cli
  26. */
  27. class Fisma_Cli_GenerateIncidents extends Fisma_Cli_AbstractGenerator
  28. {
  29. /**
  30. * Configure the arguments accepted for this CLI program
  31. *
  32. * @return array An array containing getopt long syntax
  33. */
  34. public function getArgumentsDefinitions()
  35. {
  36. return array(
  37. 'number|n=i' => "Number of incident objects to generate"
  38. );
  39. }
  40. /**
  41. * Create some sample incident data
  42. */
  43. protected function _run()
  44. {
  45. Fisma::setNotificationEnabled(false);
  46. Fisma::setListenerEnabled(false);
  47. $inMemoryConfig = new Fisma_Configuration_Array();
  48. Fisma::setConfiguration($inMemoryConfig, true);
  49. $configuration = Zend_Registry::get('doctrine_config');
  50. $numIncidents = $this->getOption('number');
  51. if (is_null($numIncidents)) {
  52. throw new Fisma_Zend_Exception_User("Number is a required argument.");
  53. return;
  54. }
  55. $incidents = array();
  56. // Some enumerations to randomly pick values from
  57. $reporterTitle = array('Mr.', 'Mrs.', 'Miss', 'Ms.');
  58. $timezones = Doctrine::getTable('Incident')->getEnumValues('incidentTimezone');
  59. $yesNo = array('YES', 'NO');
  60. $mobileMediaTypes = Doctrine::getTable('Incident')->getEnumValues('piiMobileMediaType');
  61. $hostOs = Doctrine::getTable('Incident')->getEnumValues('hostOs');
  62. $status = Doctrine::getTable('Incident')->getEnumValues('status');
  63. $resolutions = Doctrine::getTable('Incident')->getEnumValues('resolution');
  64. // Progress bar for console progress monitoring
  65. $generateProgressBar = $this->_getProgressBar($numIncidents);
  66. $generateProgressBar->update(0, "Generate Incidents");
  67. for ($i = 1; $i <= $numIncidents; $i++) {
  68. $oldDate = new Zend_Date();
  69. // Pick a random point in the last ~3 years
  70. $oldDate->setTimestamp(rand(time()-1e8, time()));
  71. $incident = array();
  72. $incident['reporterTitle'] = $reporterTitle[array_rand($reporterTitle)];
  73. $incident['reporterFirstName'] = 'John';
  74. $incident['reporterLastName'] = 'Doe';
  75. $incident['reporterOrganization'] = 'Acme, Inc.';
  76. $incident['reporterAddress1'] = rand(100, 9999) . ' Pennsylvania Ave.';
  77. $incident['reporterAddress2'] = 'Suite ' . rand (100, 999);
  78. $incident['reporterCity'] = 'Washington';
  79. $incident['reporterState'] = chr(rand(65, 90)) . chr(rand(65, 90));
  80. $incident['reporterZip'] = rand(10000, 99999);
  81. // PHP can't generate a random number greater than 2147483647, so concat a few numbers together to make a
  82. // phone number.
  83. $incident['reporterPhone'] = $this->_getRandomPhoneNumber();
  84. $incident['reporterFax'] = $this->_getRandomPhoneNumber();
  85. $incident['reporterEmail'] = 'john_doe@agency.gov';
  86. $incident['reporterIp'] = $this->_getRandomIpAddress();
  87. $incident['locationBuilding'] = "L'enfant Plaza";
  88. $incident['locationRoom'] = rand(100, 999);
  89. $incident['incidentDate'] = $oldDate->getDate()->toString(Fisma_Date::FORMAT_DATE);
  90. $incident['incidentTime'] = $oldDate->getDate()->toString(Fisma_Date::FORMAT_TIME);
  91. $incident['incidentTimezone'] = $timezones[array_rand($timezones)];
  92. // The reportTs will be anywhere from ~0-12 days after the incident date
  93. $oldDate->addTimestamp(rand(0, 1e6));
  94. $incident['reportTs'] = $oldDate->getDate()->toString(Fisma_Date::FORMAT_DATETIME);
  95. $incident['reportTz'] = $timezones[array_rand($timezones)];
  96. $incident['additionalInfo'] = Fisma_String::loremIpsum(rand(90, 100), 'html');
  97. $incident['piiInvolved'] = $yesNo[array_rand($yesNo)];
  98. $incident['piiAdditional'] = Fisma_String::loremIpsum(rand(90, 100), 'html');
  99. $incident['piiMobileMedia'] = $yesNo[array_rand($yesNo)];
  100. $incident['piiMobileMediaType'] = $mobileMediaTypes[array_rand($mobileMediaTypes)];
  101. $incident['piiEncrypted'] = $yesNo[array_rand($yesNo)];
  102. $incident['piiAuthoritiesContacted'] = $yesNo[array_rand($yesNo)];
  103. $incident['piiPoliceReport'] = $yesNo[array_rand($yesNo)];
  104. $incident['piiIndividualsCount'] = rand(1, 999999);
  105. $incident['piiIndividualsNotified'] = $yesNo[array_rand($yesNo)];
  106. $incident['piiShipment'] = $yesNo[array_rand($yesNo)];
  107. $incident['piiShipmentSenderContacted'] = $yesNo[array_rand($yesNo)];
  108. $incident['piiShipmentSenderCompany'] = ucwords(Fisma_String::loremIpsum(rand(1, 3)));
  109. $incident['piiShipmentTimeline'] = Fisma_String::loremIpsum(rand(90, 100), 'html');
  110. $incident['piiShipmentTrackingNumbers'] = Fisma_String::loremIpsum(rand(90, 100), 'html');
  111. $incident['hostIp'] = $this->_getRandomIpAddress();
  112. $incident['hostName'] = 'webprod04.agency.gov';
  113. $incident['hostOs'] = $hostOs[array_rand($hostOs)];
  114. $incident['hostAdditional'] = Fisma_String::loremIpsum(rand(40, 50), 'html');
  115. $incident['sourceIp'] = $this->_getRandomIpAddress();
  116. $incident['sourceAdditional'] = Fisma_String::loremIpsum(rand(40, 50), 'html');
  117. // Mischief. Randomly unset two fields. (Incident reports don't have required fields.)
  118. $nulls = array_rand($incident, 2);
  119. unset($incident[$nulls[0]]);
  120. unset($incident[$nulls[1]]);
  121. $incidents[] = $incident;
  122. unset($incident);
  123. $generateProgressBar->update($i);
  124. }
  125. print "\n";
  126. $saveProgressBar = $this->_getProgressBar($numIncidents);
  127. $saveProgressBar->update(0, "Save Incidents");
  128. $currentIncident = 0;
  129. try {
  130. Doctrine_Manager::connection()->beginTransaction();
  131. foreach ($incidents as $incident) {
  132. $i = new Incident();
  133. // 20% of the incidents have an attached artifact
  134. if (rand(1, 100) <= 20) {
  135. $i->Attachments[] = $this->_getSampleAttachment();
  136. }
  137. $i->merge($incident);
  138. $i->save();
  139. // 50% are reported by a real user, 50% reported by an anonymous user
  140. if (rand(1, 100) > 50) {
  141. $i->ReportingUser = $this->_getRandomUser();
  142. }
  143. $i->organizationId = $this->_getRandomOrganization()->id;
  144. $i->pocId = $this->_getRandomUser()->id;
  145. // Auto approve 80% of the incidents, reject 10%, and leave 10% alone
  146. $action = rand(1, 100);
  147. if ($action <= 80) {
  148. $i->categoryId = $this->_getRandomSubCategoryId();
  149. // Complete a random number of steps on this incident
  150. $stepsToComplete = rand(0, $i->Category->Workflow->Steps->count());
  151. while ($stepsToComplete--) {
  152. $i->completeStep("Step completed automatically by generate-incidents.php script.");
  153. }
  154. } elseif ($action <= 90) {
  155. $i->reject('Automatically rejected by generate-incidents.php script.');
  156. $i->save();
  157. }
  158. $i->free();
  159. unset($i);
  160. $currentIncident++;
  161. $saveProgressBar->update($currentIncident);
  162. }
  163. Doctrine_Manager::connection()->commit();
  164. } catch (Exception $e) {
  165. Doctrine_Manager::connection()->rollBack();
  166. throw $e;
  167. }
  168. print "\n";
  169. }
  170. /**
  171. * Return a random subcategory id
  172. *
  173. * @return int
  174. */
  175. protected function _getRandomSubCategoryId()
  176. {
  177. if (empty($this->_sampleSubCategories)) {
  178. // Get some subcategories
  179. $this->_sampleSubCategories = Doctrine_Query::create()
  180. ->from('IrSubCategory c')
  181. ->select('c.id')
  182. ->limit(50)
  183. ->setHydrationMode(Doctrine::HYDRATE_ARRAY)
  184. ->execute();
  185. if (0 == count($this->_sampleSubCategories)) {
  186. throw new Fisma_Exception("Cannot generate sample data because the application has no IR categories.");
  187. }
  188. }
  189. return $this->_sampleSubCategories[$this->_randomLog(0, count($this->_sampleSubCategories) - 1)]['id'];
  190. }
  191. }