Veiko Aasa c8eb5bb3ca
gitweb: Add tests for actions script
- add tests for create, edit and delete repository functions
- modify actions script to allow run actions without root privileges:
  - add argument --git-repo-root to overwrite the default root directory
    of repositories
  - add option --keep-ownership to the create-repo command to skip
    changing ownership to www-data
- actions script, repo-info command: instead of returning empty values,
  raise an error if the repository doesn't exist

Closes #1667

Signed-off-by: Veiko Aasa <veiko17@disroot.org>
[sunil@medhas.org Remove unneeded #! directive]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2019-10-26 21:27:28 -07:00

234 lines
8.1 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/python3
#
# This file is part of FreedomBox.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Configuration helper for Gitweb.
"""
import argparse
import configparser
import json
import os
import shutil
import subprocess
from plinth import action_utils
from plinth.modules.gitweb.manifest import GIT_REPO_PATH
def parse_arguments():
"""Return parsed command line arguments as dictionary."""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
subparsers.add_parser(
'setup', help='Perform post-installation operations for Gitweb')
subparser = subparsers.add_parser('create-repo',
help='Create a new repository')
subparser.add_argument('--name', required=True,
help='Name of the repository')
subparser.add_argument('--description', required=True,
help='Description of the repository')
subparser.add_argument('--owner', required=True,
help='Repositorys owner name')
subparser.add_argument(
'--is-private', required=False, default=False, action='store_true',
help='Allow only authorized users to access this repository')
subparser.add_argument(
'--keep-ownership', required=False, default=False, action="store_true",
help='Do not chanege ownership of the repository directory')
subparser = subparsers.add_parser(
'repo-info', help='Get information about the repository')
subparser.add_argument('--name', required=True,
help='Name of the repository')
subparser = subparsers.add_parser('rename-repo',
help='Rename an repository')
subparser.add_argument('--oldname', required=True,
help='Old name of the repository')
subparser.add_argument('--newname', required=True,
help='New name of the repository')
subparser = subparsers.add_parser('set-repo-description',
help='Set description of the repository')
subparser.add_argument('--name', required=True,
help='Name of the repository')
subparser.add_argument('--description', required=True,
help='Description of the repository')
subparser = subparsers.add_parser('set-repo-owner',
help='Set repository\'s owner name')
subparser.add_argument('--name', required=True,
help='Name of the repository')
subparser.add_argument('--owner', required=True,
help='Repositorys owner name')
subparser = subparsers.add_parser(
'set-repo-access', help='Set repository as private or public')
subparser.add_argument('--name', required=True,
help='Name of the repository')
subparser.add_argument('--access', required=True,
choices=['public', 'private'], help='Access status')
subparser = subparsers.add_parser('delete-repo',
help='Delete an existing repository')
subparser.add_argument('--name', required=True,
help='Name of the repository to remove')
subparsers.required = True
return parser.parse_args()
def subcommand_setup(_):
"""Disable default Apache2 Gitweb configuration"""
action_utils.webserver_disable('gitweb')
def _get_repo_description(repo):
"""Set description of the repository."""
description_file = os.path.join(GIT_REPO_PATH, repo + '.git',
'description')
if os.path.exists(description_file):
with open(description_file, 'r') as file_handle:
description = file_handle.read()
else:
description = ''
return description
def _set_repo_description(repo, description):
"""Set description of the repository."""
description_file = os.path.join(GIT_REPO_PATH, repo + '.git',
'description')
with open(description_file, 'w') as file_handle:
file_handle.write(description)
def _get_repo_owner(repo):
"""Set repository's owner name."""
repo_config = os.path.join(GIT_REPO_PATH, repo + '.git', 'config')
config = configparser.ConfigParser()
config.read(repo_config)
try:
owner = config['gitweb']['owner']
except KeyError:
owner = ''
return owner
def _set_repo_owner(repo, owner):
"""Set repository's owner name."""
repo_config = os.path.join(GIT_REPO_PATH, repo + '.git', 'config')
config = configparser.ConfigParser()
config.read(repo_config)
if not config.has_section('gitweb'):
config.add_section('gitweb')
config['gitweb']['owner'] = owner
with open(repo_config, 'w') as file_handle:
config.write(file_handle)
def _get_access_status(repo):
"""Get repository's access status"""
private_file = os.path.join(GIT_REPO_PATH, repo + '.git', 'private')
if os.path.exists(private_file):
return 'private'
return 'public'
def _set_access_status(repo, status):
"""Set repository as private or public"""
private_file = os.path.join(GIT_REPO_PATH, repo + '.git', 'private')
if status == 'private':
open(private_file, 'a')
elif status == 'public':
if os.path.exists(private_file):
os.remove(private_file)
def subcommand_rename_repo(arguments):
"""Rename a repository."""
oldpath = os.path.join(GIT_REPO_PATH, arguments.oldname + '.git')
newpath = os.path.join(GIT_REPO_PATH, arguments.newname + '.git')
os.rename(oldpath, newpath)
def subcommand_set_repo_description(arguments):
"""Set description of the repository."""
_set_repo_description(arguments.name, arguments.description)
def subcommand_set_repo_owner(arguments):
"""Set repository's owner name."""
_set_repo_owner(arguments.name, arguments.owner)
def subcommand_set_repo_access(arguments):
"""Set repository's access status."""
_set_access_status(arguments.name, arguments.access)
def subcommand_repo_info(arguments):
"""Get information about repository."""
repo_path = os.path.join(GIT_REPO_PATH, arguments.name + '.git')
if not os.path.exists(repo_path):
raise RuntimeError('Repository not found')
print(
json.dumps(
dict(name=arguments.name, description=_get_repo_description(
arguments.name), owner=_get_repo_owner(arguments.name),
access=_get_access_status(arguments.name))))
def subcommand_create_repo(arguments):
"""Create a new git repository."""
os.chdir(GIT_REPO_PATH)
repo_name = arguments.name + '.git'
subprocess.check_call(['git', 'init', '--bare', repo_name])
if not arguments.keep_ownership:
subprocess.check_call(['chown', '-R', 'www-data:www-data', repo_name])
_set_repo_description(arguments.name, arguments.description)
_set_repo_owner(arguments.name, arguments.owner)
if arguments.is_private:
_set_access_status(arguments.name, 'private')
def subcommand_delete_repo(arguments):
"""Delete a git repository."""
repo_path = os.path.join(GIT_REPO_PATH, arguments.name + '.git')
shutil.rmtree(repo_path)
def main():
"""Parse arguments and perform all duties."""
arguments = parse_arguments()
subcommand = arguments.subcommand.replace('-', '_')
subcommand_method = globals()['subcommand_' + subcommand]
subcommand_method(arguments)
if __name__ == '__main__':
main()