Git Repositories

Fine-grained right management (in the GUI for now)
authorCyrille Pontvieux <jrd@enialis.net>
Thu, 27 Nov 2014 01:38:20 +0000 (02:38 +0100)
committerCyrille Pontvieux <jrd@enialis.net>
Thu, 27 Nov 2014 01:38:20 +0000 (02:38 +0100)
homegit/gitrepo.sh
src/controller.config.php
src/include.inc.php
src/repo-edit.php
src/repo-list.php
src/repo-user-del.php
src/repo-user-right.php [new file with mode: 0644]
src/repo-users.php
src/style.css

index dbe257d..57beef2 100755 (executable)
@@ -304,7 +304,7 @@ add_user() {
   fi
   [ -e "$REPO".git/.users ] || touch "$REPO".git/.users
   if grep -q "^$USERNAME:.*" "$REPO".git/.users; then
-    sed -i -r "s/^$USERNAME:.*/$USERNAME:$RIGHT" "$REPO".git/.users
+    sed -i -r "s/^$USERNAME:.*/$USERNAME:$RIGHT/" "$REPO".git/.users
   else
     echo "$USERNAME:$RIGHT" >> "$REPO".git/.users
   fi
@@ -332,7 +332,7 @@ show_users() {
     exit 2
   fi
   if [ -f "$REPO".git/.users ]; then
-    cat "$REPO".git/.users
+    sort -t: -k 2 -k 1 "$REPO".git/.users
   fi
 }
 
index 2352c15..f939f4c 100644 (file)
@@ -145,6 +145,19 @@ function action_download_file($args) {
   }
 }
 
+function action_user_right($args) {
+  if (count($args) == 3 && !empty($args[0]) && !empty($args[1]) && !empty($args[2])) {
+    extract($GLOBALS);
+    $_GET['repo'] = $args[0];
+    $_GET['user'] = $args[1];
+    $_GET['right'] = $args[2];
+    include_once('repo-user-right.php');
+    return true;
+  } else {
+    return false;
+  }
+}
+
 function action_remove_user($args) {
   if (count($args) == 2 && !empty($args[0]) && !empty($args[1])) {
     extract($GLOBALS);
index adea2d5..0373b6a 100644 (file)
@@ -25,14 +25,34 @@ function isadmin($user) {
   return ($res !== false);
 }
 
+function isrepoadmin($repo, $user) {
+  $isadmin = false;
+  foreach (gitrepoinfo('show-users', $repo) as $userinfo) {
+    $info = explode(':', $userinfo);
+    if ($info[0] == $user) {
+      $isadmin = ($info[1] == 'admin');
+      break;
+    }
+  }
+  return $isadmin;
+}
+
 function redirectifnotadmin() {
-  global $admin;
+  global $admin, $gitwebroot;
   if (!$admin) {
     header('Location: /' . $gitwebroot);
     exit;
   }
 }
 
+function redirectifnotrepoadmin($repo) {
+  global $logged, $admin, $gitwebroot;
+  if (!$logged || (!$admin && !isrepoadmin($repo, $_SESSION['username']))) {
+    header('Location: /' . $gitwebroot);
+    exit;
+  }
+}
+
 function auth() {
   global $errorMsg, $logged, $admin, $gitwebroot;
   if (isset($_POST['submit_auth'])) {
index aab0958..82d121e 100644 (file)
@@ -1,12 +1,12 @@
 <?php
 require_once('include.inc.php');
-redirectifnotadmin();
 if (empty($_GET['repo'])) {
   header('Location: /' . $gitwebroot);
   exit;
 } else {
   $repo = $_GET['repo'];
 }
+redirectifnotrepoadmin($repo);
 $errorMsgDesc = '';
 $errorMsgConfig = '';
 $errorMsgExport = '';
index 71012bf..6d3b6ca 100644 (file)
@@ -37,17 +37,37 @@ foreach ($files as $file) {
     if (empty($desc) || preg_match('/^Unnamed repository;/', $desc)) {
       $desc = $proj;
     }
-    $users = array_map(function($val) { return explode(':', $val)[0]; }, gitrepoinfo('show-users', $proj));
-    $membre = count($users) > 0 ? '<span title="Veuillez vous identifier"> ? </span>' : '<span title="Aucun utilisateur"> — </span>';
-    if ($logged && count($users) > 0) {
-      if (in_array($_SESSION['username'], $users)) {
-        $membre = "Oui";
-      } else {
-        $membre = "Non";
+    if ($logged) {
+      $right = 'no';
+      foreach (gitrepoinfo('show-users', $proj) as $userinfo) {
+        $info = explode(':', $userinfo);
+        if ($info[0] == $_SESSION['username']) {
+          $right = $info[1];
+          break;
+        }
       }
+    } else {
+      $right = null;
+    }
+    switch ($right) {
+      case 'admin':
+        $member = 'Admin';
+        break;
+      case 'user':
+        $member = 'Oui';
+        break;
+      case 'readonly':
+        $member = 'Readonly';
+        break;
+      case 'no':
+        $member = 'Non';
+        break;
+      default:
+        $member = '<span title="Veuillez vous identifier"> ? </span>';
+        break;
     }
     $actions = "<a href=\"/{$gitwebroot}info/$proj\">Info</a>&nbsp;<a href=\"/{$gitwebroot}users/$proj\">Utilisateurs</a>&nbsp;<a href=\"/{$gitwebroot}histo/$proj\">Historique</a>";
-    if ($admin) {
+    if ($admin || $right == 'admin') {
       $actions .= "&nbsp;<a class=\"edit\" href=\"/{$gitwebroot}edit/$proj\">Éditer</a>";
       $actions .= "&nbsp;<a class=\"delete\" href=\"/{$gitwebroot}delete/$proj\" onclick=\"return confirm('Êtes-vous sûr de vouloir supprimer le dépôt \'$proj\' ?');\">Supprimer</a>";
     }
@@ -63,7 +83,7 @@ foreach ($files as $file) {
       $httpurl = sprintf("%s://%s/{$gitwebroot}readonly/%s", isset($_SERVER['HTTPS']) ? 'https' : 'http', $_SERVER['HTTP_HOST'], $file);
       echo "<div class=\"ro-http\">$httpurl</div>";
     }
-    echo "</td><td class=\"member\">$membre</td><td class=\"actions\">$actions</td></tr>\n";
+    echo "</td><td class=\"member\">$member</td><td class=\"actions\">$actions</td></tr>\n";
   }
 }
 ?>
index 90b24f1..12d25b4 100644 (file)
@@ -1,6 +1,5 @@
 <?php
 require_once('include.inc.php');
-redirectifnotadmin();
 if (!$logged || empty($_GET['repo']) || empty($_GET['user'])) {
   header('Location: /' . $gitwebroot);
   exit;
@@ -8,5 +7,6 @@ if (!$logged || empty($_GET['repo']) || empty($_GET['user'])) {
   $repo = $_GET['repo'];
   $user = $_GET['user'];
 }
+redirectifnotrepoadmin($repo);
 $res = gitrepoinfo('del-user', $repo, $user);
 header("Location: /{$gitwebroot}users/$repo");
diff --git a/src/repo-user-right.php b/src/repo-user-right.php
new file mode 100644 (file)
index 0000000..18c3d95
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+require_once('include.inc.php');
+$right = $_GET['right'] or '';
+if (!$logged || empty($_GET['repo']) || empty($_GET['user']) || ($right != 'admin' && $right != 'user' && $right != 'readonly')) {
+  header('Location: /' . $gitwebroot);
+  exit;
+} else {
+  $repo = $_GET['repo'];
+  $user = $_GET['user'];
+}
+redirectifnotrepoadmin($repo);
+$res = gitrepoinfo('add-user', $repo, $user, $right);
+header("Location: /{$gitwebroot}users/$repo");
index e94fd6d..9af46f1 100644 (file)
@@ -7,9 +7,11 @@ if (empty($_GET['repo'])) {
   $repo = $_GET['repo'];
 }
 $errorMsg = '';
-if ($admin && isset($_POST['submit_user_add'])) {
+$repoadmin = $admin || isrepoadmin($repo, $_SESSION['username']);
+if ($repoadmin && isset($_POST['submit_user_add'])) {
   $fUser = $_POST['username'];
-  $res = gitrepoinfo('add-user', $repo, $fUser);
+  $fRight = $_POST['right'];
+  $res = gitrepoinfo('add-user', $repo, $fUser, $fRight);
   if ($res === false) {
     $errorMsg = "L'utilisateur n'a pas pu être ajouté.";
   }
@@ -22,21 +24,30 @@ require('header.inc.php');
       <table>
         <tr>
           <th class="name">Utilisateur</th>
+          <th class="right">Droit</th>
           <th class="actions">Actions</th>
         </tr>
 <?php
-$users = array_map(function($val) { return explode(':', $val)[0]; }, gitrepoinfo('show-users', $repo));
-foreach ($users as $user) {
+$members = array();
+foreach (gitrepoinfo('show-users', $repo) as $userinfo) {
+  $info = explode(':', $userinfo);
+  $members[$info[0]] = $info[1];
+}
+$isExport = file_exists("$gitdir/$repo.git/git-daemon-export-ok");
+foreach ($members as $user => $right) {
   $actions = ' — ';
-  if ($admin) {
-    $actions = "<a href=\"/{$gitwebroot}remove_user/$repo/$user\">Retirer</a>";
+  if ($repoadmin) {
+    $actions = "<a href=\"/{$gitwebroot}user_right/$repo/$user/admin\">→ admin right</a>";
+    $actions .= "&nbsp;<a href=\"/{$gitwebroot}user_right/$repo/$user/user\">→ user right</a>";
+    $actions .= "&nbsp;<a href=\"/{$gitwebroot}user_right/$repo/$user/readonly\">→ readonly right</a>";
+    $actions .= "&nbsp;<a href=\"/{$gitwebroot}remove_user/$repo/$user\">Retirer</a>";
   }
-  echo "        <tr><td class=\"name\">$user</td><td class=\"actions\">$actions</td></tr>\n";
+  echo "        <tr><td class=\"name\">$user</td><td class=\"right\">$right</td><td class=\"actions\">$actions</td></tr>\n";
 }
 ?>
       </table>
     </div>
-<?php if ($admin) { ?>
+<?php if ($repoadmin) { ?>
     <div class="error"><?php echo $errorMsg; ?></div>
     <form id="repo-add-user" action="" method="POST">
       <fieldset>
@@ -46,11 +57,14 @@ foreach ($users as $user) {
 <?php
 $users = gitrepoinfo('list-users');
 foreach ($users as $user) {
-  $user = htmlspecialchars($user);
-  echo "          <option value=\"$user\">$user</option>\n";
+  if (!array_key_exists($user, $members)) {
+    $user = htmlspecialchars($user);
+    echo "          <option value=\"$user\">$user</option>\n";
+  }
 }
 ?>
         </select>
+        <select name="right"><option value="admin">admin</option><option value="user" selected="selected">user</option><option value="readonly">readonly</option></select>
         <input type="submit" name="submit_user_add" value="Ajouter l'utilisateur au dépôt"/>
       </fieldset>
     </form>
index 0ea2cf8..052f10d 100644 (file)
@@ -54,6 +54,7 @@ table .address {
   text-align: left;
 }
 table .member,
+table .right,
 table .actions {
   text-align: center;
 }