GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (4873)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/common/backend/BackendSystem.class.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights reserved
4
 *
5
 * This file is a part of Codendi.
6
 *
7
 * Codendi is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * Codendi is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with Codendi. If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * 
21
 */
22
23
class BackendSystem extends Backend {
24
25
26
    protected $needRefreshUserCache = false;
27
    protected $needRefreshGroupCache = false;
28
29
30
    /**
31
     * Warn system that the user lists has been updated (new user)
32
     * This is required so that nscd (name service caching daemon) knows that it needs
33
     * to update its user data.
34
     *
35
     * NOTE: Don't need to update cache on deleted user since shadow information are not cached, 
36
     * so even if the cache is not refreshed, a deleted user won't be able to login
37
     * 
38
     * @return true on success, false otherwise
39
     */
40
    public function refreshUserCache() {
41
        return (system("/usr/sbin/nscd --invalidate=passwd") !== false);
42
    }
43
    
44
    /**
45
     * set if we need to refresh the user cache
46
     * 
47
     * @return null
48
     */
49
    public function setNeedRefreshUserCache() {
50
        $this->needRefreshUserCache = true;
51
    }
52
    
53
    /**
54
     * Return if we need to refresh the user cache
55
     * 
56
     * @return boolean
57
     */
58
    public function getNeedRefreshUserCache() {
59
        return $this->needRefreshUserCache;
60
    }
61
62
    /**
63
     * Warn system that the group lists has been updated (new group, new member to group or memeber removed from group)
64
     * This is required so that nscd (name service caching daemon) knows that it needs
65
     * to update its group data.
66
     *
67
     * NOTE: Currently, we don't update group cache on deleted group, new user and deleted user
68
     * 
69
     * @return true on success, false otherwise
70
     */
71
    public function refreshGroupCache() {
72
        return (system("/usr/sbin/nscd --invalidate=group") !== false);
73
    }
74
    
75
    /**
76
     * set if we need to refresh the group cache
77
     *
78
     * @return null
79
    */
80
    public function setNeedRefreshGroupCache() {
81
        $this->needRefreshGroupCache = true;
82
    }
83
84
    /**
85
     * Return if we need to refresh the groupo cache
86
     * 
87
     * @return boolean
88
     */
89
    public function getNeedRefreshGroupCache() {
90
        return $this->needRefreshGroupCache;
91
    }
92
93
    /**
94
     * Hard reset of system related stuff (nscd for uid/gid and fs cache).
95
     * 
96
     * Should be used before modification of system (new user, project, etc)
97
     * 
98
     * @return null
99
     */
100
    public function flushNscdAndFsCache() {
101
        $this->refreshGroupCache();
102
        $this->refreshUserCache();
103
        clearstatcache();
104
    }
105
    
106
    /**
107
     * Ensure user home directory is created and has the right uid
108
     * 
109
     * @param PFUser $user the user we want to sanitize his home
110
     * 
111
     * @return null
112
     */
113
    public function userHomeSanityCheck(PFUser $user) {
114
        if (!$this->userHomeExists($user->getUserName())) {
115
            $this->createUserHome($user);
116
        }
117
        if (!$this->isUserHomeOwnedByUser($user)) {
118
            $this->setUserHomeOwnership($user);
119
        }
120
    }
121
    
122
    /**
123
     * Create user home directory
124
     * 
125
     * Also copy files from the skel directory to the new home directory.
126
     * If the directory already exists, nothing is done.
127
     * 
128
     * @param PFUser $user the user we want to create a home
129
     * 
130
     * @return true if directory is successfully created, false otherwise
131
     */
132
    public function createUserHome(PFUser $user) {
133
        $homedir = $user->getUnixHomeDir();
134
135
        if (!is_dir($homedir)) {
136
            if (mkdir($homedir, 0751)) {
137
                // copy the contents of the $codendi_shell_skel dir into homedir
138
                if (is_dir($GLOBALS['codendi_shell_skel'])) {
139
                    system("cd " . $GLOBALS['codendi_shell_skel'] . "; tar cf - . | (cd  $homedir ; tar xf - )");
140
                }
141
                touch($homedir);
142
                $this->setUserHomeOwnership($user);
143
            } else {
144
                $this->log("Can't create user home: $homedir", Backend::LOG_ERROR);
145
                return false;
146
            }
147
        } else {
148
            $this->log("User home already exists: $homedir", Backend::LOG_WARNING);
149
        }
150
        return true;
151
    }
152
    
153
    /**
154
     * Verify if given name exists as user home directory
155
     * 
156
     * @param String $username the user name to test if home exists
157
     * 
158
     * @return boolean
159
     */
160
    public function userHomeExists($username) {
161
    	return (is_dir($GLOBALS['homedir_prefix']."/".$username));
162
    }
163
    
164
    /**
165
     * Verify is user home directory has the right uid
166
     * 
167
     * @param PFUser $user the user needed to verify his home directory
168
     * 
169
     * @return boolean
170
     */
171
    private function isUserHomeOwnedByUser(PFUser $user) {
172
        $stat = stat($user->getUnixHomeDir());
173
        if ($stat) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $stat of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
174
            if ($stat['uid'] != $user->getRealUnixUID()) {
175
                return false;
176
            }
177
        }
178
        return true;
179
    }
180
    
181
    /**
182
     * Set user's uid/gid on its home directory (recursively)
183
     * 
184
     * @param PFUser $user user to set uid/gid
185
     * 
186
     * @return null
187
     */
188
    private function setUserHomeOwnership(PFUser $user) {
189
        $this->recurseChownChgrp($user->getUnixHomeDir(), $user->getUserName(), $user->getUserName());
190
    }
191
    
192
    /**
193
     * Create project home directory
194
     * If the directory already exists, nothing is done.
195
     * 
196
     * @param int $group_id a group id
197
     * 
198
     * @return true if directory is successfully created, false otherwise
199
     */
200
    public function createProjectHome($group_id) {
201
        $project = $this->getProjectManager()->getProject($group_id);
202
        if (!$project) return false;
203
204
        $unix_group_name = $project->getUnixName(false); // May contain upper-case letters
205
        $projdir         = $GLOBALS['grpdir_prefix']."/".$unix_group_name;
206
        $ht_dir          = $projdir."/htdocs";
207
        $private_dir     = $projdir .'/private';
208
        $ftp_anon_dir    = $GLOBALS['ftp_anon_dir_prefix']."/".$unix_group_name;
209
        $ftp_frs_dir     = $GLOBALS['ftp_frs_dir_prefix']."/".$unix_group_name;
210
211
        if (!is_dir($projdir)) {
212
        	// Lets create the group's homedir.
213
	        // (put the SGID sticky bit on all dir so that all files
214
	        // in there are owned by the project group and not
215
	        // the user own group
216
            // Moreover, we need to chmod after mkdir because the umask may not allow the precised mode
217
            if (mkdir($projdir,0775)) {
218
                $this->chown($projdir, "dummy");
219
                $this->chgrp($projdir, $unix_group_name);
220
                $this->chmod($projdir, 02775);
221
            } else {
222
                $this->log("Can't create project home: $projdir", Backend::LOG_ERROR);
223
                return false;
224
            }
225
        } else {
226
            // Get directory stat 
227
            $stat = stat("$projdir");
228
            if ($stat && $stat['gid'] != $project->getUnixGID()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $stat of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
229
                $this->log("Restoring ownership on project dir: $projdir", Backend::LOG_WARNING);
230
                $this->recurseChgrp($projdir,$unix_group_name);
231
            }
232
        }
233
234
        // /!\ Be careful not to lowercase the whole path as it will also modify
235
        // parents case and will lead to errors. Eg:
236
        // /Toto/home/groups/TestProj -> /toto/home/groups/testproj
237
        // instead of
238
        // /Toto/home/groups/TestProj -> /Toto/home/groups/testproj
239
        $lcProjectDir = $GLOBALS['grpdir_prefix']."/".$project->getUnixName(true);
240
        if ($projdir != $lcProjectDir) {
241
            $lcprojlnk = $lcProjectDir;
242
            if (!is_link($lcprojlnk)) {
243
                if (!symlink($projdir,$lcprojlnk)) {
244
                    $this->log("Can't create project link: $lcprojlnk", Backend::LOG_ERROR);
245
                }
246
            }
247
        }
248
                
249
        if (!is_dir($ht_dir)) {
250
            // Project web site directory
251
            if (mkdir($ht_dir,0775)) {
252
                $this->chown($ht_dir, "dummy");
253
                $this->chgrp($ht_dir, $unix_group_name);
254
                chmod($ht_dir, 02775);
255
256
                // Copy custom homepage template for project web site if any
257
                $custom_homepage = $GLOBALS['sys_custom_incdir']."/en_US/others/default_page.php";
258
                $default_homepage = $GLOBALS['sys_incdir']."/en_US/others/default_page.php";
259
                $dest_homepage = $ht_dir."/index.php";
260
                if (is_file($custom_homepage)) {
261
                    copy($custom_homepage,$dest_homepage);
262
                } else if (is_file($default_homepage)) {
263
                    copy($default_homepage,$dest_homepage);
264
                }
265
                if (is_file($dest_homepage)) {
266
                    $this->chown($dest_homepage, "dummy");
267
                    $this->chgrp($dest_homepage, $unix_group_name);
268
                    chmod($dest_homepage,0644);
269
                }
270
271
            } else {
272
                $this->log("Can't create project web root: $ht_dir", Backend::LOG_ERROR);
273
                return false;
274
            }
275
        }
276
277
        if (!is_dir($ftp_anon_dir)) {
278
            // Now lets create the group's ftp homedir for anonymous ftp space
279
            // This one must be owned by the project gid so that all project
280
            // admins can work on it (upload, delete, etc...)
281
            if (mkdir($ftp_anon_dir, 02775)) {
282
                $this->chown($ftp_anon_dir, "dummy");
283
                $this->chgrp($ftp_anon_dir, $unix_group_name);
284
                chmod($ftp_anon_dir, 02775);
285
            } else {
286
                $this->log("Can't create project public ftp dir: $ftp_anon_dir", Backend::LOG_ERROR);
287
                return false;
288
            }
289
        }
290
        
291
        if (!is_dir($ftp_frs_dir)) {
292
            // Now lets create the group's ftp homedir for anonymous ftp space
293
            // This one must be owned by the project gid so that all project
294
            // admins can work on it (upload, delete, etc...)
295
            if (mkdir($ftp_frs_dir,0771)) {
296
                chmod($ftp_frs_dir, 0771);
297
                $this->chown($ftp_frs_dir, "dummy");
298
                $this->chgrp($ftp_frs_dir, $unix_group_name);
299
            } else {
300
                $this->log("Can't create project file release dir: $ftp_frs_dir", Backend::LOG_ERROR);
301
                return false;
302
            }
303
        }
304
        
305
        if (!is_dir($private_dir)) {
306
            if (mkdir($private_dir,0770)) {
307
                $this->chmod($private_dir, 02770);
308
                $this->chown($private_dir, "dummy");
309
                $this->chgrp($private_dir, $unix_group_name);
310
            } else {
311
                $this->log("Can't create project private dir: $private_dir", Backend::LOG_ERROR);
312
                return false;
313
            }
314
        } else {
315
            // Check that perms are OK
316
            $perms = fileperms($private_dir);
317
            // 'others' should have no right on the repository
318
            if (($perms & 0x0004) || ($perms & 0x0002) || ($perms & 0x0001) || ($perms & 0x0200)) {
319
            	$this->chmod($private_dir, 02770);		
320
            }
321
            // Get directory stat 
322
            $stat = stat("$private_dir");
323
            if ($stat) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $stat of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
324
                $dummy_user = posix_getpwnam('dummy');
325
                if ( ($stat['uid'] != $dummy_user['uid'])
326
                     || ($stat['gid'] != $project->getUnixGID()) ) {
327
                    $this->log("Restoring privacy on private dir: $private_dir", Backend::LOG_WARNING);
328
                    $this->chown($private_dir, "dummy");
329
                    $this->chgrp($private_dir, $unix_group_name);
330
                }
331
            }
332
        }
333
        return true;
334
    }
335
336
    /**
337
     * Archive the user home directory
338
     * 
339
     * @param int $user_id a user id needed to find the home dir to archive
340
     * 
341
     * @return true if directory is successfully archived, false otherwise
342
     */
343
    public function archiveUserHome($user_id) {
344
        $user=$this->getUserManager()->getUserById($user_id);
345
        if (!$user) return false;
346
        $homedir=$GLOBALS['homedir_prefix']."/".$user->getUserName();
347
        $backupfile=ForgeConfig::get('sys_project_backup_path')."/".$user->getUserName().".tgz";
348
349
        if (is_dir($homedir)) {
350
            system("cd ".$GLOBALS['homedir_prefix']."; tar cfz $backupfile ".$user->getUserName());
351
            chmod($backupfile,0600);
352
            $this->recurseDeleteInDir($homedir);
353
            rmdir($homedir);
354
        }
355
        return true;
356
357
    }
358
359
360
    /**
361
     * Archive the project directory
362
     * 
363
     * @param int $group_id the group id used to find the home directory to archive 
364
     * 
365
     * @return true if directory is successfully archived, false otherwise
366
     */
367
    public function archiveProjectHome($group_id) {
368
        $project=$this->getProjectManager()->getProject($group_id);
369
        if (!$project) return false;
370
        $mydir=$GLOBALS['grpdir_prefix']."/".$project->getUnixName(false);
371
        $backupfile=ForgeConfig::get('sys_project_backup_path')."/".$project->getUnixName(false).".tgz";
372
373
        if (is_dir($mydir)) {
374
            system("cd ".$GLOBALS['grpdir_prefix']."; tar cfz $backupfile ".$project->getUnixName(false));
375
            chmod($backupfile,0600);
376
            $this->recurseDeleteInDir($mydir);
377
            rmdir($mydir);
378
379
380
            // Remove lower-case symlink if it exists
381
            if ($project->getUnixName(true) != $project->getUnixName(false)) {
382
                if (is_link($GLOBALS['grpdir_prefix']."/".$project->getUnixName(true))) {
383
                    unlink($GLOBALS['grpdir_prefix']."/".$project->getUnixName(true));
384
                }
385
            }
386
        }
387
        return true;
388
    }
389
390
    /**
391
     * Archive ftp elements for a given project.
392
     * It would delete FTP directory content of the project
393
     * and create a Tarball in temp dir.
394
     *
395
     * @param Integer $group_id the group id
396
     *
397
     * @return boolean
398
     */
399
    function archiveProjectFtp($group_id) {
400
        $project = $this->getProjectManager()->getProject($group_id);
401
        if (!$project) {
402
            return false;
403
        }
404
        $anonymousFTP = $GLOBALS['ftp_anon_dir_prefix']."/".$project->getUnixName(false);
405
        $backupfile   = ForgeConfig::get('sys_project_backup_path')."/".$project->getUnixName(false)."-ftp.tgz";
406
        if (is_dir($anonymousFTP)) {
407
            system("cd ".$GLOBALS['ftp_anon_dir_prefix']."; tar cfz $backupfile ".$project->getUnixName(false));
408
            chmod($backupfile, 0600);
409
            $this->recurseDeleteInDir($anonymousFTP);
410
        }
411
        return true;
412
    }
413
414
    /**
415
     * Remove deleted releases and released files
416
     * 
417
     * @return bool the status
418
     */
419
    public function cleanupFRS() {
420
        // Purge all deleted files older than 3 days old
421
        if (!isset($GLOBALS['sys_file_deletion_delay'])) {
422
            $delay = 3;
423
        } else {
424
            $delay = intval($GLOBALS['sys_file_deletion_delay']);
425
        }
426
        $time = $_SERVER['REQUEST_TIME'] - (3600*24*$delay);
427
        
428
        $frs = $this->getFRSFileFactory();
429
        $status =  $frs->moveFiles($time, $this);
430
        // {{{ /!\ WARNING HACK /!\
431
        // We keep the good old purge mecanism for at least one release to clean
432
        // the previously deleted files
433
        // Delete all files under DELETE that are older than 10 days
434
        //$delete_dir = $GLOBALS['ftp_frs_dir_prefix']."/DELETED";
435
        //system("find $delete_dir -type f -mtime +10 -exec rm {} \\;");
436
        //system("find $delete_dir -mindepth 1 -type d -empty -exec rm -R {} \\;");
437
        // }}} /!\ WARNING HACK /!\
438
439
        //Manage the purge of wiki attachments
440
        $wiki   = $this->getWikiAttachment();
441
        $status = $status && $wiki->purgeAttachments($time);
442
443
        $em = EventManager::instance();
444
        $em->processEvent('backend_system_purge_files', array('time' => $time));
445
446
        return ($status);
447
    }
448
449
    /**
450
     * dumps SSH authorized_keys into all users homedirs
451
     * 
452
     * @return boolean always true
453
     */
454
    public function dumpSSHKeys() {
455
        $sshkey_dumper = new User_SSHKeyDumper($this);
456
        $user_manager  = $this->getUserManager();
457
        foreach($user_manager->getUsersWithSshKey() as $user) {
458
            $sshkey_dumper->writeSSHKeys($user);
459
        }
460
        EventManager::instance()->processEvent(Event::DUMP_SSH_KEYS, array());
461
        return true;
462
    }
463
    
464
    /**
465
     * dumps SSH authorized_keys for a user in its homedir
466
     * 
467
     * @param PFUser $user the user we want to dump his key
468
     * @param string $original_keys the original keys of the user
469
     * 
470
     * @return boolean if the ssh key was written
471
     */
472
    public function dumpSSHKeysForUser(PFUser $user, $original_keys) {
473
        $sshkey_dumper = new User_SSHKeyDumper($this);
474
        return $sshkey_dumper->writeSSHKeys($user);
475
    }
476
477
    /**
478
     * Check if repository of given project exists
479
     * 
480
     * @param Project $project project to test if home exist
481
     * 
482
     * @return true is repository already exists, false otherwise
483
     */
484
    public function projectHomeExists($project) {
485
        $unix_group_name = $project->getUnixName(false); // May contain upper-case letters
486
        $home_dir=$GLOBALS['grpdir_prefix']."/".$unix_group_name;
487
        if (is_dir($home_dir)) {
488
            return true;
489
        } else return false; 
490
    }
491
492
    /**
493
     * Check if given name is not used by a repository or a file or a link under project directories
494
     * 
495
     * Return false if repository or file  or link already exists:
496
     **  with the same name under the grp_dir
497
     **  with its lower case name under the grp_dir 
498
     **  under FRS
499
     **  under ftp anon 
500
     * true otherwise
501
     * 
502
     * @param String $name the project name to test
503
     * 
504
     * @return boolean 
505
     */
506
    public function isProjectNameAvailable($name) {
507
        $dir = $GLOBALS['grpdir_prefix']."/".$name;
508
        $frs = $GLOBALS['ftp_frs_dir_prefix']."/".$name;
509
        $ftp = $GLOBALS['ftp_anon_dir_prefix']."/".$name;
510
        
511
        if ($this->fileExists($dir)) {
512
            return false;
513
        } else if ($name != strtolower ($name)) {
514
            $link = $GLOBALS['grpdir_prefix']."/".strtolower($name);
515
            if ($this->fileExists($link)) {
516
                return false;
517
            }
518
        }
519
        if ($this->fileExists($frs)) {
520
            return false;
521
        } else if ($this->fileExists($ftp)) {
522
            return false;
523
        }
524
        return true;
525
    }
526
    
527
    /**
528
     * Check if given name is not used by a repository or a file or a link under user directory
529
     * 
530
     * @param String $name a user name to test availability
531
     * 
532
     * @return boolean false if repository or file  or link already exists, true otherwise
533
     */
534
    function isUserNameAvailable($name) {
535
        $path = $GLOBALS['homedir_prefix']."/".$name;
536
        return (!$this->fileExists($path));
537
    }
538
    
539
    
540
    /**
541
     * Rename project home directory (following project unix_name change)
542
     * 
543
     * @param Project $project a project to rename
544
     * @param String  $newName the new name of the project
545
     * 
546
     * @return boolean
547
     */
548
    public function renameProjectHomeDirectory($project, $newName) {
549
        if (is_link($GLOBALS['grpdir_prefix'].'/'.$newName)) {
550
            unlink($GLOBALS['grpdir_prefix'].'/'.$newName);
551
            return rename($GLOBALS['grpdir_prefix'].'/'.$project->getUnixName(false), $GLOBALS['grpdir_prefix'].'/'.$newName);
552
        } else {
553
            $renamed = rename($GLOBALS['grpdir_prefix'].'/'.$project->getUnixName(false), $GLOBALS['grpdir_prefix'].'/'.$newName);
554
            if ($renamed) {
555
                if (is_link($GLOBALS['grpdir_prefix'].'/'.$project->getUnixName(true))) {
556
                    unlink($GLOBALS['grpdir_prefix'].'/'.$project->getUnixName(true));
557
                }
558
                if (strtolower($newName) != $newName) {
559
                    return symlink($GLOBALS['grpdir_prefix'].'/'.$newName,$GLOBALS['grpdir_prefix'].'/'.strtolower($newName));
560
                } else {
561
                    return true;
562
                }
563
            }
564
            return $renamed;
565
        }
566
    }
567
    
568
    /**
569
     * Rename Directory where the released files are located (following project unix_name change)
570
     * 
571
     * @param Project $project a project
572
     * @param String  $newName a new name
573
     * 
574
     * @return boolean
575
     */
576
    public function renameFileReleasedDirectory($project, $newName) {
577
        if (is_dir($GLOBALS['ftp_frs_dir_prefix'].'/'.$project->getUnixName(false))) {
578
            return rename($GLOBALS['ftp_frs_dir_prefix'].'/'.$project->getUnixName(false), $GLOBALS['ftp_frs_dir_prefix'].'/'.$newName);
579
        } else {
580
            return true;
581
        }
582
    }
583
    
584
    /**
585
     * Rename anon ftp project homedir (following project unix_name change)
586
     * 
587
     * @param Project $project a project
588
     * @param String  $newName a new name
589
     * 
590
     * @return boolean
591
     */
592
    public function renameAnonFtpDirectory($project, $newName) {
593
        if (is_dir($GLOBALS['ftp_anon_dir_prefix'].'/'.$project->getUnixName(false))){
594
            return rename($GLOBALS['ftp_anon_dir_prefix'].'/'.$project->getUnixName(false), $GLOBALS['ftp_anon_dir_prefix'].'/'.$newName);
595
        } else {
596
            return true;
597
        }
598
    }
599
    
600
    /**
601
     * Rename User home directory 
602
     * 
603
     * @param PFUser    $user    a user
604
     * @param String  $newName the new name of user home directory
605
     * 
606
     * @return boolean
607
     */
608
    public function renameUserHomeDirectory($user, $newName) {
609
        return rename($GLOBALS['homedir_prefix'].'/'.$user->getUserName(), $GLOBALS['homedir_prefix'].'/'.$newName);
610
    }
611
    
612
    /**
613
     * Wrapper for getFRSFileFactory
614
     * 
615
     * @return FRSFileFactory
616
     */
617
    protected function getFRSFileFactory() {
618
        return new FRSFileFactory();
619
    }
620
621
    /**
622
     * Wrapper for getWikiAttachment
623
     * 
624
     * @return WikiAttachment
625
     */
626
    protected function getWikiAttachment() {
627
        return new WikiAttachment();
628
    }
629
    
630
631
}
632
633
?>
634