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 'trackeradmin'=>array('0','2'),
42 'tracker'=>array('-1','0','1','2','3'),
43 'pmadmin'=>array('0','2'),
44 'pm'=>array('-1','0','1','2','3'),
45 'webcal'=>array('0','1','2'));
51 * Role($group,$id) - CONSTRUCTOR.
53 * @param object The Group object.
54 * @param int The role_id.
56 function Role ($Group,$role_id=false) {
57 # Initialize the default group settings
58 if ($GLOBALS['default_roles']) {
59 $this->defaults=$GLOBALS['default_roles'];
61 $this->defaults=array(
62 'Admin'=>array( 'projectadmin'=>'A', 'frs'=>'1', 'scm'=>'1', 'docman'=>'1', 'forumadmin'=>'2', 'forum'=>'2', 'trackeradmin'=>'2', 'tracker'=>'2', 'pmadmin'=>'2', 'pm'=>'2', 'webcal'=>'1' ),
63 'Senior Developer'=>array( 'projectadmin'=>'0', 'frs'=>'1', 'scm'=>'1', 'docman'=>'1', 'forumadmin'=>'2', 'forum'=>'2', 'trackeradmin'=>'2', 'tracker'=>'2', 'pmadmin'=>'2', 'pm'=>'2', 'webcal'=>'2' ),
64 'Junior Developer'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'1', 'docman'=>'0', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'1', 'pmadmin'=>'0', 'pm'=>'1', 'webcal'=>'2' ),
65 'Doc Writer'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'0', 'docman'=>'1', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'0', 'pmadmin'=>'0', 'pm'=>'0' , 'webcal'=>'2'),
66 'Support Tech'=>array( 'projectadmin'=>'0', 'frs'=>'0', 'scm'=>'0', 'docman'=>'1', 'forumadmin'=>'0', 'forum'=>'1', 'trackeradmin'=>'0', 'tracker'=>'2', 'pmadmin'=>'0', 'pm'=>'0' , 'webcal'=>'2')
72 if (!$Group || !is_object($Group) || $Group->isError()) {
73 $this->setError('Role::'.$Group->getErrorMessage());
76 $this->Group =& $Group;
78 $hook_params = array ();
79 $hook_params['role'] =& $this;
80 plugin_hook ("role_get", $hook_params);
84 //setting up an empty object
85 //probably going to call create()
88 return $this->fetchData($role_id);
92 * getID - get the ID of this role.
94 * @return integer The ID Number.
97 return $this->data_array['role_id'];
101 * getName - get the name of this role.
103 * @return string The name of this role.
106 return $this->data_array['role_name'];
110 * create - create a new role in the database.
112 * @param string The name of the role.
113 * @param array A multi-dimensional array of data in this format: $data['section_name']['ref_id']=$val
114 * @return integer The id on success or false on failure.
116 function create($role_name,$data) {
117 $perm =& $this->Group->getPermission( session_get_user() );
118 if (!$perm || !is_object($perm) || $perm->isError() || !$perm->isAdmin()) {
119 $this->setPermissionDeniedError();
123 // Check if role_name is not already used.
124 $res = db_query_params('SELECT role_name FROM role WHERE group_id=$1 AND role_name=$2',
125 array ($this->Group->getID(), htmlspecialchars($role_name)));
126 if (db_numrows($res)) {
127 $this->setError('Cannot create a role with this name (already used)');
132 $res = db_query_params ('INSERT INTO role (group_id, role_name) VALUES ($1, $2)',
133 array ($this->Group->getID(),
134 htmlspecialchars($role_name))) ;
136 $this->setError('create::'.db_error());
140 $role_id=db_insertid($res,'role','role_id');
142 $this->setError('create::db_insertid::'.db_error());
147 $arr1 = array_keys($data);
148 for ($i=0; $i<count($arr1); $i++) {
149 // array_values($Report->adjust_days)
150 $arr2 = array_keys($data[$arr1[$i]]);
151 for ($j=0; $j<count($arr2); $j++) {
152 $usection_name=$arr1[$i];
154 $uvalue=$data[$arr1[$i]][$arr2[$j]];
161 $res = db_query_params ('INSERT INTO role_setting (role_id,section_name,ref_id,value) VALUES ($1,$2,$3,$4)',
167 $this->setError('create::insertsetting::'.db_error());
173 if (!$this->fetchData($role_id)) {
181 function createDefault($name) {
182 //echo '<html><body><pre>';
184 //print_r($this->defaults);
185 $arr =& $this->defaults[$name];
186 $keys = array_keys($arr);
193 for ($i=0; $i<count($keys); $i++) {
195 if ($keys[$i] == 'forum') {
196 $res = db_query_params ('SELECT group_forum_id FROM forum_group_list WHERE group_id=$1',
197 array ($this->Group->getID())) ;
199 $this->setError('Error: Forum'.db_error());
202 for ($j=0; $j<db_numrows($res); $j++) {
203 $data[$keys[$i]][db_result($res,$j,'group_forum_id')]= $arr[$keys[$i]];
205 } elseif ($keys[$i] == 'pm') {
206 $res = db_query_params ('SELECT group_project_id FROM project_group_list WHERE group_id=$1',
207 array ($this->Group->getID())) ;
209 $this->setError('Error: TaskMgr'.db_error());
212 for ($j=0; $j<db_numrows($res); $j++) {
213 $data[$keys[$i]][db_result($res,$j,'group_project_id')]= $arr[$keys[$i]];
215 } elseif ($keys[$i] == 'tracker') {
216 $res = db_query_params ('SELECT group_artifact_id FROM artifact_group_list WHERE group_id=$1',
217 array ($this->Group->getID())) ;
219 $this->setError('Error: Tracker'.db_error());
222 for ($j=0; $j<db_numrows($res); $j++) {
223 $data[$keys[$i]][db_result($res,$j,'group_artifact_id')]= $arr[$keys[$i]];
226 $data[$keys[$i]][0]= $arr[$keys[$i]];
232 return $this->create($name,$data);
236 * fetchData - May need to refresh database fields.
238 * If an update occurred and you need to access the updated info.
240 * @return boolean success;
242 function fetchData($role_id) {
243 unset($this->data_array);
244 unset($this->setting_array);
245 $res = db_query_params ('SELECT * FROM role WHERE role_id=$1',
247 if (!$res || db_numrows($res) < 1) {
248 $this->setError('Role::fetchData()::'.db_error());
251 $this->data_array =& db_fetch_array($res);
252 $res = db_query_params ('SELECT * FROM role_setting WHERE role_id=$1',
255 $this->setError('Role::fetchData()::'.db_error());
258 $this->setting_array=array();
259 while ($arr =& db_fetch_array($res)) {
260 $this->setting_array[$arr['section_name']][$arr['ref_id']] = $arr['value'];
266 * &getRoleVals - get all the values and language text strings for this section.
268 * @return array Assoc array of values for this section.
270 function &getRoleVals($section) {
271 global $role_vals, $rbac_permission_names;
272 setup_rbac_strings () ;
275 // Optimization - save array so it is only built once per page view
277 if (!isset($role_vals[$section])) {
279 for ($i=0; $i<count($this->role_values[$section]); $i++) {
281 // Build an associative array of these key values + localized description
283 $role_vals[$section][$this->role_values[$section][$i]]=$rbac_permission_names["$section".$this->role_values[$section][$i]];
286 return $role_vals[$section];
290 * getVal - get a value out of the array of settings for this role.
292 * @param string The name of the role.
293 * @param integer The ref_id (ex: group_artifact_id, group_forum_id) for this item.
294 * @return integer The value of this item.
296 function getVal($section,$ref_id) {
297 global $role_default_array;
301 if (array_key_exists ($section, $this->setting_array)) {
302 return $this->setting_array[$section][$ref_id];
308 function setVal($section, $ref_id, $value) {
309 $this->setting_array[$section][$ref_id] = $value;
310 return $this->update( $this->getName(), $this->setting_array);
314 * delVal - delete a value out of the array of settings for this role.
316 * @param string The name of the role.
317 * @param integer The ref_id (ex: group_artifact_id, group_forum_id) for this item.
319 function delVal($section, $ref_id) {
320 unset($this->setting_array[$section][$ref_id]);
322 $sql = 'DELETE FROM role_setting
326 $res=db_query_params($sql, array($this->getID(), $section, $ref_id));
327 if (!$res || db_affected_rows($res) < 1) {
328 $this->setError('delVal($section, $ref_id)'.db_error());
335 * update - update a new in the database.
337 * @param string The name of the role.
338 * @param array A multi-dimensional array of data in this format: $data['section_name']['ref_id']=$val
339 * @return boolean True on success or false on failure.
341 function update($role_name,$data) {
344 // Cannot update role_id=1
346 if ($this->getID() == 1) {
347 $this->setError('Cannot Update Default Role');
350 $perm =& $this->Group->getPermission( session_get_user() );
351 if (!$perm || !is_object($perm) || $perm->isError() || !$perm->isAdmin()) {
352 $this->setPermissionDeniedError();
358 if ($this->getName() != stripslashes($role_name)) {
359 // Check if role_name is not already used.
360 $res = db_query_params('SELECT role_name FROM role WHERE group_id=$1 AND role_name=$2',
361 array ($this->Group->getID(), htmlspecialchars($role_name)));
362 if (db_numrows($res)) {
363 $this->setError('Cannot create a role with this name (already used)');
368 $res = db_query_params ('UPDATE role SET role_name=$1 WHERE group_id=$2 AND role_id=$3',
369 array (htmlspecialchars($role_name),
370 $this->Group->getID(),
372 if (!$res || db_affected_rows($res) < 1) {
373 $this->setError('update::name::'.db_error());
378 ////$data['section_name']['ref_id']=$val
379 $arr1 = array_keys($data);
380 for ($i=0; $i<count($arr1); $i++) {
381 // array_values($Report->adjust_days)
382 $arr2 = array_keys($data[$arr1[$i]]);
383 for ($j=0; $j<count($arr2); $j++) {
384 $usection_name=$arr1[$i];
386 $uvalue=$data[$usection_name][$uref_id];
394 // See if this setting changed. If so, then update it
396 // if ($this->getVal($usection_name,$uref_id) != $uvalue) {
397 $res = db_query_params ('UPDATE role_setting SET value=$1 WHERE role_id=$2 AND section_name=$3 AND ref_id=$4',
402 if (!$res || db_affected_rows($res) < 1) {
403 $res = db_query_params ('INSERT INTO role_setting (role_id, section_name, ref_id, value) VALUES ($1, $2, $3, $4)',
404 array ($this->getID(),
409 $this->setError('update::rolesettinginsert::'.db_error());
414 if ($usection_name == 'frs') {
415 $update_usergroup=true;
416 } elseif ($usection_name == 'scm') {
417 //$update_usergroup=true;
419 //iterate all users with this role
420 $res = db_query_params ('SELECT user_id FROM user_group WHERE role_id=$1',
421 array ($this->getID())) ;
422 for ($z=0; $z<db_numrows($res); $z++) {
424 //TODO - Shell should be separate flag
425 // If user acquired admin access to CVS,
426 // one to be given normal shell on CVS machine,
427 // else - restricted.
429 $cvs_flags=$data['scm'][0];
430 $res2 = db_query_params ('UPDATE user_group SET cvs_flags=$1 WHERE user_id=$2',
432 db_result($res,$z,'user_id')));
434 $this->setError('update::scm::'.db_error());
438 // I have doubt the following is usefull
439 // This is probably buggy if used
441 if (!$SYS->sysUserSetAttribute(db_result($res,$z,'user_id'),"debGforgeCvsShell","/bin/bash")) {
442 $this->setError($SYS->getErrorMessage());
447 if (!$SYS->sysUserSetAttribute(db_result($res,$z,'user_id'),"debGforgeCvsShell","/bin/cvssh")) {
448 $this->setError($SYS->getErrorMessage());
455 // If user acquired at least commit access to CVS,
456 // one to be promoted to CVS group, else, demoted.
459 if (!$SYS->sysGroupAddUser($this->Group->getID(),db_result($res,$z,'user_id'),1)) {
460 $this->setError($SYS->getErrorMessage());
465 if (!$SYS->sysGroupRemoveUser($this->Group->getID(),db_result($res,$z,'user_id'),1)) {
466 $this->setError($SYS->getErrorMessage());
474 } elseif ($usection_name == 'docman') {
475 $update_usergroup=true;
476 } elseif ($usection_name == 'forumadmin') {
477 $update_usergroup=true;
478 } elseif ($usection_name == 'trackeradmin') {
479 $update_usergroup=true;
480 } elseif ($usection_name == 'projectadmin') {
481 $update_usergroup=true;
482 } elseif ($usection_name == 'pmadmin') {
483 $update_usergroup=true;
488 // if ($update_usergroup) {
489 $keys = array ('forumadmin', 'pmadmin', 'trackeradmin', 'docman', 'scm', 'frs', 'projectadmin') ;
490 foreach ($keys as $k) {
491 if (!array_key_exists ($k, $data)) {
492 $data[$k] = array(0);
495 $res = db_query_params ('UPDATE user_group
504 array ($data['projectadmin'][0],
505 $data['forumadmin'][0],
510 $data['trackeradmin'][0],
513 $this->setError('::update::usergroup::'.db_error());
520 $hook_params = array ();
521 $hook_params['role'] =& $this;
522 $hook_params['role_id'] = $this->getID();
523 $hook_params['data'] = $data;
524 plugin_hook ("role_update", $hook_params);
528 $this->fetchData($this->getID());
532 function setUser($user_id) {
534 $perm =& $this->Group->getPermission( session_get_user() );
535 if (!$perm || !is_object($perm) || $perm->isError() || !$perm->isAdmin()) {
536 $this->setPermissionDeniedError();
543 // See if role is actually changing
545 $res = db_query_params ('SELECT role_id FROM user_group WHERE user_id=$1 AND group_id=$2',
547 $this->Group->getID())) ;
548 $old_roleid=db_result($res,0,0);
549 if ($this->getID() == $old_roleid) {
554 // Get the old role so we can compare new values to old
556 $oldrole= new Role($this->Group,$old_roleid);
557 if (!$oldrole || !is_object($oldrole) || $oldrole->isError()) {
558 $this->setError($oldrole->getErrorMessage());
564 // Iterate each setting to see if it's changing
565 // If not, no sense updating it
567 $arr1 = array_keys($this->setting_array);
568 for ($i=0; $i<count($arr1); $i++) {
569 // array_values($Report->adjust_days)
570 $arr2 = array_keys($this->setting_array[$arr1[$i]]);
571 for ($j=0; $j<count($arr2); $j++) {
572 $usection_name=$arr1[$i];
574 $uvalue=$this->setting_array[$usection_name][$uref_id];
582 // See if this setting changed. If so, then update it
584 // if (($this->getVal($usection_name,$uref_id) != $oldrole->getVal($usection_name,$uref_id)) || ($old_roleid == 1)) {
585 if ($usection_name == 'frs') {
586 $update_usergroup=true;
587 } elseif ($usection_name == 'scm') {
588 //TODO - Shell should be separate flag
589 // If user acquired admin access to CVS,
590 // one to be given normal shell on CVS machine,
591 // else - restricted.
593 $cvs_flags=$this->getVal('scm',0);
594 $res2 = db_query_params ('UPDATE user_group SET cvs_flags=$1 WHERE user_id=$2 AND group_id=$3',
597 $this->Group->getID())) ;
599 $this->setError('update::scm::'.db_error());
603 // I have doubt the following is usefull
604 // This is probably buggy if used
606 if (!$SYS->sysUserSetAttribute($user_id,"debGforgeCvsShell","/bin/bash")) {
607 $this->setError($SYS->getErrorMessage());
612 if (!$SYS->sysUserSetAttribute($user_id,"debGforgeCvsShell","/bin/cvssh")) {
613 $this->setError($SYS->getErrorMessage());
620 // If user acquired at least commit access to CVS,
621 // one to be promoted to CVS group, else, demoted.
622 // When we add the user we also check he has a shell as a group member
623 // When we remove we only check for SCM (cvs_only=1)
626 //echo "<h3>Role::setUser SYS->sysGroupAddUser(".$this->Group->getID().",$user_id,1)</h3>";
627 if (!$SYS->sysGroupAddUser($this->Group->getID(),$user_id,0)) {
628 $this->setError($SYS->getErrorMessage());
633 //echo "<h3>Role::setUser SYS->sysGroupRemoveUser(".$this->Group->getID().",$user_id,1)</h3>";
634 if (!$SYS->sysGroupRemoveUser($this->Group->getID(),$user_id,1)) {
635 $this->setError($SYS->getErrorMessage());
641 } elseif ($usection_name == 'docman') {
642 $update_usergroup=true;
643 } elseif ($usection_name == 'forumadmin') {
644 $update_usergroup=true;
645 } elseif ($usection_name == 'trackeradmin') {
646 $update_usergroup=true;
647 } elseif ($usection_name == 'projectadmin') {
648 $update_usergroup=true;
649 } elseif ($usection_name == 'pmadmin') {
650 $update_usergroup=true;
655 // if ($update_usergroup) {
656 $res = db_query_params ('UPDATE user_group
665 WHERE user_id=$9 AND group_id=$10',
666 array ($this->getVal('projectadmin',0),
667 $this->getVal('forumadmin',0),
668 $this->getVal('pmadmin',0),
669 $this->getVal('docman',0),
670 $this->getVal('scm',0),
671 $this->getVal('frs',0),
672 $this->getVal('trackeradmin',0),
675 $this->Group->getID()));
677 $this->setError('::update::usergroup::'.db_error());
684 $hook_params = array ();
685 $hook_params['role'] =& $this;
686 $hook_params['role_id'] = $this->getID();
687 $hook_params['user_id'] = $user_id;
688 plugin_hook ("role_setuser", $hook_params);
700 // c-file-style: "bsd"