def test_locking_scenario(self): session = SessionStore() session.save() other_session = SessionStore() other_session.save() # Lock object in session lock_for_session(self.test_model_instance, session) # Check that object is locked self.assertTrue(self.test_model_instance.is_locked()) self.assertTrue(check_for_session(self.test_model_instance, session)) # Try to lock/unlock object from another session with self.assertRaises(AlreadyLockedError): lock_for_session(self.test_model_instance, other_session) with self.assertRaises(UnlockForbiddenError): unlock_for_session(self.test_model_instance, other_session) self.assertFalse( check_for_session(self.test_model_instance, other_session)) # Unlock object unlock_for_session(self.test_model_instance, session) # Ensure object is unlocked self.assertFalse(self.test_model_instance.is_locked()) self.assertFalse(check_for_session(self.test_model_instance, session)) self.assertFalse( check_for_session(self.test_model_instance, other_session))
def edit_home_text(request): """Display form to edit home text (french and english).""" text, _ = GeneralPreferences.objects.get_or_create() try: lock_for_session(text, request.session) except AlreadyLockedError: messages.error( request, "Impossible de modifier le texte : il est en modification.") return redirect(request.META.get('HTTP_REFERER', '/')) form = HomeTextEditForm(request.POST or None, instance=text) if form.is_valid(): if not check_for_session(text, request.session): messages.error( request, "Impossible de modifier le texte : il est en modification.") return redirect(request.META.get('HTTP_REFERER', '/')) messages.success(request, "Le texte d'accueil a bien été modifié") form.save() unlock_for_session(text, request.session) return redirect(reverse('documents:index')) return render( request, "form.html", { "form": form, "form_title": "Modification du texte d'accueil", "form_button": "Modifier", "form_icon": "pencil-alt" })
def save_model(self, request, obj, form, change): if change: if not check_for_session(obj, request.session): raise PermissionDenied("Invalid lock, cannot save.") try: # Renew lock to make sure it is still valid when saving lock_for_session(obj, request.session) except AlreadyLockedError: # Race condition: lock expired just after the check_for_session call and # someone else locked the object before the lock_for_session call raise PermissionDenied("Lock has expired, cannot save.") super(LockableModelAdmin, self).save_model(request, obj, form, change) if change: unlock_for_session(obj, request.session)
def wrapped(request, *args, **kwargs): object_id = get_object_id_fn(request, *args, **kwargs) obj = model.objects.get(id=object_id) try: lock_for_session(obj, request.session) except AlreadyLockedError: return HttpResponseForbidden( "The object you are trying to access is " "locked.") lock_holder = LockHolder(obj) lock_holder.start() try: response = view(request, *args, **kwargs) finally: lock_holder.stop() unlock_for_session(obj, request.session) return response
def edit_room(request, pk): """ Display a form to edit a room pk : primary key of a room """ search_form = SearchForm() room = get_object_or_404(Room, pk=pk) try: lock_for_session(room, request.session) except AlreadyLockedError: messages.error( request, "Impossible de modifier la chambre : elle est en cours de modification." ) return redirect(request.META.get('HTTP_REFERER', '/')) room_form = RoomForm(request.POST or None, instance=room) if 'cancel' in request.POST: messages.success(request, "Demande annulée") unlock_for_session(room, request.session) return redirect(request.POST.get('cancel') or "home") if room_form.is_valid(): if not check_for_session(room, request.session): messages.error( request, "Impossible de modifier la chambre : elle est en cours de modification." ) return redirect(request.META.get('HTTP_REFERER', '/')) room_form.save() messages.success( request, "Les modifications ont bien été enregistrées") unlock_for_session(room, request.session) return redirect(reverse('gestion:roomProfile', kwargs={'pk': room.pk})) return render( request, "gestion/edit_room.html", { "sidebar": True, "room": room, "search_form": search_form, "roomForm": room_form } )
def edit_leasing(request, pk): """ Display form to edit a leasing pk : primary key of a leasing """ search_form = SearchForm() leasing = get_object_or_404(Leasing, pk=pk) try: lock_for_session(leasing, request.session) except AlreadyLockedError: messages.error( request, "Impossible de modifier le dossier : il est en cours de modification." ) return redirect(request.META.get('HTTP_REFERER', '/')) leasing_form = LeasingForm(request.POST or None, instance=leasing) if 'cancel' in request.POST: messages.success(request, "Demande annulée") unlock_for_session(leasing, request.session) return redirect(request.POST.get('cancel') or "home") if leasing_form.is_valid(): if not check_for_session(leasing, request.session): messages.error( request, "Impossible de modifier le dossier : il est en cours de modification.") return redirect(request.META.get('HTTP_REFERER', '/')) leasing_form.save() messages.success( request, "Les modifications ont bien été enregistrées") unlock_for_session(leasing, request.session) return redirect(reverse('gestion:leasingProfile', kwargs={'pk': leasing.pk})) return render( request, "gestion/edit_leasing.html", { "sidebar": True, "leasing": leasing, "leasingForm": leasing_form, "search_form": search_form } )
def edit_tenant(request, pk): """ Display a form to edit a tenant pk : primary key of a tenant """ search_form = SearchForm() tenant = get_object_or_404(Tenant, pk=pk) try: lock_for_session(tenant, request.session) except AlreadyLockedError: messages.error( request, "Impossible de modifier le locataire : il est en cours de modification." ) return redirect(request.META.get('HTTP_REFERER', '/')) tenant_form = TenantForm(request.POST or None, instance=tenant) if 'cancel' in request.POST: messages.success(request, "Demande annulée") unlock_for_session(tenant, request.session) return redirect(request.POST.get('cancel') or "home") if tenant_form.is_valid(): if not check_for_session(tenant, request.session): messages.error( request, "Impossible de modifier le locataire : il est en cours de modification." ) return redirect(request.META.get('HTTP_REFERER', '/')) tenant_form.save() messages.success(request, "Les modifications ont été enregistrées") unlock_for_session(tenant, request.session) return redirect(reverse('gestion:tenantProfile', kwargs={'pk': tenant.pk})) return render( request, "gestion/edit_tenant.html", { "sidebar": True, "tenant": tenant, "tenantForm": tenant_form, "search_form": search_form } )