5effc2bd7685822df276c1372dab480cff321941
bernd First strike: list reposito...

bernd authored 12 years ago

1) <?php
Bernd Wurst Added license tags for CC0,...

Bernd Wurst authored 12 years ago

2) /*
3) This file belongs to the Webinterface of schokokeks.org Hosting
4) 
Bernd Wurst Lizenzinfos in eigenes Modu...

Bernd Wurst authored 10 years ago

5) Written 2008-2014 by schokokeks.org Hosting, namely
Bernd Wurst Added license tags for CC0,...

Bernd Wurst authored 12 years ago

6)   Bernd Wurst <bernd@schokokeks.org>
7)   Hanno Böck <hanno@schokokeks.org>
8) 
9) To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
10) 
11) You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see 
12) http://creativecommons.org/publicdomain/zero/1.0/
13) 
14) Nevertheless, in case you use a significant part of this code, we ask (but not require, see the license) that you keep the authors' names in place and return your changes to the public. We would be especially happy if you tell us what you're going to do with this code.
15) */
16) 
bernd First strike: list reposito...

bernd authored 12 years ago

17) require_role(ROLE_SYSTEMUSER);
18) 
19) $data_dir = realpath( dirname(__FILE__).'/../data/' );
20) $config_file = $data_dir.'/gitolite-admin/conf/webinterface.conf';
21) $config_dir = $data_dir.'/gitolite-admin/conf/webinterface';
22) $key_dir = $data_dir.'/gitolite-admin/keydir';
23) DEBUG("gitolite-data_dir: ".$data_dir);
24) $git_wrapper = $data_dir . '/git-wrapper.sh';
25) 
26) 
bernd Fürs erste feature-complete

bernd authored 12 years ago

27) 
bernd First strike: list reposito...

bernd authored 12 years ago

28) function check_env() 
29) {
30)   global $git_wrapper, $data_dir, $config_file, $config_dir, $key_dir;
31)   if (!is_executable($git_wrapper)) {
32)     system_failure("git_wrapper.sh is not executable: {$git_wrapper}");
33)   }
34)   if (! (is_file($data_dir.'/sshkey') && is_file($data_dir.'/sshkey.pub'))) {
35)     system_failure("SSH-key not found. Please setup the gitolite-module correctly. Run ./data/initialize.sh");
36)   }
37)   if (! is_dir($data_dir.'/gitolite-admin')) {
38)     system_failure("Repository gitolite-admin ot found. Initial checkout must be made manually. Run ./data/initialize.sh");
39)   }
40)   if (! is_dir($config_dir)) {
41)     system_failure("gitolite-admin repository is not prepared.");
42)   }
bernd First draft of gitolite-mod...

bernd authored 12 years ago

43)   if (! (is_dir($key_dir) && is_writeable($config_file))) {
bernd First strike: list reposito...

bernd authored 12 years ago

44)     system_failure("Repository gitolite-admin is corrupted or webinterface.conf is not writeable.");
45)   }
46) }
47) 
48) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

49) function validate_name($name) {
50)   return (preg_match('/^[[:alnum:]][[:alnum:]._-]*$/', $name));
51) }
52) 
bernd show URL

bernd authored 12 years ago

53) function get_git_url($repo) {
54)   $remote = git_wrapper('remote --verbose');
55)   DEBUG('gitolite-admin repo: '.$remote[0]);
56)   $url = preg_replace('#^.*\s+(\S+):gitolite-admin.*#', '$1', $remote[0]);
57)   DEBUG('URL: '.$url);
58)   return $url.':'.$repo;
59) }
60) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

61) 
bernd First strike: list reposito...

bernd authored 12 years ago

62) function git_wrapper($commandline)
63) {
64)   global $git_wrapper, $data_dir;
65) 
66)   $command = $git_wrapper.' '.$commandline;
67)   $output = array();
68)   $retval = 0;
69)   DEBUG($command);
70)   exec($command, $output, $retval);
71)   DEBUG($output);
72)   DEBUG($retval);
73)   if ($retval > 0) {
74)     system_failure('Interner Fehler!');
75)     // FIXME: Hier sollte auf jeden Fall ein Logging angeworfen werden!
76)   }
bernd show URL

bernd authored 12 years ago

77)   return $output;
bernd First strike: list reposito...

bernd authored 12 years ago

78) }
79) 
80) function refresh_gitolite() 
81) {
82)   check_env();
83)   git_wrapper('pull');
84) }
85) 
86) 
87) 
88) function list_repos() 
89) {
90)   global $config_file, $config_dir;
91)   $username = $_SESSION['userinfo']['username'];
92)   $userconfig = $config_dir . '/' . $username . '.conf';
93)   DEBUG("using config file ".$userconfig);
94)   if (! is_file($userconfig)) {
95)     DEBUG("user-config does not exist");
96)     return array();
97)   }
98) 
99)   $repos = array();
100)   $lines = file($userconfig);
101)   $current_repo = NULL;
bernd First draft of gitolite-mod...

bernd authored 12 years ago

102)   $current_repo_users = array();
bernd First strike: list reposito...

bernd authored 12 years ago

103)   foreach ($lines as $line) {
bernd Fürs erste feature-complete

bernd authored 12 years ago

104)     DEBUG("LINE: ".$line);
bernd First strike: list reposito...

bernd authored 12 years ago

105)     $m = array();
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

106)     if (preg_match('/^(\S+) "[^"]+" = "([^"]+)"$/', $line, $m) != 0) {
107)       if (!array_key_exists($m[1], $repos)) {
108)         $repos[$m[1]] = array('users' => NULL, 'description' => '');
109)       }
110)       DEBUG("found description: {$m[1]} = \"{$m[2]}\"");
111)       $repos[$m[1]]['description'] = $m[2];
112)     } elseif (preg_match('_^\s*repo (\S+)\s*$_', $line, $m) != 0) {
113)       if (!array_key_exists($m[1], $repos)) {
114)         $repos[$m[1]] = array('users' => NULL, 'description' => '');
115)       }
bernd First draft of gitolite-mod...

bernd authored 12 years ago

116)       if ($current_repo) {
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

117)         $repos[$current_repo]['users'] = $current_repo_users;
bernd First draft of gitolite-mod...

bernd authored 12 years ago

118)       }
bernd First strike: list reposito...

bernd authored 12 years ago

119)       DEBUG("found repo ".$m[1]);
bernd First draft of gitolite-mod...

bernd authored 12 years ago

120)       $current_repo = chop($m[1]);
121)       $current_repo_users = array();
bernd Fürs erste feature-complete

bernd authored 12 years ago

122)     } else if (preg_match('/^\s*(R|RW|RW\+)\s*=\s*([[:alnum:]][[:alnum:]._-]*)\s*$/', $line, $m) != 0) {
bernd First draft of gitolite-mod...

bernd authored 12 years ago

123)       DEBUG("found access rule: ".$m[1]." for ".$m[2]);
124)       $current_repo_users[chop($m[2])] = chop($m[1]);
bernd First strike: list reposito...

bernd authored 12 years ago

125)     }
126)   }
bernd First draft of gitolite-mod...

bernd authored 12 years ago

127)   if ($current_repo) {
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

128)     $repos[$current_repo]['users'] = $current_repo_users;
bernd First draft of gitolite-mod...

bernd authored 12 years ago

129)   }
bernd Sortiere Repositories und U...

bernd authored 12 years ago

130)   ksort($repos);
bernd First strike: list reposito...

bernd authored 12 years ago

131)   DEBUG($repos);
132)   return $repos;
133) }
134) 
135) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

136) function list_users() {
137)   global $config_file, $config_dir;
138)   $username = $_SESSION['userinfo']['username'];
139)   $userconfig = $config_dir . '/' . $username . '.conf';
140)   DEBUG("using config file ".$userconfig);
141)   if (! is_file($userconfig)) {
142)     DEBUG("user-config does not exist");
143)     return array();
144)   }
145)   
146)   $lines = file($userconfig);
147)   $users = array();
148)   foreach ($lines as $line) {
149)     $m = array();
150)     if (preg_match('_# user ([^]]+)_', $line, $m) != 0) {
151)       $users[] = chop($m[1]);
152)     }
153)     if (preg_match('_^\s*repo .*_', $line) != 0) {
154)       break;
155)     }
156)   }
bernd Sortiere Repositories und U...

bernd authored 12 years ago

157)   sort($users);
bernd First draft of gitolite-mod...

bernd authored 12 years ago

158)   DEBUG($users);
159)   return $users;
160) }
bernd First strike: list reposito...

bernd authored 12 years ago

161) 
Bernd Wurst add foreign git users and g...

Bernd Wurst authored 12 years ago

162) function list_foreign_users() {
163)   global $config_file, $config_dir;
164)   $username = $_SESSION['userinfo']['username'];
165)   $userconfig = $config_dir . '/' . $username . '.conf';
166)   DEBUG("using config file ".$userconfig);
167)   if (! is_file($userconfig)) {
168)     DEBUG("user-config does not exist");
169)     return array();
170)   }
171)   
172)   $lines = file($userconfig);
173)   $users = array();
174)   foreach ($lines as $line) {
175)     $m = array();
176)     if (preg_match('_# foreign user ([^]]+)_', $line, $m) != 0) {
177)       $users[] = chop($m[1]);
178)     }
179)     if (preg_match('_^\s*repo .*_', $line) != 0) {
180)       break;
181)     }
182)   }
183)   sort($users);
184)   DEBUG($users);
185)   return $users;
186) }
187) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

188) function get_pubkey($handle) {
189)   global $key_dir;
190)   if (! validate_name($handle)) {
191)     return '';
192)   }
193)   $keyfile = $key_dir.'/'.$handle.'.pub';
194)   if (! file_exists($keyfile)) {
195)     return '';
196)   }
197)   return file_get_contents($keyfile);
198) }
199) 
200) 
201) 
Bernd Wurst add foreign git users and g...

Bernd Wurst authored 12 years ago

202) function new_foreign_user($handle) 
203) {
204)   global $key_dir, $config_dir;
205)   $username = $_SESSION['userinfo']['username'];
206) 
207)   if (! validate_name($handle)) {
208)     system_failure("Der eingegebene Name enthält ungültige Zeichen. Bitte nur Buchstaben, Zahlen, Unterstrich, Binderstrich und Punkt benutzen.");
209)   }
210) 
211)   if (in_array($handle, list_users())) {
212)     system_failure('Dieser GIT-Benutzer gehört zu diesem Kundenaccount.');
213)   }
214) 
215)   $keyfile = $key_dir.'/'.$handle.'.pub';
216)   if (! file_exists($keyfile) ) {
217)     system_failure('Diesen GIT-Benutzer gibt es nicht');
218)   }
219) 
220)   $userconfig = $config_dir . '/' . $username . '.conf';
221)   DEBUG("using config file ".$userconfig);
222)   if (! is_file($userconfig)) {
223)     DEBUG("user-config does not exist, creating new one");
224)     file_put_contents($userconfig, '# user '.$handle."\n");
225)     set_user_include();
226)   } elseif (in_array($handle, list_foreign_users())) {
227)     # user ist schon eingetragen
228)   } else {
229)     $content = file_get_contents($userconfig);
230)     file_put_contents($userconfig, "# foreign user {$handle}\n".$content);
231)   }
232)   git_wrapper('add '.$userconfig);
233) 
234)   git_wrapper('commit --allow-empty -m "added new key for '.$handle.'"');
235)   git_wrapper('push');
236) }
237) 
238) function delete_foreign_user($handle)
239) {
240)   global $config_dir;
241)   $username = $_SESSION['userinfo']['username'];
242) 
243)   $userconfig = $config_dir . '/' . $username . '.conf';
244)   DEBUG("using config file ".$userconfig);
245)   if (! is_file($userconfig)) {
246)     DEBUG("user-config does not exist, wtf?");
247)     system_failure("Es gibt für diesen Benutzer noch keine Konfiguration. Das sollte nicht sein!");
248)   } else {
249)     $content = file($userconfig);
250)     DEBUG("Old file:");
251)     DEBUG($content);
252)     $newcontent = array();
253)     foreach ($content as $line) {
254)       if (preg_match('/^# foreign user '.$handle.'$/', $line)) {
255)         DEBUG("delete1: ".$line);
256)         continue;
257)       }
258)       if (preg_match('/^\s*(R|RW|RW+)\s*=\s*'.$handle.'\s*$/', $line)) {
259)         DEBUG("delete2: ".$line);
260)         continue;
261)       }
262)       $newcontent[] = $line;
263)     }
264)     DEBUG("Modified file:");
265)     DEBUG($newcontent);
266)     file_put_contents($userconfig, implode('', $newcontent));
267)   }
268)   git_wrapper('add '.$userconfig);
269) 
270)   git_wrapper('commit -m "deleted foreign user '.$handle.' for '.$username.'"');
271)   git_wrapper('push');
272)   
273) }
274) 
275) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

276) function newkey($pubkey, $handle)
bernd First strike: list reposito...

bernd authored 12 years ago

277) {
bernd First draft of gitolite-mod...

bernd authored 12 years ago

278)   global $key_dir, $config_dir;
279)   $username = $_SESSION['userinfo']['username'];
280)   
281)   $handle = $username.'-'.$handle;
282)   if (! validate_name($handle)) {
283)     system_failure("Der eingegebene Name enthält ungültige Zeichen. Bitte nur Buchstaben, Zahlen, Unterstrich, Binderstrich und Punkt benutzen.");
284)   }
285) 
286)   $keyfile = $key_dir.'/'.$handle.'.pub';
287)   file_put_contents($keyfile, $pubkey);
bernd SSH-Key auf plausibilität p...

bernd authored 12 years ago

288)   
289)   $proc = popen("/usr/bin/ssh-keygen -l -f '{$keyfile}'", 'r');
290)   $output = fread($proc, 512);
291)   pclose($proc);
292)   if (preg_match('/.* is not a public key file.*/', $output)) {
293)     unlink($keyfile);
294)     system_failure('Der angegebene SSH-Key scheint ungültig zu sein.');
295)   }
296)   
297) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

298)   git_wrapper('add '.$keyfile);
299) 
300)   $userconfig = $config_dir . '/' . $username . '.conf';
301)   DEBUG("using config file ".$userconfig);
302)   if (! is_file($userconfig)) {
303)     DEBUG("user-config does not exist, creating new one");
304)     file_put_contents($userconfig, '# user '.$handle."\n");
bernd Gitolite: Erzeuge include f...

bernd authored 12 years ago

305)     set_user_include();
bernd First draft of gitolite-mod...

bernd authored 12 years ago

306)   } elseif (in_array($handle, list_users())) {
307)     # user ist schon eingetragen, nur neuer Key
308)   } else {
309)     $content = file_get_contents($userconfig);
310)     file_put_contents($userconfig, "# user {$handle}\n".$content);
311)   }
312)   git_wrapper('add '.$userconfig);
bernd First strike: list reposito...

bernd authored 12 years ago

313)   
bernd First draft of gitolite-mod...

bernd authored 12 years ago

314)   git_wrapper('commit --allow-empty -m "added new key for '.$handle.'"');
315)   git_wrapper('push');
bernd First strike: list reposito...

bernd authored 12 years ago

316) }
317) 
318) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

319) function delete_key($handle)
320) {
321)   global $key_dir, $config_dir;
322)   $username = $_SESSION['userinfo']['username'];
bernd First strike: list reposito...

bernd authored 12 years ago

323) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

324)   if (! validate_name($handle)) {
325)     system_failure("Der eingegebene Name enthält ungültige Zeichen. Bitte nur Buchstaben, Zahlen, Unterstrich, Binderstrich und Punkt benutzen.");
326)   }
327)   if (!in_array($handle, list_users())) {
328)     DEBUG("key {$handle} not in");
329)     DEBUG(list_users());
330)     system_failure("Den angegebenen Key scheint es nicht zu geben");
331)   }
332) 
333)   $keyfile = $key_dir.'/'.$handle.'.pub';
334)   if (! file_exists($keyfile)) {
335)     system_failure("Der angegebene Schlüssel scheint nicht mehr vorhanden zu sein. Bitte manuelle Korrektur anfordern!");
336)   } 
337)   git_wrapper('rm '.$keyfile);
338) 
339) 
340)   $userconfig = $config_dir . '/' . $username . '.conf';
341)   DEBUG("using config file ".$userconfig);
342)   if (! is_file($userconfig)) {
343)     DEBUG("user-config does not exist, wtf?");
344)     system_failure("Es gibt für diesen Benutzer noch keine Konfiguration. Das sollte nicht sein!");
345)   } else {
346)     $content = file($userconfig);
347)     DEBUG("Old file:");
348)     DEBUG($content);
349)     $newcontent = array();
350)     foreach ($content as $line) {
351)       if (preg_match('/^# user '.$handle.'$/', $line)) {
352)         DEBUG("delete1: ".$line);
353)         continue;
354)       }
355)       if (preg_match('/^\s*(R|RW|RW+)\s*=\s*'.$handle.'\s*$/', $line)) {
356)         DEBUG("delete2: ".$line);
357)         continue;
358)       }
359)       $newcontent[] = $line;
360)     }
361)     DEBUG("Modified file:");
362)     DEBUG($newcontent);
363)     file_put_contents($userconfig, implode('', $newcontent));
364)   }
365)   git_wrapper('add '.$userconfig);
366)  
367)   git_wrapper('commit -m "deleted key for '.$handle.'"');
368)   git_wrapper('push');
369) 
370) 
371) }
bernd Fürs erste feature-complete

bernd authored 12 years ago

372) 
373) 
374) function remove_repo_from_array($data, $repo) {
375)   DEBUG("Request to remove repo »{$repo}«...");
376)   $inside = false;
377)   $outdata = array();
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

378)   $blank = true;
bernd Fürs erste feature-complete

bernd authored 12 years ago

379)   foreach ($data as $line) {
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

380)     if ($blank && chop($line) == '') {
381)       continue;
382)     }
383)     $blank = (chop($line) == '');
bernd Fürs erste feature-complete

bernd authored 12 years ago

384)     $m = array();
385)     if (preg_match('_^\s*repo (\S+)\s*$_', $line, $m) != 0) {
386)       $inside = ($m[1] == $repo);
387)     }
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

388)     if (! $inside && ! preg_match('/^'.$repo.'\s.*/', $line)) {
bernd Fürs erste feature-complete

bernd authored 12 years ago

389)       $outdata[] = $line;
390)     }
391)   }
392)   DEBUG($outdata);
393)   return $outdata;
394) }
395) 
396) 
397) function repo_exists_globally($repo) 
398) {
399)   global $config_dir;
400)   $files = scandir($config_dir);
401)   foreach ($files as $f) {
402)     if (is_file(realpath($config_dir.'/'.$f))) {
403)       $data = file(realpath($config_dir.'/'.$f));
404)       foreach ($data as $line) {
405)         if (preg_match('/^\s*repo '.$repo.'\s*$/', $line) != 0) {
406)           return true;
407)         }
408)       }
409)     }
410)   }
411)   return false;
412) }
413) 
414) 
415) function delete_repo($repo) 
416) {
417)   $repos = list_repos();
418)   if (!array_key_exists($repo, $repos)) {
419)     system_failure("Ein solches Repository existiert nicht!");
420)   }
421)   
422)   global $config_dir;
423)   $username = $_SESSION['userinfo']['username'];
424)   $userconfig = $config_dir . '/' . $username . '.conf';
425)   DEBUG("using config file ".$userconfig);
426)   $data = file($userconfig);
427)   $data = remove_repo_from_array($data, $repo);
428)   file_put_contents($userconfig, implode('', $data));
429)   git_wrapper('add '.$userconfig);
430)   
431)   git_wrapper('commit --allow-empty -m "deleted repo '.$repo.'"');
432)   git_wrapper('push');
433) }
434) 
bernd Gitolite: Erzeuge include f...

bernd authored 12 years ago

435) 
436) function set_user_include()
437) {
438)   global $config_file, $userconfig;
439)   $username = $_SESSION['userinfo']['username'];
440)   if (!file_exists($userconfig))
441)   {
442)     // Erzeuge eine leere Konfiguration damit das Include auf jeden Fall funktionieren kann
443)     file_put_contents($userconfig, '');
444)     git_wrapper('add '.$userconfig);
445)   }
446)   $found = false;
447)   $data = file($config_file);
448)   foreach ($data as $line) {
449)     if (preg_match('#webinterface/'.$username.'\.conf#', $line)) {
450)       $found = true;
451)     }
452)   }
453)   if (!$found) {
454)     $includeline = 'include  "webinterface/'.$username.'.conf"';
455)     $data = chop(file_get_contents($config_file));
456)     $data = $data."\n".$includeline."\n";
457)     file_put_contents($config_file, $data);
458)     git_wrapper('add '.$config_file);
459)   }
460) }
461) 
462) 
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

463) function save_repo($repo, $permissions, $description) 
bernd Fürs erste feature-complete

bernd authored 12 years ago

464) {
465)   if (!validate_name($repo)) {
466)     system_failure("Der gewählte name entspricht nicht den Konventionen!");
467)   }
468)   if (!array_key_exists($repo, list_repos()) && repo_exists_globally($repo)) {
469)     system_failure("Der gewählte Name existiert bereits auf diesem Server. Bitte wählen Sie einen spezifischeren Namen.");
470)   } 
471)   global $config_dir;
472)   $username = $_SESSION['userinfo']['username'];
473)   $userconfig = $config_dir . '/' . $username . '.conf';
474)   DEBUG("using config file ".$userconfig);
475)   $data = array();
476)   if (! is_file($userconfig)) {
477)     DEBUG("user-config does not exist, creating new one");
bernd Gitolite: Erzeuge include f...

bernd authored 12 years ago

478)     set_user_include();
bernd Fürs erste feature-complete

bernd authored 12 years ago

479)   } else {
480)     $data = file($userconfig);
481)   }
482) 
483)   $repos = list_repos();
484)   if (array_key_exists($repo, $repos)) {
485)     $data = remove_repo_from_array($data, $repo);
486)   }
487) 
488)   $data[] = "\n";
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

489)   if ($description) {
bernd GIT-URL eingebaut

bernd authored 12 years ago

490)     $description = preg_replace('/\[\'"\r\n/', '', $description);
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

491)     $realname = $_SESSION['userinfo']['name'];
492)     $data[] = "{$repo} \"{$realname}\" = \"{$description}\"\n";
493)   }