5 * Copyright 2004, GForge, LLC
6 * Copyright 2009, Roland Mas
8 * This file is part of FusionForge.
10 * FusionForge is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published
12 * by the Free Software Foundation; either version 2 of the License,
13 * or (at your option) any later version.
15 * FusionForge is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with FusionForge; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 require_once $gfcommon.'include/rbac_texts.php' ;
28 class Role extends Error {
34 var $role_values=array(
35 'projectadmin'=>array('0','A'),
36 'frs'=>array('0','1'),
37 'scm'=>array('-1','0','1'),
38 'docman'=>array('0','1'),
39 'forumadmin'=>array('0','2'),
40 'forum'=>array('-1','0','1','2'),
41 'newforum'=>array('-1','0','1','2'),
42 'trackeradmin'=>array('0','2'),
43 'tracker'=>array('-1','0','1','2','3'),
44 'newtracker'=>array('-1','0','1','2','3'),
45 'pmadmin'=>array('0','2'),
46 'pm'=>array('-1','0','1','2','3'),
47 'newpm'=>array('-1','0','1','2','3'),
48 'webcal'=>array('0','1','2'));
53 * Role($group,$id) - CONSTRUCTOR.
55 * @param object The Group object.
56 * @param int The role_id.
58 function Role ($Group,$role_id=false) {
59 # Initialize the default group settings
60 if ($GLOBALS['default_roles']) {
61 $this->defaults=$GLOBALS['default_roles'];
63 $this->defaults=array(
64 'Admin'=>array( 'projectadmin'=>'A', 'frs'=>'1', 'scm'=>'1', 'docman'=>'1', 'forumadmin'=>'2', 'forum'=>'2', 'newforum'=>'2', 'trackeradmin'=>'2', 'tracker'=>'2', 'newtracker'=>'2', 'pmadmin'=>'2', 'pm'=>'2', 'newpm'=>'2', 'webcal'=>'1' ),
65 'Senior Developer'=>array( 'projectadmin'=>'0', 'frs'=>'1', 'scm'=>'1', 'docman'=>'1', 'forumadmin'=>'2', 'forum'=>'2', 'newforum'=>'2', 'trackeradmin'=>'2', 'tracker'=>'2', 'newtracker'=>'2', 'pmadmin'=>'2', 'pm'=>'2', 'newpm'=>'2', 'webcal'=>'2' ),
66 'Junior Developer'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'1', 'docman'=>'0', 'forumadmin'=>'0', 'forum'=>'1', 'newforum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'1', 'newtracker'=>'1', 'pmadmin'=>'0', 'pm'=>'1', 'newpm'=>'1', 'webcal'=>'2' ),
67 'Doc Writer'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'0', 'docman'=>'1', 'forumadmin'=>'0', 'forum'=>'1', 'newforum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'0', 'newtracker'=>'0', 'pmadmin'=>'0', 'pm'=>'0' , 'newpm'=>'0' , 'webcal'=>'2'),
68 'Support Tech'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'0', 'docman'=>'1', 'forumadmin'=>'0', 'forum'=>'1', 'newforum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'2', 'newtracker'=>'2', 'pmadmin'=>'0', 'pm'=>'0' , 'newpm'=>'0' , 'webcal'=>'2')
74 if (!$Group || !is_object($Group) || $Group->isError()) {
75 $this->setError('Role::'.$Group->getErrorMessage());
78 $this->Group =& $Group;
80 $hook_params = array ();
81 $hook_params['role'] =& $this;
82 plugin_hook ("role_get", $hook_params);
86 //setting up an empty object
87 //probably going to call create()
90 return $this->fetchData($role_id);
94 * getID - get the ID of this role.
96 * @return integer The ID Number.
99 return $this->data_array['role_id'];
103 * getName - get the name of this role.
105 * @return string The name of this role.
108 return $this->data_array['role_name'];
112 * create - create a new role in the database.
114 * @param string The name of the role.
115 * @param array A multi-dimensional array of data in this format: $data['section_name']['ref_id']=$val
116 * @return integer The id on success or false on failure.
118 function create($role_name,$data) {
119 $perm =& $this->Group->getPermission( session_get_user() );
120 if (!$perm || !is_object($perm) || $perm->isError() || !$perm->isAdmin()) {
121 $this->setPermissionDeniedError();
125 // Check if role_name is not already used.
126 $res = db_query_params('SELECT role_name FROM role WHERE group_id=$1 AND role_name=$2',
127 array ($this->Group->getID(), htmlspecialchars($role_name)));
128 if (db_numrows($res)) {
129 $this->setError('Cannot create a role with this name (already used)');
134 $res = db_query_params ('INSERT INTO role (group_id, role_name) VALUES ($1, $2)',
135 array ($this->Group->getID(),
136 htmlspecialchars($role_name))) ;
138 $this->setError('create::'.db_error());
142 $role_id=db_insertid($res,'role','role_id');
144 $this->setError('create::db_insertid::'.db_error());
149 $arr1 = array_keys($data);
150 for ($i=0; $i<count($arr1); $i++) {
151 // array_values($Report->adjust_days)
152 $arr2 = array_keys($data[$arr1[$i]]);
153 for ($j=0; $j<count($arr2); $j++) {
154 $usection_name=$arr1[$i];
156 $uvalue=$data[$arr1[$i]][$arr2[$j]];
163 $res = db_query_params ('INSERT INTO role_setting (role_id,section_name,ref_id,value) VALUES ($1,$2,$3,$4)',
169 $this->setError('create::insertsetting::'.db_error());
175 if (!$this->fetchData($role_id)) {
183 function createDefault($name) {
184 //echo '<html><body><pre>';
186 //print_r($this->defaults);
187 $arr =& $this->defaults[$name];
188 $keys = array_keys($arr);
195 for ($i=0; $i<count($keys); $i++) {
197 if ($keys[$i] == 'forum') {
198 $res = db_query_params ('SELECT group_forum_id FROM forum_group_list WHERE group_id=$1',
199 array ($this->Group->getID())) ;
201 $this->setError('Error: Forum'.db_error());
204 for ($j=0; $j<db_numrows($res); $j++) {
205 $data[$keys[$i]][db_result($res,$j,'group_forum_id')]= $arr[$keys[$i]];
207 } elseif ($keys[$i] == 'pm') {
208 $res = db_query_params ('SELECT group_project_id FROM project_group_list WHERE group_id=$1',
209 array ($this->Group->getID())) ;
211 $this->setError('Error: TaskMgr'.db_error());
214 for ($j=0; $j<db_numrows($res); $j++) {
215 $data[$keys[$i]][db_result($res,$j,'group_project_id')]= $arr[$keys[$i]];
217 } elseif ($keys[$i] == 'tracker') {
218 $res = db_query_params ('SELECT group_artifact_id FROM artifact_group_list WHERE group_id=$1',
219 array ($this->Group->getID())) ;
221 $this->setError('Error: Tracker'.db_error());
224 for ($j=0; $j<db_numrows($res); $j++) {
225 $data[$keys[$i]][db_result($res,$j,'group_artifact_id')]= $arr[$keys[$i]];
228 $data[$keys[$i]][0]= $arr[$keys[$i]];
234 return $this->create($name,$data);
238 * fetchData - May need to refresh database fields.
240 * If an update occurred and you need to access the updated info.
242 * @return boolean success;
244 function fetchData($role_id) {
245 unset($this->data_array);
246 unset($this->setting_array);
247 $res = db_query_params ('SELECT * FROM role WHERE role_id=$1',
249 if (!$res || db_numrows($res) < 1) {
250 $this->setError('Role::fetchData()::'.db_error());
253 $this->data_array =& db_fetch_array($res);
254 $res = db_query_params ('SELECT * FROM role_setting WHERE role_id=$1',
257 $this->setError('Role::fetchData()::'.db_error());
260 $this->setting_array=array();
261 while ($arr =& db_fetch_array($res)) {
262 $this->setting_array[$arr['section_name']][$arr['ref_id']] = $arr['value'];
268 * &getRoleVals - get all the values and language text strings for this section.
270 * @return array Assoc array of values for this section.
272 function &getRoleVals($section) {
273 global $role_vals, $rbac_permission_names;
274 setup_rbac_strings () ;
277 // Optimization - save array so it is only built once per page view
279 if (!isset($role_vals[$section])) {
281 for ($i=0; $i<count($this->role_values[$section]); $i++) {
283 // Build an associative array of these key values + localized description
285 $role_vals[$section][$this->role_values[$section][$i]]=$rbac_permission_names["$section".$this->role_values[$section][$i]];
288 return $role_vals[$section];
292 * getVal - get a value out of the array of settings for this role.
294 * @param string The name of the role.
295 * @param integer The ref_id (ex: group_artifact_id, group_forum_id) for this item.
296 * @return integer The value of this item.
298 function getVal($section,$ref_id) {
299 global $role_default_array;
303 if (array_key_exists ($section, $this->setting_array)) {
304 return $this->setting_array[$section][$ref_id];
310 function setVal($section, $ref_id, $value) {
311 $this->setting_array[$section][$ref_id] = $value;
312 return $this->update( $this->getName(), $this->setting_array);
316 * delVal - delete a value out of the array of settings for this role.
318 * @param string The name of the role.
319 * @param integer The ref_id (ex: group_artifact_id, group_forum_id) for this item.
321 function delVal($section, $ref_id) {
322 unset($this->setting_array[$section][$ref_id]);
324 $sql = 'DELETE FROM role_setting
328 $res=db_query_params($sql, array($this->getID(), $section, $ref_id));
329 if (!$res || db_affected_rows($res) < 1) {
330 $this->setError('delVal($section, $ref_id)'.db_error());
337 * update - update a new in the database.
339 * @param string The name of the role.
340 * @param array A multi-dimensional array of data in this format: $data['section_name']['ref_id']=$val
341 * @return boolean True on success or false on failure.
343 function update($role_name,$data) {
346 // Cannot update role_id=1
348 if ($this->getID() == 1) {
349 $this->setError('Cannot Update Default Role');
352 $perm =& $this->Group->getPermission( session_get_user() );
353 if (!$perm || !is_object($perm) || $perm->isError() || !$perm->isAdmin()) {
354 $this->setPermissionDeniedError();
360 if ($this->getName() != stripslashes($role_name)) {
361 // Check if role_name is not already used.
362 $res = db_query_params('SELECT role_name FROM role WHERE group_id=$1 AND role_name=$2',
363 array ($this->Group->getID(), htmlspecialchars($role_name)));
364 if (db_numrows($res)) {
365 $this->setError('Cannot create a role with this name (already used)');
370 $res = db_query_params ('UPDATE role SET role_name=$1 WHERE group_id=$2 AND role_id=$3',
371 array (htmlspecialchars($role_name),
372 $this->Group->getID(),
374 if (!$res || db_affected_rows($res) < 1) {
375 $this->setError('update::name::'.db_error());
380 ////$data['section_name']['ref_id']=$val
381 $arr1 = array_keys($data);
382 for ($i=0; $i<count($arr1); $i++) {
383 // array_values($Report->adjust_days)
384 $arr2 = array_keys($data[$arr1[$i]]);
385 for ($j=0; $j<count($arr2); $j++) {
386 $usection_name=$arr1[$i];
388 $uvalue=$data[$usection_name][$uref_id];
396 // See if this setting changed. If so, then update it
398 // if ($this->getVal($usection_name,$uref_id) != $uvalue) {
399 $res = db_query_params ('UPDATE role_setting SET value=$1 WHERE role_id=$2 AND section_name=$3 AND ref_id=$4',
404 if (!$res || db_affected_rows($res) < 1) {
405 $res = db_query_params ('INSERT INTO role_setting (role_id, section_name, ref_id, value) VALUES ($1, $2, $3, $4)',
406 array ($this->getID(),
411 $this->setError('update::rolesettinginsert::'.db_error());
416 if ($usection_name == 'frs') {
417 $update_usergroup=true;
418 } elseif ($usection_name == 'scm') {
419 //$update_usergroup=true;
421 //iterate all users with this role
422 $res = db_query_params ('SELECT user_id FROM user_group WHERE role_id=$1',
423 array ($this->getID())) ;
424 for ($z=0; $z<db_numrows($res); $z++) {
426 //TODO - Shell should be separate flag
427 // If user acquired admin access to CVS,
428 // one to be given normal shell on CVS machine,
429 // else - restricted.
431 $cvs_flags=$data['scm'][0];
432 $res2 = db_query_params ('UPDATE user_group SET cvs_flags=$1 WHERE user_id=$2',
434 db_result($res,$z,'user_id')));
436 $this->setError('update::scm::'.db_error());
440 // I have doubt the following is usefull
441 // This is probably buggy if used
443 if (!$SYS->sysUserSetAttribute(db_result($res,$z,'user_id'),"debGforgeCvsShell","/bin/bash")) {
444 $this->setError($SYS->getErrorMessage());
449 if (!$SYS->sysUserSetAttribute(db_result($res,$z,'user_id'),"debGforgeCvsShell","/bin/cvssh")) {
450 $this->setError($SYS->getErrorMessage());
457 // If user acquired at least commit access to CVS,
458 // one to be promoted to CVS group, else, demoted.
461 if (!$SYS->sysGroupAddUser($this->Group->getID(),db_result($res,$z,'user_id'),1)) {
462 $this->setError($SYS->getErrorMessage());
467 if (!$SYS->sysGroupRemoveUser($this->Group->getID(),db_result($res,$z,'user_id'),1)) {
468 $this->setError($SYS->getErrorMessage());
476 } elseif ($usection_name == 'docman') {
477 $update_usergroup=true;
478 } elseif ($usection_name == 'forumadmin') {
479 $update_usergroup=true;
480 } elseif ($usection_name == 'trackeradmin') {
481 $update_usergroup=true;
482 } elseif ($usection_name == 'projectadmin') {
483 $update_usergroup=true;
484 } elseif ($usection_name == 'pmadmin') {
485 $update_usergroup=true;
490 // if ($update_usergroup) {
491 $keys = array ('forumadmin', 'pmadmin', 'trackeradmin', 'docman', 'scm', 'frs', 'projectadmin') ;
492 foreach ($keys as $k) {
493 if (!array_key_exists ($k, $data)) {
494 $data[$k] = array(0);
497 $res = db_query_params ('UPDATE user_group
506 array ($data['projectadmin'][0],
507 $data['forumadmin'][0],
512 $data['trackeradmin'][0],
515 $this->setError('::update::usergroup::'.db_error());
522 $hook_params = array ();
523 $hook_params['role'] =& $this;
524 $hook_params['role_id'] = $this->getID();
525 $hook_params['data'] = $data;
526 plugin_hook ("role_update", $hook_params);
530 $this->fetchData($this->getID());
534 function setUser($user_id) {
536 $perm =& $this->Group->getPermission( session_get_user() );
537 if (!$perm || !is_object($perm) || $perm->isError() || !$perm->isAdmin()) {
538 $this->setPermissionDeniedError();
545 // See if role is actually changing
547 $res = db_query_params ('SELECT role_id FROM user_group WHERE user_id=$1 AND group_id=$2',
549 $this->Group->getID())) ;
550 $old_roleid=db_result($res,0,0);
551 if ($this->getID() == $old_roleid) {
556 // Get the old role so we can compare new values to old
558 $oldrole= new Role($this->Group,$old_roleid);
559 if (!$oldrole || !is_object($oldrole) || $oldrole->isError()) {
560 $this->setError($oldrole->getErrorMessage());
566 // Iterate each setting to see if it's changing
567 // If not, no sense updating it
569 $arr1 = array_keys($this->setting_array);
570 for ($i=0; $i<count($arr1); $i++) {
571 // array_values($Report->adjust_days)
572 $arr2 = array_keys($this->setting_array[$arr1[$i]]);
573 for ($j=0; $j<count($arr2); $j++) {
574 $usection_name=$arr1[$i];
576 $uvalue=$this->setting_array[$usection_name][$uref_id];
584 // See if this setting changed. If so, then update it
586 // if (($this->getVal($usection_name,$uref_id) != $oldrole->getVal($usection_name,$uref_id)) || ($old_roleid == 1)) {
587 if ($usection_name == 'frs') {
588 $update_usergroup=true;
589 } elseif ($usection_name == 'scm') {
590 //TODO - Shell should be separate flag
591 // If user acquired admin access to CVS,
592 // one to be given normal shell on CVS machine,
593 // else - restricted.
595 $cvs_flags=$this->getVal('scm',0);
596 $res2 = db_query_params ('UPDATE user_group SET cvs_flags=$1 WHERE user_id=$2 AND group_id=$3',
599 $this->Group->getID())) ;
601 $this->setError('update::scm::'.db_error());
605 // I have doubt the following is usefull
606 // This is probably buggy if used
608 if (!$SYS->sysUserSetAttribute($user_id,"debGforgeCvsShell","/bin/bash")) {
609 $this->setError($SYS->getErrorMessage());
614 if (!$SYS->sysUserSetAttribute($user_id,"debGforgeCvsShell","/bin/cvssh")) {
615 $this->setError($SYS->getErrorMessage());
622 // If user acquired at least commit access to CVS,
623 // one to be promoted to CVS group, else, demoted.
624 // When we add the user we also check he has a shell as a group member
625 // When we remove we only check for SCM (cvs_only=1)
628 //echo "<h3>Role::setUser SYS->sysGroupAddUser(".$this->Group->getID().",$user_id,1)</h3>";
629 if (!$SYS->sysGroupAddUser($this->Group->getID(),$user_id,0)) {
630 $this->setError($SYS->getErrorMessage());
635 //echo "<h3>Role::setUser SYS->sysGroupRemoveUser(".$this->Group->getID().",$user_id,1)</h3>";
636 if (!$SYS->sysGroupRemoveUser($this->Group->getID(),$user_id,1)) {
637 $this->setError($SYS->getErrorMessage());
643 } elseif ($usection_name == 'docman') {
644 $update_usergroup=true;
645 } elseif ($usection_name == 'forumadmin') {
646 $update_usergroup=true;
647 } elseif ($usection_name == 'trackeradmin') {
648 $update_usergroup=true;
649 } elseif ($usection_name == 'projectadmin') {
650 $update_usergroup=true;
651 } elseif ($usection_name == 'pmadmin') {
652 $update_usergroup=true;
657 // if ($update_usergroup) {
658 $res = db_query_params ('UPDATE user_group
667 WHERE user_id=$9 AND group_id=$10',
668 array ($this->getVal('projectadmin',0),
669 $this->getVal('forumadmin',0),
670 $this->getVal('pmadmin',0),
671 $this->getVal('docman',0),
672 $this->getVal('scm',0),
673 $this->getVal('frs',0),
674 $this->getVal('trackeradmin',0),
677 $this->Group->getID()));
679 $this->setError('::update::usergroup::'.db_error());
686 $hook_params = array ();
687 $hook_params['role'] =& $this;
688 $hook_params['role_id'] = $this->getID();
689 $hook_params['user_id'] = $user_id;
690 plugin_hook ("role_setuser", $hook_params);
702 // c-file-style: "bsd"