module.itop-profiles-itil.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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, $sPreviousVersion, $sCurrentVersion)
  71. {
  72. self::ComputeITILProfiles();
  73. //self::ComputeBasicProfiles();
  74. $bFirstInstall = empty($sPreviousVersion);
  75. self::DoCreateProfiles($bFirstInstall);
  76. UserRights::FlushPrivileges(true /* reset admin cache */);
  77. }
  78. // Note: It is possible to specify the same class in several modules
  79. //
  80. protected static $m_aModules = array();
  81. protected static $m_aProfiles = array();
  82. protected static function DoSetupProfile($sName, $aProfileData)
  83. {
  84. $sDescription = $aProfileData['description'];
  85. if (strlen(trim($aProfileData['write_modules'])) == 0)
  86. {
  87. $aWriteModules = array();
  88. }
  89. else
  90. {
  91. $aWriteModules = explode(',', trim($aProfileData['write_modules']));
  92. }
  93. if (strlen(trim($aProfileData['delete_modules'])) == 0)
  94. {
  95. $aDeleteModules = array();
  96. }
  97. else
  98. {
  99. $aDeleteModules = explode(',', trim($aProfileData['delete_modules']));
  100. }
  101. $aStimuli = $aProfileData['stimuli'];
  102. $iProfile = URP_Profiles::DoCreateProfile($sName, $sDescription);
  103. // Warning: BulkInsert is working because we will load one single class
  104. // having one single table !
  105. // the benefit is: 10 queries (1 per profile) instead of 1500
  106. // which divides the overall user rights setup process by 5
  107. DBObject::BulkInsertStart();
  108. // Grant read rights for everything
  109. //
  110. foreach (MetaModel::GetClasses('bizmodel') as $sClass)
  111. {
  112. URP_Profiles::DoCreateActionGrant($iProfile, UR_ACTION_READ, $sClass);
  113. URP_Profiles::DoCreateActionGrant($iProfile, UR_ACTION_BULK_READ, $sClass);
  114. }
  115. // Grant write for given modules
  116. // Start by compiling the information, because some modules may overlap
  117. $aWriteableClasses = array();
  118. foreach ($aWriteModules as $sModule)
  119. {
  120. //$oPage->p('Granting write access for the module"'.$sModule.'" - '.count(self::$m_aModules[$sModule]).' classes');
  121. foreach (self::$m_aModules[$sModule] as $sClass)
  122. {
  123. $aWriteableClasses[$sClass] = true;
  124. }
  125. }
  126. foreach ($aWriteableClasses as $sClass => $foo)
  127. {
  128. if (!MetaModel::IsValidClass($sClass))
  129. {
  130. throw new CoreException("Invalid class name '$sClass'");
  131. }
  132. URP_Profiles::DoCreateActionGrant($iProfile, UR_ACTION_MODIFY, $sClass);
  133. URP_Profiles::DoCreateActionGrant($iProfile, UR_ACTION_BULK_MODIFY, $sClass);
  134. }
  135. // Grant delete for given modules
  136. // Start by compiling the information, because some modules may overlap
  137. $aDeletableClasses = array();
  138. foreach ($aDeleteModules as $sModule)
  139. {
  140. //$oPage->p('Granting delete access for the module"'.$sModule.'" - '.count(self::$m_aModules[$sModule]).' classes');
  141. foreach (self::$m_aModules[$sModule] as $sClass)
  142. {
  143. $aDeletableClasses[$sClass] = true;
  144. }
  145. }
  146. foreach ($aDeletableClasses as $sClass => $foo)
  147. {
  148. if (!MetaModel::IsValidClass($sClass))
  149. {
  150. throw new CoreException("Invalid class name '$sClass'");
  151. }
  152. URP_Profiles::DoCreateActionGrant($iProfile, UR_ACTION_DELETE, $sClass);
  153. // By default, do not allow bulk deletion operations for standard users
  154. // URP_Profiles::DoCreateActionGrant($iProfile, UR_ACTION_BULK_DELETE, $sClass);
  155. }
  156. // Grant stimuli for given classes
  157. foreach ($aStimuli as $sClass => $sAllowedStimuli)
  158. {
  159. if (!MetaModel::IsValidClass($sClass))
  160. {
  161. // Could be a class defined in a module that wasn't installed
  162. continue;
  163. //throw new CoreException("Invalid class name '$sClass'");
  164. }
  165. if ($sAllowedStimuli == 'any')
  166. {
  167. $aAllowedStimuli = array_keys(MetaModel::EnumStimuli($sClass));
  168. }
  169. elseif ($sAllowedStimuli == 'none')
  170. {
  171. $aAllowedStimuli = array();
  172. }
  173. else
  174. {
  175. $aAllowedStimuli = explode(',', $sAllowedStimuli);
  176. }
  177. foreach ($aAllowedStimuli as $sStimulusCode)
  178. {
  179. URP_Profiles::DoCreateStimulusGrant($iProfile, $sStimulusCode, $sClass);
  180. }
  181. }
  182. // Again: this is working only because action/stimulus grant are classes made of a single table!
  183. DBObject::BulkInsertFlush();
  184. }
  185. /*
  186. * Create the built-in User Portal profile with its reserved name
  187. */
  188. public static function DoCreateUserPortalProfile()
  189. {
  190. $iNewId = URP_Profiles::DoCreateProfile(PORTAL_PROFILE_NAME, 'Has the rights to access to the user portal. People having this profile will not be allowed to access the standard application, they will be automatically redirected to the user portal.', true /* reserved name */);
  191. // Grant read rights for everything
  192. //
  193. foreach (MetaModel::GetClasses('bizmodel') as $sClass)
  194. {
  195. URP_Profiles::DoCreateActionGrant($iNewId, UR_ACTION_READ, $sClass);
  196. URP_Profiles::DoCreateActionGrant($iNewId, UR_ACTION_BULK_READ, $sClass);
  197. }
  198. // Can create UserRequests and attach Documents to it
  199. URP_Profiles::DoCreateActionGrant($iNewId, UR_ACTION_MODIFY, 'UserRequest');
  200. URP_Profiles::DoCreateActionGrant($iNewId, UR_ACTION_MODIFY, 'lnkTicketToDoc');
  201. URP_Profiles::DoCreateActionGrant($iNewId, UR_ACTION_DELETE, 'lnkTicketToDoc');
  202. URP_Profiles::DoCreateActionGrant($iNewId, UR_ACTION_MODIFY, 'FileDoc');
  203. // Can close user requests
  204. URP_Profiles::DoCreateStimulusGrant($iNewId, 'ev_close', 'UserRequest');
  205. }
  206. public static function DoCreateProfiles($bFirstInstall = true)
  207. {
  208. URP_Profiles::DoCreateAdminProfile(); // Will be created only if it does not exist
  209. self::DoCreateUserPortalProfile(); // Will be created only if it does not exist and updated otherwise
  210. foreach(self::$m_aProfiles as $sName => $aProfileData)
  211. {
  212. self::DoSetupProfile($sName, $aProfileData);
  213. }
  214. }
  215. public static function ComputeBasicProfiles()
  216. {
  217. // In this profiling scheme, one single module represents all the classes
  218. //
  219. self::$m_aModules = array(
  220. 'UserData' => MetaModel::GetClasses('bizmodel'),
  221. );
  222. self::$m_aProfiles = array(
  223. 'Reader' => array(
  224. 'description' => 'Person having a ready-only access to the data',
  225. 'write_modules' => '',
  226. 'delete_modules' => '',
  227. 'stimuli' => array(
  228. ),
  229. ),
  230. 'Writer' => array(
  231. 'description' => 'Contributor to the contents (read + write access)',
  232. 'write_modules' => 'UserData',
  233. 'delete_modules' => 'UserData',
  234. 'stimuli' => array(
  235. // any class => 'any'
  236. ),
  237. ),
  238. );
  239. }
  240. public static function ComputeITILProfiles()
  241. {
  242. // In this profiling scheme, modules are based on ITIL recommendations
  243. //
  244. self::$m_aModules = array(
  245. 'General' => MetaModel::GetClasses('structure'),
  246. 'Documentation' => MetaModel::GetClasses('documentation'),
  247. 'Configuration' => MetaModel::GetClasses('configmgmt'),
  248. 'Incident' => MetaModel::GetClasses('incidentmgmt'),
  249. 'Problem' => MetaModel::GetClasses('problemmgmt'),
  250. 'Change' => MetaModel::GetClasses('changemgmt'),
  251. 'Service' => MetaModel::GetClasses('servicemgmt'),
  252. 'Call' => MetaModel::GetClasses('requestmgmt'),
  253. 'KnownError' => MetaModel::GetClasses('knownerrormgmt'),
  254. 'LnkTickets' => MetaModel::GetClasses('lnkticket'),
  255. 'LnkIncidents' => MetaModel::GetClasses('lnkincident'),
  256. 'LnkServices' => MetaModel::GetClasses('lnkservice'),
  257. 'LnkKnownErrors' => MetaModel::GetClasses('lnkknownerror'),
  258. );
  259. self::$m_aProfiles = array(
  260. 'Configuration Manager' => array(
  261. 'description' => 'Person in charge of the documentation of the managed CIs',
  262. 'write_modules' => 'General,Documentation,Configuration',
  263. 'delete_modules' => 'General,Documentation,Configuration',
  264. 'stimuli' => array(
  265. //'Server' => 'none',
  266. //'Contract' => 'none',
  267. //'IncidentTicket' => 'none',
  268. //'ChangeTicket' => 'any',
  269. ),
  270. ),
  271. 'Service Desk Agent' => array(
  272. 'description' => 'Person in charge of creating incident reports',
  273. 'write_modules' => 'Incident,Call',
  274. 'delete_modules' => 'LnkTickets,LnkIncidents',
  275. 'stimuli' => array(
  276. 'Incident' => 'ev_assign',
  277. 'UserRequest' => 'ev_assign',
  278. ),
  279. ),
  280. 'Support Agent' => array(
  281. 'description' => 'Person analyzing and solving the current incidents',
  282. 'write_modules' => 'Incident',
  283. 'delete_modules' => 'LnkTickets,LnkIncidents',
  284. 'stimuli' => array(
  285. 'Incident' => 'ev_assign,ev_reassign,ev_resolve,ev_close',
  286. 'UserRequest' => 'ev_assign,ev_reassign,ev_resolve,ev_close,ev_freeze',
  287. ),
  288. ),
  289. 'Problem Manager' => array(
  290. 'description' => 'Person analyzing and solving the current problems',
  291. 'write_modules' => 'Problem,KnownError',
  292. 'delete_modules' => 'LnkTickets,LnkKnownErrors',
  293. 'stimuli' => array(
  294. 'Problem' => 'ev_assign,ev_reassign,ev_resolve,ev_close',
  295. ),
  296. ),
  297. 'Change Implementor' => array(
  298. 'description' => 'Person executing the changes',
  299. 'write_modules' => 'Change',
  300. 'delete_modules' => 'LnkTickets',
  301. 'stimuli' => array(
  302. 'NormalChange' => 'ev_plan,ev_replan,ev_implement,ev_monitor',
  303. 'EmergencyChange' => 'ev_plan,ev_replan,ev_implement,ev_monitor',
  304. 'RoutineChange' => 'ev_plan,ev_replan,ev_implement,ev_monitor',
  305. ),
  306. ),
  307. 'Change Supervisor' => array(
  308. 'description' => 'Person responsible for the overall change execution',
  309. 'write_modules' => 'Change',
  310. 'delete_modules' => 'LnkTickets',
  311. 'stimuli' => array(
  312. 'NormalChange' => 'ev_validate,ev_reject,ev_assign,ev_reopen,ev_finish',
  313. 'EmergencyChange' => 'ev_assign,ev_reopen,ev_finish',
  314. 'RoutineChange' => 'ev_assign,ev_reopen,ev_finish',
  315. ),
  316. ),
  317. 'Change Approver' => array(
  318. 'description' => 'Person who could be impacted by some changes',
  319. 'write_modules' => 'Change',
  320. 'delete_modules' => 'LnkTickets',
  321. 'stimuli' => array(
  322. 'NormalChange' => 'ev_approve,ev_notapprove',
  323. 'EmergencyChange' => 'ev_approve,ev_notapprove',
  324. 'RoutineChange' => 'none',
  325. ),
  326. ),
  327. 'Service Manager' => array(
  328. 'description' => 'Person responsible for the service delivered to the [internal] customer',
  329. 'write_modules' => 'Service',
  330. 'delete_modules' => 'LnkServices',
  331. 'stimuli' => array(
  332. ),
  333. ),
  334. 'Document author' => array(
  335. 'description' => 'Any person who could contribute to documentation',
  336. 'write_modules' => 'Documentation',
  337. 'delete_modules' => 'Documentation,LnkTickets',
  338. 'stimuli' => array(
  339. ),
  340. ),
  341. );
  342. }
  343. }
  344. ?>