04f386f1dc52a3d45918c003eeef345c8425137d
bernd First strike: list reposito...

bernd authored 12 years ago

1) <?php
2) require_role(ROLE_SYSTEMUSER);
3) 
4) $data_dir = realpath( dirname(__FILE__).'/../data/' );
5) $config_file = $data_dir.'/gitolite-admin/conf/webinterface.conf';
6) $config_dir = $data_dir.'/gitolite-admin/conf/webinterface';
7) $key_dir = $data_dir.'/gitolite-admin/keydir';
8) DEBUG("gitolite-data_dir: ".$data_dir);
9) $git_wrapper = $data_dir . '/git-wrapper.sh';
10) 
11) 
bernd Fürs erste feature-complete

bernd authored 12 years ago

12) 
bernd First strike: list reposito...

bernd authored 12 years ago

13) function check_env() 
14) {
15)   global $git_wrapper, $data_dir, $config_file, $config_dir, $key_dir;
16)   if (!is_executable($git_wrapper)) {
17)     system_failure("git_wrapper.sh is not executable: {$git_wrapper}");
18)   }
19)   if (! (is_file($data_dir.'/sshkey') && is_file($data_dir.'/sshkey.pub'))) {
20)     system_failure("SSH-key not found. Please setup the gitolite-module correctly. Run ./data/initialize.sh");
21)   }
22)   if (! is_dir($data_dir.'/gitolite-admin')) {
23)     system_failure("Repository gitolite-admin ot found. Initial checkout must be made manually. Run ./data/initialize.sh");
24)   }
25)   if (! is_dir($config_dir)) {
26)     system_failure("gitolite-admin repository is not prepared.");
27)   }
bernd First draft of gitolite-mod...

bernd authored 12 years ago

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

bernd authored 12 years ago

29)     system_failure("Repository gitolite-admin is corrupted or webinterface.conf is not writeable.");
30)   }
31) }
32) 
33) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

34) function validate_name($name) {
35)   return (preg_match('/^[[:alnum:]][[:alnum:]._-]*$/', $name));
36) }
37) 
bernd show URL

bernd authored 12 years ago

38) function get_git_url($repo) {
39)   $remote = git_wrapper('remote --verbose');
40)   DEBUG('gitolite-admin repo: '.$remote[0]);
41)   $url = preg_replace('#^.*\s+(\S+):gitolite-admin.*#', '$1', $remote[0]);
42)   DEBUG('URL: '.$url);
43)   return $url.':'.$repo;
44) }
45) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

46) 
bernd First strike: list reposito...

bernd authored 12 years ago

47) function git_wrapper($commandline)
48) {
49)   global $git_wrapper, $data_dir;
50) 
51)   $command = $git_wrapper.' '.$commandline;
52)   $output = array();
53)   $retval = 0;
54)   DEBUG($command);
55)   exec($command, $output, $retval);
56)   DEBUG($output);
57)   DEBUG($retval);
58)   if ($retval > 0) {
59)     system_failure('Interner Fehler!');
60)     // FIXME: Hier sollte auf jeden Fall ein Logging angeworfen werden!
61)   }
bernd show URL

bernd authored 12 years ago

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

bernd authored 12 years ago

63) }
64) 
65) function refresh_gitolite() 
66) {
67)   check_env();
68)   git_wrapper('pull');
69) }
70) 
71) 
72) 
73) function list_repos() 
74) {
75)   global $config_file, $config_dir;
76)   $username = $_SESSION['userinfo']['username'];
77)   $userconfig = $config_dir . '/' . $username . '.conf';
78)   DEBUG("using config file ".$userconfig);
79)   if (! is_file($userconfig)) {
80)     DEBUG("user-config does not exist");
81)     return array();
82)   }
83) 
84)   $repos = array();
85)   $lines = file($userconfig);
86)   $current_repo = NULL;
bernd First draft of gitolite-mod...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

91)     if (preg_match('/^(\S+) "[^"]+" = "([^"]+)"$/', $line, $m) != 0) {
92)       if (!array_key_exists($m[1], $repos)) {
93)         $repos[$m[1]] = array('users' => NULL, 'description' => '');
94)       }
95)       DEBUG("found description: {$m[1]} = \"{$m[2]}\"");
96)       $repos[$m[1]]['description'] = $m[2];
97)     } elseif (preg_match('_^\s*repo (\S+)\s*$_', $line, $m) != 0) {
98)       if (!array_key_exists($m[1], $repos)) {
99)         $repos[$m[1]] = array('users' => NULL, 'description' => '');
100)       }
bernd First draft of gitolite-mod...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

107)     } 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

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

bernd authored 12 years ago

110)     }
111)   }
bernd First draft of gitolite-mod...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

114)   }
bernd Sortiere Repositories und U...

bernd authored 12 years ago

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

bernd authored 12 years ago

116)   DEBUG($repos);
117)   return $repos;
118) }
119) 
120) 
121) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

122) function list_users() {
123)   global $config_file, $config_dir;
124)   $username = $_SESSION['userinfo']['username'];
125)   $userconfig = $config_dir . '/' . $username . '.conf';
126)   DEBUG("using config file ".$userconfig);
127)   if (! is_file($userconfig)) {
128)     DEBUG("user-config does not exist");
129)     return array();
130)   }
131)   
132)   $lines = file($userconfig);
133)   $users = array();
134)   foreach ($lines as $line) {
135)     $m = array();
136)     if (preg_match('_# user ([^]]+)_', $line, $m) != 0) {
137)       $users[] = chop($m[1]);
138)     }
139)     if (preg_match('_^\s*repo .*_', $line) != 0) {
140)       break;
141)     }
142)   }
bernd Sortiere Repositories und U...

bernd authored 12 years ago

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

bernd authored 12 years ago

144)   DEBUG($users);
145)   return $users;
146) }
bernd First strike: list reposito...

bernd authored 12 years ago

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

bernd authored 12 years ago

148) function get_pubkey($handle) {
149)   global $key_dir;
150)   if (! validate_name($handle)) {
151)     return '';
152)   }
153)   $keyfile = $key_dir.'/'.$handle.'.pub';
154)   if (! file_exists($keyfile)) {
155)     return '';
156)   }
157)   return file_get_contents($keyfile);
158) }
159) 
160) 
161) 
162) function newkey($pubkey, $handle)
bernd First strike: list reposito...

bernd authored 12 years ago

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

bernd authored 12 years ago

164)   global $key_dir, $config_dir;
165)   $username = $_SESSION['userinfo']['username'];
166)   
167)   $handle = $username.'-'.$handle;
168)   if (! validate_name($handle)) {
169)     system_failure("Der eingegebene Name enthält ungültige Zeichen. Bitte nur Buchstaben, Zahlen, Unterstrich, Binderstrich und Punkt benutzen.");
170)   }
171) 
172)   $keyfile = $key_dir.'/'.$handle.'.pub';
173)   file_put_contents($keyfile, $pubkey);
bernd SSH-Key auf plausibilität p...

bernd authored 12 years ago

174)   
175)   $proc = popen("/usr/bin/ssh-keygen -l -f '{$keyfile}'", 'r');
176)   $output = fread($proc, 512);
177)   pclose($proc);
178)   if (preg_match('/.* is not a public key file.*/', $output)) {
179)     unlink($keyfile);
180)     system_failure('Der angegebene SSH-Key scheint ungültig zu sein.');
181)   }
182)   
183) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

184)   git_wrapper('add '.$keyfile);
185) 
186)   $userconfig = $config_dir . '/' . $username . '.conf';
187)   DEBUG("using config file ".$userconfig);
188)   if (! is_file($userconfig)) {
189)     DEBUG("user-config does not exist, creating new one");
190)     file_put_contents($userconfig, '# user '.$handle."\n");
191)   } elseif (in_array($handle, list_users())) {
192)     # user ist schon eingetragen, nur neuer Key
193)   } else {
194)     $content = file_get_contents($userconfig);
195)     file_put_contents($userconfig, "# user {$handle}\n".$content);
196)   }
197)   git_wrapper('add '.$userconfig);
bernd First strike: list reposito...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

201) }
202) 
203) 
bernd First draft of gitolite-mod...

bernd authored 12 years ago

204) function delete_key($handle)
205) {
206)   global $key_dir, $config_dir;
207)   $username = $_SESSION['userinfo']['username'];
bernd First strike: list reposito...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

258) 
259) 
260) function remove_repo_from_array($data, $repo) {
261)   DEBUG("Request to remove repo »{$repo}«...");
262)   $inside = false;
263)   $outdata = array();
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

266)     if ($blank && chop($line) == '') {
267)       continue;
268)     }
269)     $blank = (chop($line) == '');
bernd Fürs erste feature-complete

bernd authored 12 years ago

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

bernd authored 12 years ago

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

bernd authored 12 years ago

275)       $outdata[] = $line;
276)     }
277)   }
278)   DEBUG($outdata);
279)   return $outdata;
280) }
281) 
282) 
283) function repo_exists_globally($repo) 
284) {
285)   global $config_dir;
286)   $files = scandir($config_dir);
287)   foreach ($files as $f) {
288)     if (is_file(realpath($config_dir.'/'.$f))) {
289)       $data = file(realpath($config_dir.'/'.$f));
290)       foreach ($data as $line) {
291)         if (preg_match('/^\s*repo '.$repo.'\s*$/', $line) != 0) {
292)           return true;
293)         }
294)       }
295)     }
296)   }
297)   return false;
298) }
299) 
300) 
301) function delete_repo($repo) 
302) {
303)   $repos = list_repos();
304)   if (!array_key_exists($repo, $repos)) {
305)     system_failure("Ein solches Repository existiert nicht!");
306)   }
307)   
308)   global $config_dir;
309)   $username = $_SESSION['userinfo']['username'];
310)   $userconfig = $config_dir . '/' . $username . '.conf';
311)   DEBUG("using config file ".$userconfig);
312)   $data = file($userconfig);
313)   $data = remove_repo_from_array($data, $repo);
314)   file_put_contents($userconfig, implode('', $data));
315)   git_wrapper('add '.$userconfig);
316)   
317)   git_wrapper('commit --allow-empty -m "deleted repo '.$repo.'"');
318)   git_wrapper('push');
319) }
320) 
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

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

bernd authored 12 years ago

322) {
323)   if (!validate_name($repo)) {
324)     system_failure("Der gewählte name entspricht nicht den Konventionen!");
325)   }
326)   if (!array_key_exists($repo, list_repos()) && repo_exists_globally($repo)) {
327)     system_failure("Der gewählte Name existiert bereits auf diesem Server. Bitte wählen Sie einen spezifischeren Namen.");
328)   } 
329)   global $config_dir;
330)   $username = $_SESSION['userinfo']['username'];
331)   $userconfig = $config_dir . '/' . $username . '.conf';
332)   DEBUG("using config file ".$userconfig);
333)   $data = array();
334)   if (! is_file($userconfig)) {
335)     DEBUG("user-config does not exist, creating new one");
336)   } else {
337)     $data = file($userconfig);
338)   }
339) 
340)   $repos = list_repos();
341)   if (array_key_exists($repo, $repos)) {
342)     $data = remove_repo_from_array($data, $repo);
343)   }
344) 
345)   $data[] = "\n";
bernd Setze Berechtigung für gitw...

bernd authored 12 years ago

346)   if ($description) {
bernd Sortiere Repositories und U...

bernd authored 12 years ago

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

bernd authored 12 years ago

348)     $realname = $_SESSION['userinfo']['name'];
349)     $data[] = "{$repo} \"{$realname}\" = \"{$description}\"\n";
350)   }