module.itop-profiles-itil.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. <?php
  2. // Copyright (C) 2010 Combodo SARL
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; version 3 of the License.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. SetupWebPage::AddModule(
  17. __FILE__, // Path to the current file, all other file names are relative to the directory containing this file
  18. 'itop-profiles-itil/1.0.0',
  19. array(
  20. // Identification
  21. //
  22. 'label' => 'Create standard ITIL profiles',
  23. 'category' => 'create_profiles',
  24. // Setup
  25. //
  26. 'dependencies' => array(
  27. ),
  28. 'mandatory' => true,
  29. 'visible' => false,
  30. 'installer' => 'CreateITILProfilesInstaller',
  31. // Components
  32. //
  33. 'datamodel' => array(
  34. //'model.itop-profiles-itil.php',
  35. ),
  36. 'webservice' => array(
  37. //'webservices.itop-profiles-itil.php',
  38. ),
  39. 'dictionary' => array(
  40. //'en.dict.itop-profiles-itil.php',
  41. //'fr.dict.itop-profiles-itil.php',
  42. //'de.dict.itop-profiles-itil.php',
  43. ),
  44. 'data.struct' => array(
  45. //'data.struct.itop-profiles-itil.xml',
  46. ),
  47. 'data.sample' => array(
  48. //'data.sample.itop-profiles-itil.xml',
  49. ),
  50. // Documentation
  51. //
  52. 'doc.manual_setup' => '',
  53. 'doc.more_information' => '',
  54. // Default settings
  55. //
  56. 'settings' => array(
  57. //'some_setting' => 'some value',
  58. ),
  59. )
  60. );
  61. // Module installation handler
  62. //
  63. class CreateITILProfilesInstaller extends ModuleInstallerAPI
  64. {
  65. public static function BeforeWritingConfig(Config $oConfiguration)
  66. {
  67. //$oConfiguration->SetModuleSetting('user-rigths-profile', 'myoption', 'myvalue');
  68. return $oConfiguration;
  69. }
  70. public static function AfterDatabaseCreation(Config $oConfiguration)
  71. {
  72. self::ComputeITILProfiles();
  73. //self::ComputeBasicProfiles();
  74. self::DoCreateProfiles();
  75. UserRights::FlushPrivileges(true /* reset admin cache */);
  76. }
  77. protected static $m_aActions = array(
  78. UR_ACTION_READ => 'Read',
  79. UR_ACTION_MODIFY => 'Modify',
  80. UR_ACTION_DELETE => 'Delete',
  81. UR_ACTION_BULK_READ => 'Bulk Read',
  82. UR_ACTION_BULK_MODIFY => 'Bulk Modify',
  83. UR_ACTION_BULK_DELETE => 'Bulk Delete',
  84. );
  85. // Note: It is possible to specify the same class in several modules
  86. //
  87. protected static $m_aModules = array();
  88. protected static $m_aProfiles = array();
  89. protected static function DoCreateActionGrant($iProfile, $iAction, $sClass, $bPermission = true)
  90. {
  91. $oNewObj = MetaModel::NewObject("URP_ActionGrant");
  92. $oNewObj->Set('profileid', $iProfile);
  93. $oNewObj->Set('permission', $bPermission ? 'yes' : 'no');
  94. $oNewObj->Set('class', $sClass);
  95. $oNewObj->Set('action', self::$m_aActions[$iAction]);
  96. $iId = $oNewObj->DBInsertNoReload();
  97. return $iId;
  98. }
  99. protected static function DoCreateStimulusGrant($iProfile, $sStimulusCode, $sClass)
  100. {
  101. $oNewObj = MetaModel::NewObject("URP_StimulusGrant");
  102. $oNewObj->Set('profileid', $iProfile);
  103. $oNewObj->Set('permission', 'yes');
  104. $oNewObj->Set('class', $sClass);
  105. $oNewObj->Set('stimulus', $sStimulusCode);
  106. $iId = $oNewObj->DBInsertNoReload();
  107. return $iId;
  108. }
  109. protected static function DoCreateOneProfile($sName, $aProfileData)
  110. {
  111. $sDescription = $aProfileData['description'];
  112. if (strlen(trim($aProfileData['write_modules'])) == 0)
  113. {
  114. $aWriteModules = array();
  115. }
  116. else
  117. {
  118. $aWriteModules = explode(',', trim($aProfileData['write_modules']));
  119. }
  120. if (strlen(trim($aProfileData['delete_modules'])) == 0)
  121. {
  122. $aDeleteModules = array();
  123. }
  124. else
  125. {
  126. $aDeleteModules = explode(',', trim($aProfileData['delete_modules']));
  127. }
  128. $aStimuli = $aProfileData['stimuli'];
  129. $oNewObj = MetaModel::NewObject("URP_Profiles");
  130. $oNewObj->Set('name', $sName);
  131. $oNewObj->Set('description', $sDescription);
  132. $iProfile = $oNewObj->DBInsertNoReload();
  133. // Grant read rights for everything
  134. //
  135. // Warning: BulkInsert is working because we will load one single class
  136. // having one single table !
  137. // the benefit is: 10 queries (1 per profile) instead of 1500
  138. // which divides the overall user rights setup process by 2
  139. DBObject::BulkInsertStart();
  140. foreach (MetaModel::GetClasses('bizmodel') as $sClass)
  141. {
  142. self::DoCreateActionGrant($iProfile, UR_ACTION_READ, $sClass);
  143. self::DoCreateActionGrant($iProfile, UR_ACTION_BULK_READ, $sClass);
  144. }
  145. DBObject::BulkInsertFlush();
  146. // Grant write for given modules
  147. // Start by compiling the information, because some modules may overlap
  148. $aWriteableClasses = array();
  149. foreach ($aWriteModules as $sModule)
  150. {
  151. //$oPage->p('Granting write access for the module"'.$sModule.'" - '.count(self::$m_aModules[$sModule]).' classes');
  152. foreach (self::$m_aModules[$sModule] as $sClass)
  153. {
  154. $aWriteableClasses[$sClass] = true;
  155. }
  156. }
  157. foreach ($aWriteableClasses as $sClass => $foo)
  158. {
  159. if (!MetaModel::IsValidClass($sClass))
  160. {
  161. throw new CoreException("Invalid class name '$sClass'");
  162. }
  163. self::DoCreateActionGrant($iProfile, UR_ACTION_MODIFY, $sClass);
  164. self::DoCreateActionGrant($iProfile, UR_ACTION_BULK_MODIFY, $sClass);
  165. }
  166. // Grant delete for given modules
  167. // Start by compiling the information, because some modules may overlap
  168. $aDeletableClasses = array();
  169. foreach ($aDeleteModules as $sModule)
  170. {
  171. //$oPage->p('Granting delete access for the module"'.$sModule.'" - '.count(self::$m_aModules[$sModule]).' classes');
  172. foreach (self::$m_aModules[$sModule] as $sClass)
  173. {
  174. $aDeletableClasses[$sClass] = true;
  175. }
  176. }
  177. foreach ($aDeletableClasses as $sClass => $foo)
  178. {
  179. if (!MetaModel::IsValidClass($sClass))
  180. {
  181. throw new CoreException("Invalid class name '$sClass'");
  182. }
  183. self::DoCreateActionGrant($iProfile, UR_ACTION_DELETE, $sClass);
  184. // By default, do not allow bulk deletion operations for standard users
  185. // self::DoCreateActionGrant($iProfile, UR_ACTION_BULK_DELETE, $sClass);
  186. }
  187. // Grant stimuli for given classes
  188. foreach ($aStimuli as $sClass => $sAllowedStimuli)
  189. {
  190. if (!MetaModel::IsValidClass($sClass))
  191. {
  192. // Could be a class defined in a module that wasn't installed
  193. continue;
  194. //throw new CoreException("Invalid class name '$sClass'");
  195. }
  196. if ($sAllowedStimuli == 'any')
  197. {
  198. $aAllowedStimuli = array_keys(MetaModel::EnumStimuli($sClass));
  199. }
  200. elseif ($sAllowedStimuli == 'none')
  201. {
  202. $aAllowedStimuli = array();
  203. }
  204. else
  205. {
  206. $aAllowedStimuli = explode(',', $sAllowedStimuli);
  207. }
  208. foreach ($aAllowedStimuli as $sStimulusCode)
  209. {
  210. self::DoCreateStimulusGrant($iProfile, $sStimulusCode, $sClass);
  211. }
  212. }
  213. }
  214. public static function DoCreateProfiles()
  215. {
  216. URP_Profiles::DoCreateAdminProfile();
  217. URP_Profiles::DoCreateUserPortalProfile();
  218. foreach(self::$m_aProfiles as $sName => $aProfileData)
  219. {
  220. self::DoCreateOneProfile($sName, $aProfileData);
  221. }
  222. }
  223. public static function ComputeBasicProfiles()
  224. {
  225. // In this profiling scheme, one single module represents all the classes
  226. //
  227. self::$m_aModules = array(
  228. 'UserData' => MetaModel::GetClasses('bizmodel'),
  229. );
  230. self::$m_aProfiles = array(
  231. 'Reader' => array(
  232. 'description' => 'Person having a ready-only access to the data',
  233. 'write_modules' => '',
  234. 'delete_modules' => '',
  235. 'stimuli' => array(
  236. ),
  237. ),
  238. 'Writer' => array(
  239. 'description' => 'Contributor to the contents (read + write access)',
  240. 'write_modules' => 'UserData',
  241. 'delete_modules' => 'UserData',
  242. 'stimuli' => array(
  243. // any class => 'any'
  244. ),
  245. ),
  246. );
  247. }
  248. public static function ComputeITILProfiles()
  249. {
  250. // In this profiling scheme, modules are based on ITIL recommendations
  251. //
  252. self::$m_aModules = array(
  253. 'General' => MetaModel::GetClasses('structure'),
  254. 'Documentation' => MetaModel::GetClasses('documentation'),
  255. 'Configuration' => MetaModel::GetClasses('configmgmt'),
  256. 'Incident' => MetaModel::GetClasses('incidentmgmt'),
  257. 'Problem' => MetaModel::GetClasses('problemmgmt'),
  258. 'Change' => MetaModel::GetClasses('changemgmt'),
  259. 'Service' => MetaModel::GetClasses('servicemgmt'),
  260. 'Call' => MetaModel::GetClasses('requestmgmt'),
  261. 'KnownError' => MetaModel::GetClasses('knownerrormgmt'),
  262. );
  263. self::$m_aProfiles = array(
  264. 'Configuration Manager' => array(
  265. 'description' => 'Person in charge of the documentation of the managed CIs',
  266. 'write_modules' => 'General,Documentation,Configuration',
  267. 'delete_modules' => 'General,Documentation,Configuration',
  268. 'stimuli' => array(
  269. //'Server' => 'none',
  270. //'Contract' => 'none',
  271. //'IncidentTicket' => 'none',
  272. //'ChangeTicket' => 'any',
  273. ),
  274. ),
  275. 'Service Desk Agent' => array(
  276. 'description' => 'Person in charge of creating incident reports',
  277. 'write_modules' => 'Incident,Call',
  278. 'delete_modules' => 'Incident,Call',
  279. 'stimuli' => array(
  280. 'Incident' => 'ev_assign',
  281. 'UserRequest' => 'ev_assign',
  282. ),
  283. ),
  284. 'Support Agent' => array(
  285. 'description' => 'Person analyzing and solving the current incidents',
  286. 'write_modules' => 'Incident',
  287. 'delete_modules' => 'Incident',
  288. 'stimuli' => array(
  289. 'Incident' => 'ev_assign,ev_reassign,ev_resolve,ev_close',
  290. 'UserRequest' => 'ev_assign,ev_reassign,ev_resolve,ev_close,ev_freeze',
  291. ),
  292. ),
  293. 'Problem Manager' => array(
  294. 'description' => 'Person analyzing and solving the current problems',
  295. 'write_modules' => 'Problem,KnownError',
  296. 'delete_modules' => 'Problem,KnownError',
  297. 'stimuli' => array(
  298. 'Problem' => 'ev_assign,ev_reassign,ev_resolve,ev_close',
  299. ),
  300. ),
  301. 'Change Implementor' => array(
  302. 'description' => 'Person executing the changes',
  303. 'write_modules' => 'Change',
  304. 'delete_modules' => 'Change',
  305. 'stimuli' => array(
  306. 'NormalChange' => 'ev_plan,ev_replan,ev_implement,ev_monitor',
  307. 'EmergencyChange' => 'ev_plan,ev_replan,ev_implement,ev_monitor',
  308. 'RoutineChange' => 'ev_plan,ev_replan,ev_implement,ev_monitor',
  309. ),
  310. ),
  311. 'Change Supervisor' => array(
  312. 'description' => 'Person responsible for the overall change execution',
  313. 'write_modules' => 'Change',
  314. 'delete_modules' => 'Change',
  315. 'stimuli' => array(
  316. 'NormalChange' => 'ev_validate,ev_reject,ev_assign,ev_reopen,ev_finish',
  317. 'EmergencyChange' => 'ev_assign,ev_reopen,ev_finish',
  318. 'RoutineChange' => 'ev_assign,ev_reopen,ev_finish',
  319. ),
  320. ),
  321. 'Change Approver' => array(
  322. 'description' => 'Person who could be impacted by some changes',
  323. 'write_modules' => 'Change',
  324. 'delete_modules' => 'Change',
  325. 'stimuli' => array(
  326. 'NormalChange' => 'ev_approve,ev_notapprove',
  327. 'EmergencyChange' => 'ev_approve,ev_notapprove',
  328. 'RoutineChange' => 'none',
  329. ),
  330. ),
  331. 'Service Manager' => array(
  332. 'description' => 'Person responsible for the service delivered to the [internal] customer',
  333. 'write_modules' => 'Service',
  334. 'delete_modules' => 'Service',
  335. 'stimuli' => array(
  336. ),
  337. ),
  338. 'Document author' => array(
  339. 'description' => 'Any person who could contribute to documentation',
  340. 'write_modules' => 'Documentation',
  341. 'delete_modules' => 'Documentation',
  342. 'stimuli' => array(
  343. ),
  344. ),
  345. );
  346. }
  347. }
  348. ?>