From ae2b0e63d6efb72970c8835c3885ddd3842e2c68 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 15 Nov 2013 20:19:20 +0600 Subject: [PATCH] Further tweaks to gi ermissions script - Seems @all didn't work, now use explicit list of repos - Handle cases when phab user uses the same key as used for "system" repositories. --- scripts/gitadmin/rebuild_gitadmin.php | 70 +++++++++++++++++++++------ 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/scripts/gitadmin/rebuild_gitadmin.php b/scripts/gitadmin/rebuild_gitadmin.php index c9b8776b84..f76ad77d73 100755 --- a/scripts/gitadmin/rebuild_gitadmin.php +++ b/scripts/gitadmin/rebuild_gitadmin.php @@ -12,6 +12,12 @@ function startswith($string, $prefix) { return substr($string, 0, strlen($prefix)) == $prefix; } +function endswith($string, $suffix) { + $suffix_length = strlen($suffix); + return substr($string, strlen($string) - $suffix_length, + $suffix_length) == $suffix; +} + function write_ini_file($array, $file) { $res = array(); foreach ($array as $key => $val) { @@ -30,7 +36,7 @@ function write_ini_file($array, $file) { // Get user's heys and put them to the configuration function handleSingleUserPHID( - $keydir, $viewer, $userPHID, &$used_keys) { + $keydir, $viewer, $userPHID, $system_keys, &$used_keys) { $user = id(new PhabricatorPeopleQuery()) ->setViewer($viewer) ->withPHIDs(array($userPHID)) @@ -42,18 +48,23 @@ function handleSingleUserPHID( $members = array(); foreach ($keys as $key) { - $escaped_key_name = escape_name($key->getName()); - $member = 'PHAB_'.$user->getUserName(). - '_'.$escaped_key_name. - '_'.$key->getID(); - $members[] = $member; - if (!array_key_exists($member, $used_keys)) { - $used_keys[$member] = true; $full_key_content = $key->getKeyType().' '. $key->getKeyBody().' '. $key->getKeyComment()."\n"; - file_put_contents("$keydir/$member.pub", $full_key_content); + + if (array_key_exists($full_key_content, $system_keys)) { + $members[] = $system_keys[$full_key_content]; + } else { + $escaped_key_name = escape_name($key->getName()); + $member = 'PHAB_'.$user->getUserName(). + '_'.$escaped_key_name. + '_'.$key->getID(); + $members[] = $member; + if (!array_key_exists($member, $used_keys)) { + $used_keys[$member] = true; + file_put_contents("$keydir/$member.pub", $full_key_content); + } } } return $members; @@ -61,7 +72,8 @@ function handleSingleUserPHID( // Parse repository and put it's members to the config file function handleSingleRepository( - $keydir, $viewer, $repository, &$new_configuration, &$used_keys) { + $keydir, $viewer, $repository, $all_repositories, $system_keys, + &$new_configuration, &$used_keys) { $policies = PhabricatorPolicyQuery::loadPolicies( $viewer, $repository); @@ -81,11 +93,12 @@ function handleSingleRepository( $memberPHIDs = $project->getMemberPHIDs(); foreach ($memberPHIDs as $memberPHID) { $members = array_merge($members, - handleSingleUserPHID($keydir, $viewer, $memberPHID, $used_keys)); + handleSingleUserPHID($keydir, $viewer, $memberPHID, + $system_keys, $used_keys)); } } else if ($type == PhabricatorPeoplePHIDTypeUser::TYPECONST) { $members = handleSingleUserPHID( - $keydir, $viewer, $pushable->getPHID(), $used_keys); + $keydir, $viewer, $pushable->getPHID(), $system_keys, $used_keys); } else if ($type == PhabricatorPolicyPHIDTypePolicy::TYPECONST) { /* pass */ } else { @@ -99,7 +112,7 @@ function handleSingleRepository( $group_name = "PHAB_${escaped_repository_name}"; $values = array(); $values['members'] = join(' ', $members); - $values['readonly'] = '@all'; + $values['readonly'] = join(' ', $all_repositories); $values['writable'] = $repository_name; $new_configuration["group $group_name"] = $values; } @@ -116,6 +129,19 @@ function getCleanOldConfiguration($old_configuration) { return $new_configuration; } +// Get non-phab keys +function getSystemPublicKeys($keydir) { + $files = scandir($keydir); + $system_keys = array(); + foreach ($files as $file) { + if (!startswith($file, "PHAB") && endswith($file, '.pub')) { + $key = file_get_contents("$keydir/$file"); + $system_keys[$key] = basename($file, '.pub'); + } + } + return $system_keys; +} + // Remove unused public keys function removeUnusedPublicKeys($keydir, $used_keys) { $files = scandir($keydir); @@ -147,6 +173,21 @@ function rebuildConfiguration($gitosis_root) { $new_configuration = getCleanOldConfiguration( $old_configuration); + // Get "system" keys to re-use if phab account uses the + // same public key + $system_keys = getSystemPublicKeys($keydir); + + // Get list of all repos which is awailable for read + $all_repositories = array(); + foreach ($old_configuration as $group => $values) { + if (startswith($group, 'repo')) { + $repository_name = substr($group, 5, strlen($group) - 5); + if ($repository_name == 'gitosis-admin') + continue; + $all_repositories[] = $repository_name; + } + } + // Fill in new configuration and keys $used_keys = array(); $repositories = id(new PhabricatorRepositoryQuery()) @@ -157,7 +198,8 @@ function rebuildConfiguration($gitosis_root) { $type = $repository->getVersionControlSystem(); if ($type == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) { handleSingleRepository( - $keydir, $viewer, $repository, $new_configuration, $used_keys); + $keydir, $viewer, $repository, $all_repositories, $system_keys, + $new_configuration, $used_keys); } }