From: Costantino Vitale Date: Mon, 10 Oct 2022 11:24:35 +0000 (+0200) Subject: - Implementazione permessi nelle view X-Git-Url: https://git.atlas4tour.it/?a=commitdiff_plain;h=d37aeff9daaf4efa53b5a3aafbddec9fbf3707c8;p=pia_atlas.git - Implementazione permessi nelle view - Salvataggio multimedia per i poi --- diff --git a/.idea/misc.xml b/.idea/misc.xml index d28790d..ec83ff9 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/.idea/socoin_atlas.iml b/.idea/socoin_atlas.iml index a312c3a..0220ca7 100644 --- a/.idea/socoin_atlas.iml +++ b/.idea/socoin_atlas.iml @@ -16,7 +16,7 @@ - + diff --git a/sistema/forms.py b/sistema/forms.py index 1efb005..f90e132 100644 --- a/sistema/forms.py +++ b/sistema/forms.py @@ -1,8 +1,6 @@ -from datetime import datetime from django.contrib.auth.forms import * - -from sistema.models import Localita, TipologiaMultimedia, Gestisce, PointOfInterest, Percorso +from sistema.models import Localita, TipologiaMultimedia, Gestisce, PointOfInterest, Percorso, Multimedia class LocalitaForm(forms.ModelForm): @@ -96,3 +94,23 @@ class GestisceForm(forms.ModelForm): self.fields['localita'] = forms.ModelChoiceField(queryset=localita, widget=forms.Select(attrs={'class': 'form-control'}), initial='') self.fields['data_inizio'].widget.attrs.update({'class': 'form-control'}) self.fields['data_fine'].widget.attrs.update({'class': 'form-control'}) + + +class MultimediaForm(forms.ModelForm): + media = forms.FileField( + label='Icona (se non caricata verrà inserita una di default)', + required=False, + widget=forms.FileInput(attrs={'class': 'form-control', 'form': 'multimedia_form'}) + ) + + class Meta: + model = Multimedia + exclude = ('poi', 'is_active',) + + def __init__(self, *args, **kwargs): + super(MultimediaForm, self).__init__(*args, **kwargs) + tipologia = TipologiaMultimedia.objects.filter(is_active=True) + self.fields['tipologia'] = forms.ModelChoiceField(queryset=tipologia, widget=forms.Select(attrs={'class': 'form-control'}), initial='') + self.fields['testo'].required = False + for f in self.fields: + self.fields[f].widget.attrs.update({'class': 'form-control'}) diff --git a/sistema/models.py b/sistema/models.py index 5baf7aa..fe5d3ca 100644 --- a/sistema/models.py +++ b/sistema/models.py @@ -3,6 +3,9 @@ from django.contrib.auth.models import User from django.utils import timezone from rest_framework import serializers +from socoin_atlas.settings import MEDIA_ROOT, STATICFILES_DIRS, STATIC_URL + + class Localita(models.Model): descrizione = models.CharField(max_length=255, null=False) provincia = models.CharField(max_length=50, null=True, blank=True) @@ -78,15 +81,24 @@ class TipologiaMultimedia(models.Model): nome = models.CharField(max_length=255, null=False) is_active = models.BooleanField(default=True) + def __str__(self): + return self.nome + class Multimedia(models.Model): tipologia = models.ForeignKey(TipologiaMultimedia, on_delete=models.DO_NOTHING) - path = models.CharField(max_length=255, null=False) + poi = models.ForeignKey(PointOfInterest, on_delete=models.DO_NOTHING, null=True) + media = models.FileField(upload_to='poi_media/', null=True) nome = models.CharField(max_length=255, null=False) descrizione = models.CharField(max_length=255, null=False) testo = models.TextField(max_length=255, null=False) is_active = models.BooleanField(default=True) + def save(self, *args, **kwargs): + if not self.media: + self.media = STATIC_URL + 'assets/img/image-64.png' + super().save() + class Feedback(models.Model): utente = models.ForeignKey(User, on_delete=models.DO_NOTHING) diff --git a/sistema/templates/add_mod_percorso.html b/sistema/templates/add_mod_percorso.html index e34355d..b17fe89 100644 --- a/sistema/templates/add_mod_percorso.html +++ b/sistema/templates/add_mod_percorso.html @@ -28,6 +28,7 @@ {{form | crispy }} +

Seleziona i punti di interesse

@@ -56,25 +57,19 @@
- - -
-
- -
-
+
-{% for point in associated_tappe %} - {{ point.poi_id }} - {% endfor %} + diff --git a/sistema/templates/add_mod_poi.html b/sistema/templates/add_mod_poi.html index 2555914..2808607 100644 --- a/sistema/templates/add_mod_poi.html +++ b/sistema/templates/add_mod_poi.html @@ -23,21 +23,78 @@ {% endif %} {{form | crispy }}
- - + +
+
Multimedia
+
{% csrf_token %} + {{form_multimedia | crispy }}
+ diff --git a/sistema/templates/base.html b/sistema/templates/base.html index 6f0ead2..43d0da3 100644 --- a/sistema/templates/base.html +++ b/sistema/templates/base.html @@ -193,7 +193,6 @@ diff --git a/sistema/views.py b/sistema/views.py index ebcb15a..ccd16b7 100644 --- a/sistema/views.py +++ b/sistema/views.py @@ -8,32 +8,34 @@ from django.views import View from django.views.generic import TemplateView from rest_framework import status -from sistema.forms import LocalitaForm, TipoMultimediaForm, PoiForm, PercorsoForm -from sistema.models import Localita, TipologiaMultimedia, PointOfInterest, Percorso, Tappa, TappaSerializer +from sistema.forms import LocalitaForm, TipoMultimediaForm, PoiForm, PercorsoForm, MultimediaForm +from sistema.models import Localita, TipologiaMultimedia, PointOfInterest, Percorso, Tappa, TappaSerializer, Multimedia from socoin_atlas import settings from utenti.mixins import CustomLoginRequiredMixin from django.template.defaultfilters import register -@register.filter(name='dict_key') -def dict_key(d, k): - '''Returns the given key from a dictionary.''' - return d[k] +class LocalitaListView(TemplateView):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] - -class LocalitaListView(TemplateView): template_name = 'localita_list.html' -class PuntiInteresseListView(TemplateView): +class PuntiInteresseListView(TemplateView):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] + template_name = 'poi_list.html' -class TipologiaMultimediaListView(TemplateView): +class TipologiaMultimediaListView(TemplateView):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] + template_name = 'tipo_multimedia_list.html' -class MultimediaListView(TemplateView): +class MultimediaListView(TemplateView):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] + template_name = 'multimedia_list.html' @@ -46,7 +48,9 @@ class Home(View): # CustomLoginRequiredMixin return render(request, 'home.html', {}) -class LocalitaView(View): +class LocalitaView(View):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] + def add_localita(self, request): form = LocalitaForm(request.POST) if form.is_valid(): @@ -95,7 +99,9 @@ class LocalitaView(View): return redirect(reverse('sistema:localita_list')) -class TipoMultimediaView(View): +class TipoMultimediaView(View):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] + def add_tipologia(self, request): form = TipoMultimediaForm(request.POST) if form.is_valid(): @@ -144,7 +150,8 @@ class TipoMultimediaView(View): return redirect(reverse('sistema:tipo_multimedia_list')) -class PoiView(View): +class PoiView(View):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] def get_coordinates(self): start = int(self.GET.get('start')) @@ -172,10 +179,16 @@ class PoiView(View): return JsonResponse({'response': poi_coords}, status=status.HTTP_200_OK) def add_poi(self, request): - form = PoiForm(request.POST) + form = PoiForm(data=json.loads(request.POST.get('poi_form'))) if form.is_valid(): form.save() + multimedia_form = MultimediaForm(data=json.loads(request.POST.get('multimedia_form'))) + if multimedia_form.is_valid(): + multimedia = multimedia_form.save(commit=False) + multimedia.poi = form.instance + multimedia.save() + messages.add_message(request, messages.INFO, 'Nuova punto di interesse inserito con successo.') else: errors = '' @@ -188,6 +201,10 @@ class PoiView(View): if form.is_valid(): form.save() + multimedia_form = MultimediaForm(data=json.loads(request.POST.get('multimedia_form')), instance=Multimedia.objects.get(pk=int(self.request.POST.get('pk_multimedia_form')))) + if multimedia_form.is_valid(): + multimedia_form.save() + messages.add_message(request, messages.INFO, 'Punto di interesse aggiornata con successo.') else: errors = '' @@ -206,12 +223,13 @@ class PoiView(View): return JsonResponse({'response': 'Punto di interesse eliminato con successo'}, status=status.HTTP_200_OK) elif 'pk' in kwargs: - return render(request, 'add_mod_poi.html', {'form': PoiForm(instance=PointOfInterest.objects.get(pk=int(self.kwargs['pk'])))}) + return render(request, 'add_mod_poi.html', {'form': PoiForm(instance=PointOfInterest.objects.get(pk=int(self.kwargs['pk']))), + 'form_multimedia': MultimediaForm(instance=Multimedia.objects.get(poi_id=int(self.kwargs['pk'])))}) else: - return render(request, 'add_mod_poi.html', {'form': PoiForm()}) + return render(request, 'add_mod_poi.html', {'form': PoiForm(), 'form_multimedia': MultimediaForm()}) def post(self, request, *args, **kwargs): - if 'mod' in request.POST: + if self.request.POST.get('method') == 'mod': self.mod_poi(request) else: self.add_poi(request) @@ -219,7 +237,8 @@ class PoiView(View): return redirect(reverse('sistema:poi_list')) -class PercorsoView(View): +class PercorsoView(View):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] def del_poi(self, request): percorso = Percorso.objects.get(pk=int(request.GET.get('pk'))) diff --git a/socoin_atlas/urls.py b/socoin_atlas/urls.py index 87fdf7d..37061b8 100644 --- a/socoin_atlas/urls.py +++ b/socoin_atlas/urls.py @@ -13,14 +13,17 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ +from django.conf.urls.static import static from django.contrib import admin +from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.urls import path, include from django.contrib.auth import views as auth_views +from socoin_atlas import settings urlpatterns = [ path('admin/', admin.site.urls), path('', include(('sistema.urls', 'sistema'), namespace='sistema')), path('utenti/', include(('utenti.urls', 'utenti'), namespace='utenti')), path('api/', include(('api.urls', 'api'), namespace='api')), -] +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + staticfiles_urlpatterns() diff --git a/utenti/mixins.py b/utenti/mixins.py index f3f4e34..7500a35 100644 --- a/utenti/mixins.py +++ b/utenti/mixins.py @@ -1,5 +1,6 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.core.exceptions import PermissionDenied +from django.shortcuts import redirect from django.urls import reverse_lazy from django.views import View from rest_framework.permissions import IsAuthenticated @@ -15,40 +16,27 @@ class APIViewAuthenticated(APIView): permission_classes = [IsAuthenticated] -class PermissionRequiredMixin(object): - permission_required = None +class AuthorizationRequiredMixin(object): + authorization_required = None def dispatch(self, request, *args, **kwargs): if request.user.is_authenticated: - if request.session.get('structure'): - user_perms = request.user.get_all_permissions_by_structure_flat(request.session['structure']) - if len(set(user_perms).intersection(self.permission_required)) <= 0: - raise PermissionDenied - return super(PermissionRequiredMixin, self).dispatch(request, *args, **kwargs) - else: - user_perms = request.user.get_all_permissions_flat() - if len(set(user_perms).intersection(self.permission_required)) <= 0: - raise PermissionDenied - return super(PermissionRequiredMixin, self).dispatch(request, *args, **kwargs) + return super(AuthorizationRequiredMixin, self).dispatch(request, *args, **kwargs) else: - raise PermissionDenied + return redirect('/login/') -class AuthorizationRequiredMixin(object): - authorization_required = None +class PermissionRequiredMixin(object): + permission_required = None def dispatch(self, request, *args, **kwargs): if request.user.is_authenticated: - if request.session.get('structure'): - user_authorization = request.user.get_all_authorizations_by_structure_flat(request.session['structure']) - if len(set(user_authorization).intersection(self.authorization_required)) <= 0: - raise PermissionDenied - return super(AuthorizationRequiredMixin, self).dispatch(request, *args, **kwargs) + user_perms = request.session.get('roles') + if user_perms: + if len(set(user_perms).intersection(self.permission_required)) <= 0: + return redirect('/login/') + return super(PermissionRequiredMixin, self).dispatch(request, *args, **kwargs) else: - user_authorization = request.user.get_all_authorizations_flat() - if len(set(user_authorization).intersection(self.authorization_required)) <= 0: - raise PermissionDenied - return super(AuthorizationRequiredMixin, self).dispatch(request, *args, **kwargs) + return redirect('/login/') else: - raise PermissionDenied - + return redirect('/login/') \ No newline at end of file diff --git a/utenti/views.py b/utenti/views.py index 3df8067..26637a8 100644 --- a/utenti/views.py +++ b/utenti/views.py @@ -81,19 +81,27 @@ class Register(View): return redirect('utenti:register') -class AdminListView(TemplateView): +class AdminListView(TemplateView):#PermissionRequiredMixin + #permission_required = [settings.ADMIN_GROUPS] + template_name = 'admin_list.html' -class TourOperatorListView(TemplateView): +class TourOperatorListView(TemplateView):#PermissionRequiredMixin + #permission_required = [settings.ADMIN_GROUPS] + template_name = 'tour_operator_list.html' -class ClientiListView(TemplateView): +class ClientiListView(TemplateView):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] + template_name = 'clienti_list.html' -class TourOperatorView(View): +class TourOperatorView(View):#PermissionRequiredMixin + #permission_required = [settings.ADMIN_GROUPS] + def add_tour_operator(self, request): form = TourOperatorNewForm(data=json.loads(request.POST.get('tour_operator_form'))) if form.is_valid(): @@ -162,7 +170,9 @@ class TourOperatorView(View): return redirect(reverse('utenti:touroperator_list')) -class ClienteView(View): +class ClienteView(View):#PermissionRequiredMixin + #permission_required = [settings.TOUR_OPERATOR_GROUPS, settings.ADMIN_GROUPS] + def del_cliente(self, request): cliente = User.objects.get(pk=int(request.GET.get('pk'))) cliente.is_active = False @@ -174,7 +184,8 @@ class ClienteView(View): return JsonResponse({'response': 'Cliente eliminato con successo'}, status=status.HTTP_200_OK) -class AdminView(View): +class AdminView(View):#PermissionRequiredMixin + #permission_required = [settings.ADMIN_GROUPS] def add_admin(self, request): form = AdminForm(request.POST)