Browse code

First draft of gitolite-module, only key-management implemented

git-svn-id: https://svn.schokokeks.org/repos/tools/webinterface/trunk@2091 87cf0b9e-d624-0410-a070-f6ee81989793

bernd authored on21/12/2011 16:51:51
Showing7 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,59 @@
1
+<?php
2
+require_role(ROLE_SYSTEMUSER);
3
+require_once('inc/security.php');
4
+
5
+include('git.php');
6
+$section = 'git_git';
7
+
8
+if (isset($_GET['repo'])) {
9
+  $repos = list_repos();
10
+  if (!array_key_exists($_GET['repo'], $repos)) {
11
+    system_failure("Es sollte ein unbekanntes Repository gelöscht werden!");
12
+  }
13
+
14
+  $sure = user_is_sure();
15
+  if ($sure === NULL)
16
+  {
17
+    are_you_sure("repo={$_GET['repo']}", '<p>Soll das GIT-Repository »'.$_GET['repo'].'« wirklich gelöscht werden?</p>
18
+    <p>Alle Inhalte die in diesem Repository gespeichert sind, werden gelöscht!</p>');
19
+  }
20
+  elseif ($sure === true)
21
+  {
22
+    delete_repository($_GET['repo']);
23
+    if (! $debugmode)
24
+      header('Location: git');
25
+    die();
26
+  }
27
+  elseif ($sure === false)
28
+  {
29
+    if (! $debugmode)
30
+      header("Location: git");
31
+    die();
32
+  }
33
+}
34
+
35
+if (isset($_GET['handle'])) {
36
+  $users = list_users();
37
+  if (!in_array($_GET['handle'], $users)) {
38
+    system_failure("Es sollte ein unbekannter SSH-Key gelöscht werden!");
39
+  }
40
+
41
+  $sure = user_is_sure();
42
+  if ($sure === NULL)
43
+  {
44
+    are_you_sure("handle={$_GET['handle']}", '<p>Soll der SSH-Key »'.$_GET['handle'].'« wirklich gelöscht werden?</p>');
45
+  }
46
+  elseif ($sure === true)
47
+  {
48
+    delete_key($_GET['handle']);
49
+    if (! $debugmode)
50
+      header('Location: git');
51
+    die();
52
+  }
53
+  elseif ($sure === false)
54
+  {
55
+    if (! $debugmode)
56
+      header("Location: git");
57
+    die();
58
+  }
59
+}
0 60
new file mode 100644
... ...
@@ -0,0 +1,10 @@
1
+<?php
2
+require_role(ROLE_SYSTEMUSER);
3
+
4
+include("git.php");
5
+
6
+$section = 'git_git';
7
+
8
+
9
+
10
+
... ...
@@ -1,8 +1,58 @@
1 1
 <?php
2
+require_once('inc/icons.php');
2 3
 
3 4
 include('git.php');
4 5
 require_role(ROLE_SYSTEMUSER);
5 6
 
6
-list_repos();
7
-#refresh_gitosis();
7
+title("GIT-Zugänge");
8 8
 
9
+output("<p>Das verteilte Versionskontrollsystem <a href=\"http://www.git-scm.org\">GIT</a> ist ein populäres Werkzeug um Programmcode zu verwalten. Mit dieser Oberfläche können Sie GIT-repositories erstellen und den Zugriff für mehrere Benutzer festlegen.</p>");
10
+output("<p>Wir verwenden das beliebte System »gitolite« um diese Funktionalität anzubieten. Gitolite erlaubt bei Bedarf weitaus feingliedrigere Kontrolle als dieser Webinterface. Fragen Sie bitte den Support, wenn Sie Interesse daran haben zusätzliche Berechtigungen einzurichten.</p>");
11
+
12
+$repos = list_repos();
13
+$users = list_users();
14
+
15
+if (count($repos) == 0) {
16
+  output("<p><em>bisher haben Sie keine GIT-Repositories</em></p>");
17
+} else {
18
+  output("<h3>Ihre GIT-Repositories</h3>"); 
19
+}
20
+
21
+foreach ($repos as $repo => $access) {
22
+  output("<div><p><strong>{$repo}</strong> ".internal_link('edit', icon_edit('Zugriffsrechte bearbeiten'), 'repo='.$repo)." ".internal_link('delete', icon_delete('Repository löschen'), 'repo='.$repo)."</p><ul>");
23
+  foreach ($access as $user => $rights) {
24
+    $grant = '';
25
+    switch ($rights) {
26
+      case 'R': $grant = 'Lesezugriff';
27
+                break;
28
+      case 'RW': $grant = 'Lese- und Schreibzugriff';
29
+                break;
30
+      case 'RW+': $grant = 'erweiterter Zugriff (inkl. "rewind")';
31
+                break;
32
+    }    
33
+    output("<li>{$user}: {$grant}</li>");
34
+  }
35
+  output("</ul></div>");
36
+}
37
+
38
+if (count($users) > 0) {
39
+  addnew('edit', 'Neues GIT-Repository anlegen');
40
+} else {
41
+  output('<p><em>Bitte legen Sie zunächst mindestens einen SSH-Key an.</em></p>');
42
+}
43
+
44
+
45
+
46
+if (count($users) == 0) {
47
+  output('<p><em>Es sind bisher keine SSH-Keys eingerichtet.</em></p>');
48
+} else {
49
+  output('<h3>Ihre aktuell hinterlegten SSH-Keys</h3>');
50
+}
51
+
52
+foreach ($users as $handle) {
53
+  output('<p><strong>'.$handle.'</strong> '.internal_link('newkey', icon_edit('Hinterlegten SSH-Key ändern'), 'handle='.$handle)." ".internal_link('delete', icon_delete('SSH-Key löschen'), 'handle='.$handle)."</p>");
54
+}
55
+
56
+addnew('newkey', 'Neuen SSH-Key eintragen');
57
+
58
+output('<p style="font-size: 90%;padding-top: 0.5em; border-top: 1px solid black;">Hinweis: Die hier gezeigten Berechtigungen können unter Umständen nicht aktuell sein. Bei Bearf können Sie '.internal_link('refresh', 'die Berechtigungen neu einlesen lassen').'</p>');
... ...
@@ -24,12 +24,17 @@ function check_env()
24 24
   if (! is_dir($config_dir)) {
25 25
     system_failure("gitolite-admin repository is not prepared.");
26 26
   }
27
-  if (! (is_dir($key_dir) && is_writeable($$config_file))) {
27
+  if (! (is_dir($key_dir) && is_writeable($config_file))) {
28 28
     system_failure("Repository gitolite-admin is corrupted or webinterface.conf is not writeable.");
29 29
   }
30 30
 }
31 31
 
32 32
 
33
+function validate_name($name) {
34
+  return (preg_match('/^[[:alnum:]][[:alnum:]._-]*$/', $name));
35
+}
36
+
37
+
33 38
 function git_wrapper($commandline)
34 39
 {
35 40
   global $git_wrapper, $data_dir;
... ...
@@ -54,17 +59,6 @@ function refresh_gitolite()
54 59
 }
55 60
 
56 61
 
57
-function read_config()
58
-{
59
-  global $gitolite_conf;
60
-  $customerno = (int) $_SESSION['customerinfo']['customerno'];
61
-  $groups = array();
62
-
63
-  $data = parse_ini_file($gitolite_conf, TRUE);
64
-  DEBUG($data);
65
-  
66
-}
67
-
68 62
 
69 63
 function list_repos() 
70 64
 {
... ...
@@ -80,24 +74,153 @@ function list_repos()
80 74
   $repos = array();
81 75
   $lines = file($userconfig);
82 76
   $current_repo = NULL;
77
+  $current_repo_users = array();
83 78
   foreach ($lines as $line) {
84 79
     $m = array();
85 80
     if (preg_match('_^[ \t]*repo ([^]]+)_', $line, $m) != 0) {
81
+      if ($current_repo) {
82
+        $repos[$current_repo] = $current_repo_users;
83
+      }
86 84
       DEBUG("found repo ".$m[1]);
87
-      $repos[] = $m[1];
85
+      $current_repo = chop($m[1]);
86
+      $current_repo_users = array();
87
+    } else if (preg_match('/^\s*(R|RW|RW+)\s*=\s*([[:alnum:]][[:alnum:]._-]*)\s*/', $line, $m) != 0) {
88
+      DEBUG("found access rule: ".$m[1]." for ".$m[2]);
89
+      $current_repo_users[chop($m[2])] = chop($m[1]);
88 90
     }
89 91
   }
92
+  if ($current_repo) {
93
+    $repos[$current_repo] = $current_repo_users;
94
+  }
90 95
   DEBUG($repos);
91 96
   return $repos;
92 97
 }
93 98
 
94 99
 
95 100
 
101
+function list_users() {
102
+  global $config_file, $config_dir;
103
+  $username = $_SESSION['userinfo']['username'];
104
+  $userconfig = $config_dir . '/' . $username . '.conf';
105
+  DEBUG("using config file ".$userconfig);
106
+  if (! is_file($userconfig)) {
107
+    DEBUG("user-config does not exist");
108
+    return array();
109
+  }
110
+  
111
+  $lines = file($userconfig);
112
+  $users = array();
113
+  foreach ($lines as $line) {
114
+    $m = array();
115
+    if (preg_match('_# user ([^]]+)_', $line, $m) != 0) {
116
+      $users[] = chop($m[1]);
117
+    }
118
+    if (preg_match('_^\s*repo .*_', $line) != 0) {
119
+      break;
120
+    }
121
+  }
122
+  DEBUG($users);
123
+  return $users;
124
+}
96 125
 
97
-function add_key($pubkey, $handle)
126
+function get_pubkey($handle) {
127
+  global $key_dir;
128
+  if (! validate_name($handle)) {
129
+    return '';
130
+  }
131
+  $keyfile = $key_dir.'/'.$handle.'.pub';
132
+  if (! file_exists($keyfile)) {
133
+    return '';
134
+  }
135
+  return file_get_contents($keyfile);
136
+}
137
+
138
+
139
+
140
+function newkey($pubkey, $handle)
98 141
 {
142
+  global $key_dir, $config_dir;
143
+  $username = $_SESSION['userinfo']['username'];
144
+  
145
+  $handle = $username.'-'.$handle;
146
+  if (! validate_name($handle)) {
147
+    system_failure("Der eingegebene Name enthält ungültige Zeichen. Bitte nur Buchstaben, Zahlen, Unterstrich, Binderstrich und Punkt benutzen.");
148
+  }
149
+
150
+  // FIXME: Muss man den SSH-Key auf Plausibilität prüfen? Aus Sicherheitsgründen vermutlich nicht.
151
+  $keyfile = $key_dir.'/'.$handle.'.pub';
152
+  file_put_contents($keyfile, $pubkey);
153
+  git_wrapper('add '.$keyfile);
154
+
155
+  $userconfig = $config_dir . '/' . $username . '.conf';
156
+  DEBUG("using config file ".$userconfig);
157
+  if (! is_file($userconfig)) {
158
+    DEBUG("user-config does not exist, creating new one");
159
+    file_put_contents($userconfig, '# user '.$handle."\n");
160
+  } elseif (in_array($handle, list_users())) {
161
+    # user ist schon eingetragen, nur neuer Key
162
+  } else {
163
+    $content = file_get_contents($userconfig);
164
+    file_put_contents($userconfig, "# user {$handle}\n".$content);
165
+  }
166
+  git_wrapper('add '.$userconfig);
99 167
   
168
+  git_wrapper('commit --allow-empty -m "added new key for '.$handle.'"');
169
+  git_wrapper('push');
100 170
 }
101 171
 
102 172
 
173
+function delete_key($handle)
174
+{
175
+  global $key_dir, $config_dir;
176
+  $username = $_SESSION['userinfo']['username'];
103 177
 
178
+  if (! validate_name($handle)) {
179
+    system_failure("Der eingegebene Name enthält ungültige Zeichen. Bitte nur Buchstaben, Zahlen, Unterstrich, Binderstrich und Punkt benutzen.");
180
+  }
181
+  if (!in_array($handle, list_users())) {
182
+    DEBUG("key {$handle} not in");
183
+    DEBUG(list_users());
184
+    system_failure("Den angegebenen Key scheint es nicht zu geben");
185
+  }
186
+
187
+  // FIXME: Muss man den SSH-Key auf Plausibilität prüfen? Aus Sicherheitsgründen vermutlich nicht.
188
+  $keyfile = $key_dir.'/'.$handle.'.pub';
189
+  if (! file_exists($keyfile)) {
190
+    system_failure("Der angegebene Schlüssel scheint nicht mehr vorhanden zu sein. Bitte manuelle Korrektur anfordern!");
191
+  } 
192
+  git_wrapper('rm '.$keyfile);
193
+
194
+
195
+  $userconfig = $config_dir . '/' . $username . '.conf';
196
+  DEBUG("using config file ".$userconfig);
197
+  if (! is_file($userconfig)) {
198
+    DEBUG("user-config does not exist, wtf?");
199
+    system_failure("Es gibt für diesen Benutzer noch keine Konfiguration. Das sollte nicht sein!");
200
+  } else {
201
+    $content = file($userconfig);
202
+    DEBUG("Old file:");
203
+    DEBUG($content);
204
+    $newcontent = array();
205
+    foreach ($content as $line) {
206
+      if (preg_match('/^# user '.$handle.'$/', $line)) {
207
+        DEBUG("delete1: ".$line);
208
+        continue;
209
+      }
210
+      if (preg_match('/^\s*(R|RW|RW+)\s*=\s*'.$handle.'\s*$/', $line)) {
211
+        DEBUG("delete2: ".$line);
212
+        continue;
213
+      }
214
+      $newcontent[] = $line;
215
+    }
216
+    DEBUG("Modified file:");
217
+    DEBUG($newcontent);
218
+    file_put_contents($userconfig, implode('', $newcontent));
219
+  }
220
+  git_wrapper('add '.$userconfig);
221
+ 
222
+  git_wrapper('commit -m "deleted key for '.$handle.'"');
223
+  git_wrapper('push');
224
+
225
+
226
+}
104 227
new file mode 100644
... ...
@@ -0,0 +1,43 @@
1
+<?php
2
+require_role(ROLE_SYSTEMUSER);
3
+
4
+include('git.php');
5
+
6
+$section = 'git_git';
7
+
8
+$handle = '';
9
+if (isset($_GET['handle'])) {
10
+  $handle = filter_input_general($_GET['handle']);
11
+}
12
+
13
+$action = '';
14
+$form = '';
15
+
16
+$pubkey = '';
17
+
18
+if ($handle) {
19
+  $action = 'newkey';
20
+  title('Neuen SSH-Key für GIT-Benutzer');
21
+  output('<p>Legen Sie hier einen neuen SSH-Key für einen bestehenden Benutzer fest.</p>');
22
+  $pubkey = get_pubkey($handle);
23
+} else {
24
+  $action = 'newuser';
25
+  title('Neuer GIT-Benutzer');
26
+  output('<p>Tragen Sie hier einen eindeutigen Namen für den neuen Benutzer fest und hinterlegen Sie einen SSH-Public-Key.</p>');
27
+}
28
+
29
+$userprefix = $_SESSION['userinfo']['username'].'-';
30
+
31
+$form .= '<table><tr><td><label for="handle" />Name des Benutzers:</label></td>';
32
+if ($handle) {
33
+  $form .= '<td><input type="hidden" name="handle" value="'.str_replace($userprefix, '', $handle).'" /><strong>'.$handle.'</strong></td></tr>';
34
+} else {
35
+  $form .= '<td>'.$userprefix.'<input type="text" id="handle" name="handle" value="'.$handle.'" /></td></tr>';
36
+}
37
+$form .= '<tr><td><label for="pubkey">SSH-Public-Key:</label></td><td><textarea name="pubkey" id="pubkey" cols="70" rows="10">'.$pubkey.'</textarea></td></tr>
38
+  </table>
39
+  <p><input type="submit" value="Speichern" /></p>
40
+  ';
41
+
42
+
43
+output(html_form('git_newkey', 'save', "action={$action}", $form));
0 44
new file mode 100644
... ...
@@ -0,0 +1,16 @@
1
+<?php
2
+require_role(ROLE_SYSTEMUSER);
3
+include("git.php");
4
+
5
+$section = 'git_git';
6
+
7
+title("GIT-Konfiguration aktualisieren");
8
+
9
+output('<p>Bitte warten Sie während die GIT-Konfiguration neu eingelesen wird...</p>');
10
+
11
+refresh_gitolite();
12
+
13
+if (!$debugmode) {
14
+  header("Location: git");
15
+}
16
+
0 17
new file mode 100644
... ...
@@ -0,0 +1,31 @@
1
+<?php
2
+require_role(ROLE_SYSTEMUSER);
3
+
4
+include('git.php');
5
+
6
+if ($_GET['action'] == 'newuser') {
7
+  $handle = $_POST['handle'];
8
+  if ($handle == '') {
9
+    system_failure("Leere Benutzerbezeichnung!");
10
+  }
11
+  $users = list_users();
12
+  if (in_array($handle, $users)) {
13
+    system_failure("Ein Benutzer mit diesem Namen existiert bereits.");
14
+  }
15
+  newkey($_POST['pubkey'], $handle);
16
+  if (! $debugmode)
17
+    header('Location: git');
18
+  die();
19
+} elseif ($_GET['action'] == 'newkey') {
20
+  $handle = $_POST['handle'];
21
+  if ($handle == '') {
22
+    system_failure("Leere Benutzerbezeichnung!");
23
+  }
24
+  newkey($_POST['pubkey'], $handle);
25
+  if (! $debugmode)
26
+    header('Location: git');
27
+  die();
28
+}
29
+
30
+
31
+