from django.shortcuts import render,get_object_or_404,redirect from django.urls import reverse, reverse_lazy from django.http import HttpRequest,HttpResponse,Http404 from django.contrib.auth.mixins import LoginRequiredMixin,UserPassesTestMixin from django.core.exceptions import PermissionDenied from django.utils.translation import gettext as _ from .. import settings from ..models import Page from .base import View,FormView from ..forms import PageForm,PageAdminForm,PageDeleteForm class PageView(View): template_name = "tinywiki/page/view.html" bs_template_name = "tinywiki/page/bs-view.html" @classmethod def get_template_name(cls) -> str: if settings.USE_BOOTSTRAP: return cls.bs_template_name return cls.template_name def get_context_data(self,page,**kwargs): can_edit_page = False can_delete_page = False user = self.request.user if (user.is_staff): can_edit_page = True can_delete_page = True elif page.slug.startswith('tw-'): if user.has_perm('page.tinywiki-edit-system'): can_edit_page = True if user.has_perm('page.tinywiki-delete-system'): can_delete_page = True else: if (user.has_perm('page.tinywiki-edit-all') or (user.pk == page.author.pk and user.has_perm('page.tinywiki-edit'))): can_edit_page = True if (user.has_perm('page.tinywiki-delete-all') or (user.pk == page.author.pk and user.has_perm('page.tinywiki-delete'))): can_delete_page = True kwargs.update({'page':page, 'user_can_edit_wiki_page':can_edit_page, 'user_can_delete_wiki_page':can_delete_page, 'subtitle':page.title}) return super().get_context_data(**kwargs) def get(self,request:HttpRequest,slug:str)->HttpResponse: try: page = Page.objects.get(slug=slug) except Page.DoesNotExist: if self.page_is_creatable(slug): return redirect(reverse('tinywiki:page-create') + f"?slug={slug}") raise Http404() return render(request, self.get_template_name(), self.get_context_data(page=page)) class PageCreateView(LoginRequiredMixin,UserPassesTestMixin,FormView): template_name = "tinywiki/page/create.html" bs_template_name = "tinywiki/page/bs-create.html" form_class = PageForm def test_func(self) -> bool: if self.request.user.is_authenticated: if self.request.user.is_staff: return True return self.request.user.has_perm('tinywiki.tinywiki-create') return False def get_template_name(self) -> str: if settings.USE_BOOTSTRAP: return self.bs_template_name return self.template_name def get(self,request): return render(request, self.get_template_name(), self.get_context_data()) def get_context_data(self,**kwargs): context = super().get_context_data(**kwargs) context['create']=True context['slug'] = self.request.GET.get('slug',None) context.setdefault("title_extra","") context.setdefault("slug_extra","") context.setdefault("content_type_extra","") context.setdefault("status_extra","") context.setdefault("content_extra","") return context def form_invalid(self, form): if 'slug' in form.errors: slug_extra = "is-invalid" else: slug_extra = "is-valid" if 'title' in form.errors: title_extra = 'is-invalid' else: title_extra = 'is-valid' if 'status_data' in form.errors: status_extra = 'is-invalid' else: status_extra = 'is-valid' if 'content_type_data' in form.errors: content_type_extra = 'is-invalid' else: content_type_extra = 'is-valid' if 'content' in form.errors: content_extra = 'is-invalid' else: content_extra = 'is-valid' return render(self.request, self.get_template_name(), self.get_context_data( slug_extra=slug_extra, title_extra=title_extra, status_extra=status_extra, content_type_extra=content_type_extra, content_extra=content_extra, )) def form_valid(self,form): user = self.request.user instance = form.save(commit=False) if (instance.slug.startswith('tw-') and not user.is_staff and not user.has_perm('page.tinywiki-create-system')): return render(self.request, self.get_template_name(), self.get_context_data( slug_extra="is-invalid", title_extra="is-valid", status_extra="is-valid", content_type_extra="is-valid", content_extra="is-valid", )) instance.author = user instance.created_by = user instance.last_edited_by = user try: form.save(commit=True) if self.request.GET.get('save',"0") == "1": return redirect(reverse("tinywiki:page-edit",kwargs={"slug":instance.slug})) return redirect(reverse("tinywiki:page",kwargs={'slug':instance.slug})) except: return render(self.request, self.get_template_name(), self.get_context_data( slug_extra="is-invalid", title_extra="is-valid", status_extra="is-valid", content_type_extra="is-valid", content_extra="is-valid", )) class PageEditView(LoginRequiredMixin,UserPassesTestMixin,FormView): template_name = "tinywiki/page/edit.html" bs_template_name = "tinywiki/page/bs-edit.html" form_class = PageForm def test_func(self) -> bool: if self.request.user.is_authenticated: if self.request.user.is_staff: return True return False def get_template_name(self) -> str: if settings.USE_BOOTSTRAP: return self.bs_template_name return self.template_name def get_context_data(self,page,**kwargs): context = super().get_context_data(**kwargs) context['create']=False context['page']=page context.setdefault("title_extra","") context.setdefault("slug_extra","") context.setdefault("content_type_extra","") context.setdefault("status_extra","") context.setdefault("content_extra","") return context def form_invalid(self, form): if 'slug' in form.errors: slug_extra = "is-invalid" else: slug_extra = "is-valid" if 'title' in form.errors: title_extra = 'is-invalid' else: title_extra = 'is-valid' if 'status_data' in form.errors: status_extra = 'is-invalid' else: status_extra = 'is-valid' if 'content_type_data' in form.errors: content_type_extra = 'is-invalid' else: content_type_extra = 'is-valid' if 'content' in form.errors: content_extra = 'is-invalid' else: content_extra = 'is-valid' return render(self.request, self.get_template_name(), self.get_context_data( page=self.instance, slug_extra=slug_extra, title_extra=title_extra, status_extra=status_extra, content_type_extra=content_type_extra, content_extra=content_extra, )) def get(self,request,slug:str): instance = get_object_or_404(Page,slug=slug) user = request.user if (instance.slug.startswith('tw-') and not user.is_staff and not user.has_perm('page.tinywiki-edit-system')): raise PermissionDenied(_("Only staff users and wiki-admins are allowed to edit TinyWiki system pages!")) if user.pk != instance.author.pk: if not user.is_staff and not user.has_perm("page.tinywiki-edit-all"): raise PermissionDenied() else: if not user.has_perm('page.tinywiki-edit-all') or not user.has_perm('page.tinywiki-edit'): raise PermissionDenied() self.instance = instance return render(request, self.get_template_name(), self.get_context_data(page=instance)) def post(self,request,slug:str): instance = get_object_or_404(Page,slug=slug) user = request.user if (instance.slug.startswith('tw-') and not user.is_staff): raise PermissionDenied(_("Only staff users are allowed to edit TinyWiki system pages!")) if user.pk != instance.author.pk: if not user.is_staff and not user.has_perm("page.tinywiki-edit-all"): raise PermissionDenied() else: if not user.has_perm('page.tinywiki-edit-all') or not user.has_perm('page.tinywiki-edit'): raise PermissionDenied() self.instance = instance return super().post(request) def get_form(self): return self.get_form_class()(instance=self.instance,**self.get_form_kwargs()) def form_valid(self,form): user = self.request.user instance = form.save(commit=False) instance.created_by = user instance.last_edited_by = user try: form.save(commit=True) if self.request.GET.get('save',"0") == "1": return redirect(reverse("tinywiki:page-edit",kwargs={"slug":instance.slug})) return redirect(reverse("tinywiki:page",kwargs={'slug':instance.slug})) except: return render(self.request, self.get_template_name(), self.get_context_data(slug_invalid=True)) class PageDeleteView(LoginRequiredMixin,UserPassesTestMixin,FormView): template_name = "tinywiki/page/delete.html" form_class = PageDeleteForm def test_func(self) -> bool: if self.request.user.is_staff: return True if self.request.user.has_perm('tinyiwki-delete-all') or self.request.user.has_perm('tinywiki-delete'): return True return False def get(self,request:HttpRequest,slug:str)->HttpResponse: instance = get_object_or_404(Page,slug=slug) if not request.user.is_staff and not instance.author == request.user: raise PermissionDenied() return render(request, self.template_name, self.get_context_data(form=self.get_form_class()(), page=instance)) def form_invalid(self,form:PageDeleteForm)->HttpResponse: return redirect(reverse('tinywiki:page',kwargs={'slug':self.instance.slug})) def form_valid(self,form:PageDeleteForm)->HttpResponse: if self.instance.slug == form.cleaned_data['slug']: try: self.instance.delete() return redirect(reverse("tinywiki:home")) except: pass return redirect(reverse('tinywiki:page',kwargs={'slug':self.instance.slug})) def post(self,request:HttpRequest,slug:str)->HttpResponse: self.instance = get_object_or_404(Page,slug=slug) if not request.user.is_staff and not instance.author == request.user: raise PermissionDenied() return super().post(request) class HxPageEditView(LoginRequiredMixin,UserPassesTestMixin,FormView): template_name = "tinywiki/page/hx-edit.html" bs_template_name = "tinywiki/page/hx-bs-edit.html" form_class = PageForm def test_func(self) -> bool: if self.request.user.is_authenticated: if self.request.user.is_staff: return True if self.request.user.has_perm('tinywiki-edit-page') or self.request.user.has_perm('tinywiki-edit-all-pages'): return True return False def get_template_name(self) -> str: if settings.USE_BOOTSTRAP: return self.bs_template_name return self.template_name def get_context_data(self,**kwargs): context = super().get_context_data(**kwargs) context['create']=False context['page']=self.instance context.setdefault("title_extra","") context.setdefault("slug_extra","") context.setdefault("content_type_extra","") context.setdefault("status_extra","") context.setdefault("content_extra","") return context def form_invalid(self, form): if 'slug' in form.errors: slug_extra = "is-invalid" else: slug_extra = "is-valid" if 'title' in form.errors: title_extra = 'is-invalid' else: title_extra = 'is-valid' if 'status_data' in form.errors: status_extra = 'is-invalid' else: status_extra = 'is-valid' if 'content_type_data' in form.errors: content_type_extra = 'is-invalid' else: content_type_extra = 'is-valid' if 'content' in form.errors: content_extra = 'is-invalid' else: content_extra = 'is-valid' return render(self.request, self.get_template_name(), self.get_context_data( page=self.instance, )) def post(self,request,pk:int): instance = get_object_or_404(Page,pk=pk) user = request.user if (instance.slug.startswith('tw-') and not user.is_staff): raise PermissionDenied(_("Only staff users are allowed to edit TinyWiki system pages!")) if user.pk != instance.author.pk: if not user.is_staff and not user.has_perm("page.tinywiki-edit-all"): raise PermissionDenied() else: if not user.has_perm('page.tinywiki-edit-all') or not user.has_perm('page.tinywiki-edit'): raise PermissionDenied() self.instance = instance return super().post(request) def get_form(self): return self.get_form_class()(instance=self.instance,**self.get_form_kwargs()) def form_valid(self,form): user = self.request.user instance = form.save(commit=False) instance.created_by = user instance.last_edited_by = user try: form.save(commit=True) return render(self.request,self.get_template_name(),self.get_context_data(save_success=True)) except: return render(self.request, self.get_template_name(), self.get_context_data(save_success=False)) class HxPageDeleteView(View): pass