c208bd906b3991555db11b9229846c4601ca408c
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) 
5) Written 2008-2012 by schokokeks.org Hosting, namely
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) 
136) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

163) function get_pubkey($handle) {
164)   global $key_dir;
165)   if (! validate_name($handle)) {
166)     return '';
167)   }
168)   $keyfile = $key_dir.'/'.$handle.'.pub';
169)   if (! file_exists($keyfile)) {
170)     return '';
171)   }
172)   return file_get_contents($keyfile);
173) }
174) 
175) 
176) 
177) function newkey($pubkey, $handle)
bernd First strike: list reposito...

bernd authored 12 years ago

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

bernd authored 12 years ago

179)   global $key_dir, $config_dir;
180)   $username = $_SESSION['userinfo']['username'];
181)   
182)   $handle = $username.'-'.$handle;
183)   if (! validate_name($handle)) {
184)     system_failure("Der eingegebene Name enthält ungültige Zeichen. Bitte nur Buchstaben, Zahlen, Unterstrich, Binderstrich und Punkt benutzen.");
185)   }
186) 
187)   $keyfile = $key_dir.'/'.$handle.'.pub';
188)   file_put_contents($keyfile, $pubkey);
bernd SSH-Key auf plausibilität p...

bernd authored 12 years ago

189)   
190)   $proc = popen("/usr/bin/ssh-keygen -l -f '{$keyfile}'", 'r');
191)   $output = fread($proc, 512);
192)   pclose($proc);
193)   if (preg_match('/.* is not a public key file.*/', $output)) {
194)     unlink($keyfile);
195)     system_failure('Der angegebene SSH-Key scheint ungültig zu sein.');
196)   }
197)   
198) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

199)   git_wrapper('add '.$keyfile);
200) 
201)   $userconfig = $config_dir . '/' . $username . '.conf';
202)   DEBUG("using config file ".$userconfig);
203)   if (! is_file($userconfig)) {
204)     DEBUG("user-config does not exist, creating new one");
205)     file_put_contents($userconfig, '# user '.$handle."\n");
bernd Gitolite: Erzeuge include f...

bernd authored 12 years ago

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

bernd authored 12 years ago

207)   } elseif (in_array($handle, list_users())) {
208)     # user ist schon eingetragen, nur neuer Key
209)   } else {
210)     $content = file_get_contents($userconfig);
211)     file_put_contents($userconfig, "# user {$handle}\n".$content);
212)   }
213)   git_wrapper('add '.$userconfig);
bernd First strike: list reposito...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

217) }
218) 
219) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

220) function delete_key($handle)
221) {
222)   global $key_dir, $config_dir;
223)   $username = $_SESSION['userinfo']['username'];
bernd First strike: list reposito...

bernd authored 12 years ago

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

bernd authored 12 years ago

225)   if (! validate_name($handle)) {
226)     system_failure("Der eingegebene Name enthält ungültige Zeichen. Bitte nur Buchstaben, Zahlen, Unterstrich, Binderstrich und Punkt benutzen.");
227)   }
228)   if (!in_array($handle, list_users())) {
229)     DEBUG("key {$handle} not in");
230)     DEBUG(list_users());
231)     system_failure("Den angegebenen Key scheint es nicht zu geben");
232)   }
233) 
234)   // FIXME: Muss man den SSH-Key auf Plausibilität prüfen? Aus Sicherheitsgründen vermutlich nicht.
235)   $keyfile = $key_dir.'/'.$handle.'.pub';
236)   if (! file_exists($keyfile)) {
237)     system_failure("Der angegebene Schlüssel scheint nicht mehr vorhanden zu sein. Bitte manuelle Korrektur anfordern!");
238)   } 
239)   git_wrapper('rm '.$keyfile);
240) 
241) 
242)   $userconfig = $config_dir . '/' . $username . '.conf';
243)   DEBUG("using config file ".$userconfig);
244)   if (! is_file($userconfig)) {
245)     DEBUG("user-config does not exist, wtf?");
246)     system_failure("Es gibt für diesen Benutzer noch keine Konfiguration. Das sollte nicht sein!");
247)   } else {
248)     $content = file($userconfig);
249)     DEBUG("Old file:");
250)     DEBUG($content);
251)     $newcontent = array();
252)     foreach ($content as $line) {
253)       if (preg_match('/^# user '.$handle.'$/', $line)) {
254)         DEBUG("delete1: ".$line);
255)         continue;
256)       }
257)       if (preg_match('/^\s*(R|RW|RW+)\s*=\s*'.$handle.'\s*$/', $line)) {
258)         DEBUG("delete2: ".$line);
259)         continue;
260)       }
261)       $newcontent[] = $line;
262)     }
263)     DEBUG("Modified file:");
264)     DEBUG($newcontent);
265)     file_put_contents($userconfig, implode('', $newcontent));
266)   }
267)   git_wrapper('add '.$userconfig);
268)  
269)   git_wrapper('commit -m "deleted key for '.$handle.'"');
270)   git_wrapper('push');
271) 
272) 
273) }
bernd Fürs erste feature-complete

bernd authored 12 years ago

274) 
275) 
276) function remove_repo_from_array($data, $repo) {
277)   DEBUG("Request to remove repo »{$repo}«...");
278)   $inside = false;
279)   $outdata = array();
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

282)     if ($blank && chop($line) == '') {
283)       continue;
284)     }
285)     $blank = (chop($line) == '');
bernd Fürs erste feature-complete

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

291)       $outdata[] = $line;
292)     }
293)   }
294)   DEBUG($outdata);
295)   return $outdata;
296) }
297) 
298) 
299) function repo_exists_globally($repo) 
300) {
301)   global $config_dir;
302)   $files = scandir($config_dir);
303)   foreach ($files as $f) {
304)     if (is_file(realpath($config_dir.'/'.$f))) {
305)       $data = file(realpath($config_dir.'/'.$f));
306)       foreach ($data as $line) {
307)         if (preg_match('/^\s*repo '.$repo.'\s*$/', $line) != 0) {
308)           return true;
309)         }
310)       }
311)     }
312)   }
313)   return false;
314) }
315) 
316) 
317) function delete_repo($repo) 
318) {
319)   $repos = list_repos();
320)   if (!array_key_exists($repo, $repos)) {
321)     system_failure("Ein solches Repository existiert nicht!");
322)   }
323)   
324)   global $config_dir;
325)   $username = $_SESSION['userinfo']['username'];
326)   $userconfig = $config_dir . '/' . $username . '.conf';
327)   DEBUG("using config file ".$userconfig);
328)   $data = file($userconfig);
329)   $data = remove_repo_from_array($data, $repo);
330)   file_put_contents($userconfig, implode('', $data));
331)   git_wrapper('add '.$userconfig);
332)   
333)   git_wrapper('commit --allow-empty -m "deleted repo '.$repo.'"');
334)   git_wrapper('push');
335) }
336) 
bernd Gitolite: Erzeuge include f...

bernd authored 12 years ago

337) 
338) function set_user_include()
339) {
340)   global $config_file, $userconfig;
341)   $username = $_SESSION['userinfo']['username'];
342)   if (!file_exists($userconfig))
343)   {
344)     // Erzeuge eine leere Konfiguration damit das Include auf jeden Fall funktionieren kann
345)     file_put_contents($userconfig, '');
346)     git_wrapper('add '.$userconfig);
347)   }
348)   $found = false;
349)   $data = file($config_file);
350)   foreach ($data as $line) {
351)     if (preg_match('#webinterface/'.$username.'\.conf#', $line)) {
352)       $found = true;
353)     }
354)   }
355)   if (!$found) {
356)     $includeline = 'include  "webinterface/'.$username.'.conf"';
357)     $data = chop(file_get_contents($config_file));
358)     $data = $data."\n".$includeline."\n";
359)     file_put_contents($config_file, $data);
360)     git_wrapper('add '.$config_file);
361)   }
362) }
363) 
364) 
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

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

bernd authored 12 years ago

366) {
367)   if (!validate_name($repo)) {
368)     system_failure("Der gewählte name entspricht nicht den Konventionen!");
369)   }
370)   if (!array_key_exists($repo, list_repos()) && repo_exists_globally($repo)) {
371)     system_failure("Der gewählte Name existiert bereits auf diesem Server. Bitte wählen Sie einen spezifischeren Namen.");
372)   } 
373)   global $config_dir;
374)   $username = $_SESSION['userinfo']['username'];
375)   $userconfig = $config_dir . '/' . $username . '.conf';
376)   DEBUG("using config file ".$userconfig);
377)   $data = array();
378)   if (! is_file($userconfig)) {
379)     DEBUG("user-config does not exist, creating new one");
bernd Gitolite: Erzeuge include f...

bernd authored 12 years ago

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

bernd authored 12 years ago

381)   } else {
382)     $data = file($userconfig);
383)   }
384) 
385)   $repos = list_repos();
386)   if (array_key_exists($repo, $repos)) {
387)     $data = remove_repo_from_array($data, $repo);
388)   }
389) 
390)   $data[] = "\n";
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

393)     $realname = $_SESSION['userinfo']['name'];
394)     $data[] = "{$repo} \"{$realname}\" = \"{$description}\"\n";
395)   }