]> git.atlas4tour.it Git - pia_atlas.git/commitdiff
- Implementazione permessi nelle view
authorCostantino Vitale <costantino.vitale@dyrecta.com>
Mon, 10 Oct 2022 11:24:35 +0000 (13:24 +0200)
committerCostantino Vitale <costantino.vitale@dyrecta.com>
Mon, 10 Oct 2022 11:24:35 +0000 (13:24 +0200)
- Salvataggio multimedia per i poi

.idea/misc.xml
.idea/socoin_atlas.iml
sistema/forms.py
sistema/models.py
sistema/templates/add_mod_percorso.html
sistema/templates/add_mod_poi.html
sistema/templates/base.html
sistema/views.py
socoin_atlas/urls.py
utenti/mixins.py
utenti/views.py

index d28790de07edb35c6cca22cd03eb28b8454e328a..ec83ff998036e2d2bfc49cbce7d3cc49f09891d4 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
-  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (pia_atlas)" project-jdk-type="Python SDK" />
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (socoin_atlas)" project-jdk-type="Python SDK" />
 </project>
\ No newline at end of file
index a312c3aab382f77006378fb8bd673b1eb2064314..0220ca76843f5d4264d714ea5048b95a1c676569 100644 (file)
@@ -16,7 +16,7 @@
     <content url="file://$MODULE_DIR$">
       <excludeFolder url="file://$MODULE_DIR$/env" />
     </content>
-    <orderEntry type="jdk" jdkName="Python 3.7 (pia_atlas)" jdkType="Python SDK" />
+    <orderEntry type="jdk" jdkName="Python 3.7 (socoin_atlas)" jdkType="Python SDK" />
     <orderEntry type="sourceFolder" forTests="false" />
   </component>
   <component name="TemplatesService">
index 1efb005682fb27386bd7c68b10c0c44b212aa55e..f90e1327185e8f1027062db71a8df241f50b99c5 100644 (file)
@@ -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'})
index 5baf7aa3fe761f72177976d60e9034935ef1bf8c..fe5d3ca049bd38dd655a268073a835e0a56b3ab5 100644 (file)
@@ -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)
index e34355dc01cdf351bb6f9acddc9d0f000625eead..b17fe89baec1380f86416cea5ffee73f8eff359f 100644 (file)
@@ -28,6 +28,7 @@
                                     {{form | crispy }}
                             </form>
 
+                            <br>
                             <br>
                             <h5>Seleziona i punti di interesse</h5>
                             <br>
 
                                 <br />
                                 <button class="btn-sm btn-primary" onclick="getCoordinates()">Genera Percorso</button>
-                                <button class="btn-sm btn-primary" onclick="getList()">Reset</button>
-
-                                <br>
-                                <br>
-                                <button class="btn-sm btn-success" type="button" onclick="saveItinerary()">Salva</button>
-
 
                             </div>
                         </div>
                         <div id="map-div" class="col-lg-9 col-md-9 col-sm-9 col-xs-9 pr-0 pt-3">
-                            <div id="map" style="height: 650px"></div>
+                            <div id="map" style="height: 1000px"></div>
                             <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDzVvxHi5OWsa7R7Rg5lrXQynqPgU0oiD0&callback=initMap"
                                     async></script>
                         </div>
                     </div>
                 </div>
-{% for point in associated_tappe %}
-    {{ point.poi_id }}
-            {% endfor %}
+                     <div class="card-footer text-right">
+                        <button class="btn-sm btn-success" type="button" onclick="saveItinerary()">Salva</button>
+                    </div>
             </div>
         </div>
     </div>
index 255591438622b63dfaf9f86cbb14301fbba042d7..2808607749c801abd8186a5db92e4d69403ea7f3 100644 (file)
                         {% endif %}
                             {{form | crispy }}
                             <br>
-                        <div class="card-footer text-right">
-                            <button class="btn btn-primary" type="button" onclick="javascript:this.form.submit();"><i class="fas fa-save" aria-hidden="true"></i> Salva
-                            </button>
-                        </div>
-
+                    </form>
+                    <hr>
+                    <div class="section-title mt-0">Multimedia</div>
+                    <form method="POST" id="multimedia_form" action="{% url 'sistema:poi' %}">{% csrf_token %}
+                        {{form_multimedia | crispy }}
                     </form>
                 </div>
 
+                <div class="card-footer text-right">
+                    <button class="btn btn-primary" type="button" onclick="submitForms()"><i class="fas fa-save" aria-hidden="true"></i> Salva
+                    </button>
+                </div>
             </div>
         </div>
     </div>
 
 
     <script>
+        function objectifyForm(formArray) {
+            //serialize data function
+            var returnArray = {};
+            for (var i = 0; i < formArray.length; i++) {
+                returnArray[formArray[i]['name']] = formArray[i]['value'];
+            }
+            return returnArray;
+        }
+
+        function submitForms(){
+            poi_form = objectifyForm($('#poi_form').serializeArray());
+            multimedia_form = objectifyForm($('#multimedia_form').serializeArray());
+
+            method = ''
+            pk_poi_form = ''
+            pk_multimedia_form = ''
+            {% if form.instance.pk %}
+                method = 'mod'
+                pk_poi_form = {{ form.instance.pk }}
+                pk_multimedia_form = {{ form_multimedia.instance.pk }}
+            {% endif %}
+
+          $.ajax({
+                data: {
+                    'poi_form': JSON.stringify(poi_form),
+                    'multimedia_form': JSON.stringify(multimedia_form),
+                    'pk_poi_form': pk_poi_form,
+                    'pk_multimedia_form': pk_multimedia_form,
+                    'method': method,
+                },
+                type: "POST",
+                url: '{% url 'sistema:poi' %}',
+                "headers": {'X-CSRFToken': '{{ csrf_token }}'},
+            })
+                .done(function (response) {
+                    Swal.fire('', "Operazione effettuata con successo", "success").then((value) => {
+                        location.reload();
+                    });
+                })
+                .fail(function (jqXHR, textStatus, errorThrown) {
+                    errore = ''
+                    if (typeof jqXHR.responseText.reason === 'string' || jqXHR.responseText.reason instanceof String) {
+                        errore = jqXHR.responseText
+                    } else {
+                        for (var i = 0; i < jqXHR.responseJSON.reason.length; i++) {
+                            errore += jqXHR.responseJSON.reason[i]
+                            errore += '<br>'
+                        }
+                    }
+                    Swal.fire("Attenzione!", errore, "error")
+
+                });
 
+        }
     </script>
 
 
index 6f0ead2b179f387ac93675ac13a6ab09e5127289..43d0da30cdb059980613ec5d911d12c086f56eef 100644 (file)
                         <ul class="dropdown-menu" id="menu-drop">
                             <li><a class="nav-link" href="{% url 'sistema:poi_list' %}">Lista punti di interesse</a></li>
                             <li><a class="nav-link" href="{% url 'sistema:tipo_multimedia_list' %}">Tipologia multimedia</a></li>
-                            <li><a class="nav-link" href="#">Multimedia</a></li>
                         </ul>
                     </li>
 
index ebcb15a2720c74e71852d364e0a5731aec9a08bc..ccd16b70e6e0e90677d929ef3b83f0bade30bea3 100644 (file)
@@ -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')))
index 87fdf7d71e69ec436aec2c8879555e3b141222a8..37061b89512b3d67dc456260b337c9bc42ac856f 100644 (file)
@@ -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()
index f3f4e341a3594130071265c5df0eae223712e893..7500a35210819edea171d0b2607a12b9c1df262c 100644 (file)
@@ -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
index 3df8067885cb052d8a41b38c62154ba7e1535ba1..26637a8c0fa6edf5256b995a29e75386828a6148 100644 (file)
@@ -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)