Sunil Mohan Adapa b91f1cf922
gitweb: Use privileged decorator for actions
Tests:

- Functions tests work
- Initial setup works
  - Global default branch is set to 'main'
- Creating an repository works
- Cloning a repository works
  - Progress is shown on the app page
- List of repositories is shown properly in the app page
- Deleting a repo works
- Editing a repository works
  - Repository information is shown properly in the form
  - Renaming a repository
  - Setting description
  - Setting owner
  - Setting a repository private/public
  - Setting default branch (list of branches is shown properly)
  - Error is thrown properly when a remote repository does not exist
- Errors are handled properly when creating/editing/deleting repo

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2022-10-08 18:52:02 -04:00

154 lines
4.9 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-or-later
"""Django views for Gitweb."""
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.http import Http404
from django.shortcuts import redirect
from django.template.response import TemplateResponse
from django.urls import reverse_lazy
from django.utils.translation import gettext as _
from django.views.generic import FormView
from plinth import app as app_module
from plinth import views
from plinth.modules import gitweb
from . import privileged
from .forms import CreateRepoForm, EditRepoForm
class GitwebAppView(views.AppView):
"""Serve configuration page."""
app_id = 'gitweb'
template_name = 'gitweb_configure.html'
def get_context_data(self, *args, **kwargs):
"""Add repositories to the context data."""
context = super().get_context_data(*args, **kwargs)
repos = gitweb.get_repo_list()
context['repos'] = repos
context['cloning'] = any('clone_progress' in repo for repo in repos)
if context['cloning']:
context['refresh_page_sec'] = 3
return context
class CreateRepoView(SuccessMessageMixin, FormView):
"""View to create a new repository."""
form_class = CreateRepoForm
prefix = 'gitweb'
template_name = 'form.html'
success_url = reverse_lazy('gitweb:index')
success_message = _('Repository created.')
def get_context_data(self, **kwargs):
"""Return additional context for rendering the template."""
context = super().get_context_data(**kwargs)
context['title'] = _('Create Repository')
return context
def form_valid(self, form):
"""Create the repository on valid form submission."""
form_data = {}
for key, value in form.cleaned_data.items():
if value is None:
form_data[key] = ''
else:
form_data[key] = value
try:
gitweb.create_repo(form_data['name'], form_data['description'],
form_data['owner'], form_data['is_private'])
except Exception as error:
self.success_message = ''
messages.error(
self.request, "{0} {1}".format(
_('An error occurred while creating the repository.'),
error))
else:
app_module.App.get('gitweb').update_service_access()
return super().form_valid(form)
class EditRepoView(SuccessMessageMixin, FormView):
"""View to edit an existing repository."""
form_class = EditRepoForm
prefix = 'gitweb'
template_name = 'form.html'
success_url = reverse_lazy('gitweb:index')
success_message = _('Repository edited.')
def get_context_data(self, **kwargs):
"""Return additional context for rendering the template."""
context = super().get_context_data(**kwargs)
context['title'] = _('Edit repository')
return context
def get_initial(self):
"""Load information about repository being edited."""
name = self.kwargs['name']
for repo in gitweb.get_repo_list():
if repo['name'] == name and 'clone_progress' not in repo:
break
else:
raise Http404
return gitweb.repo_info(name)
def form_valid(self, form):
"""Edit the repo on valid form submission."""
if form.initial != form.cleaned_data:
form_data = {}
for key, value in form.cleaned_data.items():
if value is None:
form_data[key] = ''
else:
form_data[key] = value
try:
gitweb.edit_repo(form.initial, form_data)
except Exception:
messages.error(self.request,
_('An error occurred during configuration.'))
app_module.App.get('gitweb').update_service_access()
return super().form_valid(form)
def delete(request, name):
"""Handle deleting repositories, showing a confirmation dialog first.
On GET, display a confirmation page.
On POST, delete the repository.
"""
for repo in gitweb.get_repo_list():
if repo['name'] == name and 'clone_progress' not in repo:
break
else:
raise Http404
app = app_module.App.get('gitweb')
if request.method == 'POST':
try:
privileged.delete_repo(name)
messages.success(request, _('{name} deleted.').format(name=name))
except Exception as error:
messages.error(
request,
_('Could not delete {name}: {error}').format(
name=name, error=error),
)
app.update_service_access()
return redirect(reverse_lazy('gitweb:index'))
return TemplateResponse(request, 'gitweb_delete.html', {
'title': app.info.name,
'name': name
})