Merge pull request 'asegurnado paginas administrativas #88' (#89) from secure_admin_pages_#88 into main
Reviewed-on: OneTeam/don_confiao#89
This commit is contained in:
		
							
								
								
									
										5
									
								
								Rakefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Rakefile
									
									
									
									
									
								
							| @@ -65,6 +65,11 @@ namespace :dev do | |||||||
|     compose('exec', 'django', 'python', '/app/manage.py', 'test', '/app/don_confiao') |     compose('exec', 'django', 'python', '/app/manage.py', 'test', '/app/don_confiao') | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   desc 'terminal django' | ||||||
|  |   task :djangoShell do | ||||||
|  |     compose('exec', 'django', 'python', '/app/manage.py', 'shell') | ||||||
|  |   end | ||||||
|  |  | ||||||
|   desc 'crear migraciones' |   desc 'crear migraciones' | ||||||
|   task :makemigrations do |   task :makemigrations do | ||||||
|     compose('exec', 'django', 'python', '/app/manage.py', 'makemigrations') |     compose('exec', 'django', 'python', '/app/manage.py', 'makemigrations') | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ from rest_framework.response import Response | |||||||
| from rest_framework.status import HTTP_400_BAD_REQUEST | from rest_framework.status import HTTP_400_BAD_REQUEST | ||||||
| from rest_framework.views import APIView | from rest_framework.views import APIView | ||||||
|  |  | ||||||
| from .models import Sale, SaleLine, Customer, Product, ReconciliationJar, PaymentMethods | from .models import Sale, SaleLine, Customer, Product, ReconciliationJar, PaymentMethods, AdminCode | ||||||
| from .serializers import SaleSerializer, ProductSerializer, CustomerSerializer, ReconciliationJarSerializer, PaymentMethodSerializer, SaleForRenconciliationSerializer, SaleSummarySerializer | from .serializers import SaleSerializer, ProductSerializer, CustomerSerializer, ReconciliationJarSerializer, PaymentMethodSerializer, SaleForRenconciliationSerializer, SaleSummarySerializer | ||||||
|  |  | ||||||
| from decimal import Decimal | from decimal import Decimal | ||||||
| @@ -126,3 +126,8 @@ class SaleSummary(APIView): | |||||||
|         sale = Sale.objects.get(pk=id) |         sale = Sale.objects.get(pk=id) | ||||||
|         serializer = SaleSummarySerializer(sale) |         serializer = SaleSummarySerializer(sale) | ||||||
|         return Response(serializer.data) |         return Response(serializer.data) | ||||||
|  |  | ||||||
|  | class AdminCodeValidateView(APIView): | ||||||
|  |     def get(self, request, code): | ||||||
|  |         codes = AdminCode.objects.filter(value=code) | ||||||
|  |         return Response({'validCode': bool(codes)}) | ||||||
|   | |||||||
| @@ -0,0 +1,50 @@ | |||||||
|  | <template> | ||||||
|  |   <v-dialog v-model="dialog" persistent> | ||||||
|  |     <v-card> | ||||||
|  |       <v-card-title> | ||||||
|  |         Ingrese el código | ||||||
|  |       </v-card-title> | ||||||
|  |       <v-card-text> | ||||||
|  |         <v-form id="code-form" @submit.prevent="verifyCode"> | ||||||
|  |           <v-text-field v-model="code" label="Código" type="password" autocomplete="off" /> | ||||||
|  |         </v-form> | ||||||
|  |       </v-card-text> | ||||||
|  |       <v-card-actions> | ||||||
|  |         <v-btn type="submit" form="code-form">Aceptar</v-btn> | ||||||
|  |       </v-card-actions> | ||||||
|  |     </v-card> | ||||||
|  |   </v-dialog> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |   import { inject } from 'vue'; | ||||||
|  |  | ||||||
|  |   export default { | ||||||
|  |     data() { | ||||||
|  |       return { | ||||||
|  |         api: inject('api'), | ||||||
|  |         dialog: true, | ||||||
|  |         code: '', | ||||||
|  |       }; | ||||||
|  |     }, | ||||||
|  |     methods: { | ||||||
|  |       verifyCode() { | ||||||
|  |         this.api.isValidAdminCode(this.code) | ||||||
|  |             .then(data => { | ||||||
|  |               if (data['validCode']) { | ||||||
|  |                 this.$emit('code-verified', true); | ||||||
|  |                 this.dialog = false; | ||||||
|  |               } else { | ||||||
|  |                 alert('Código incorrecto'); | ||||||
|  |                 this.$emit('code-verified', false); | ||||||
|  |               } | ||||||
|  |             }) | ||||||
|  |             .catch(error => { | ||||||
|  |               alert('Error al validar el código'); | ||||||
|  |               this.$emit('code-verified', false); | ||||||
|  |               console.error(error); | ||||||
|  |             }); | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |   } | ||||||
|  | </script> | ||||||
| @@ -1,7 +1,20 @@ | |||||||
| <template> | <template> | ||||||
|   <ReconciliationJar /> |   <div> | ||||||
|  |     <CodeDialog @code-verified="(verified) => showComponent = verified"/> | ||||||
|  |   </div> | ||||||
|  |   <ReconciliationJar v-if="showComponent" /> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script setup> | <script > | ||||||
|   // |   import CodeDialog from '../components/CodeDialog.vue' | ||||||
|  |  | ||||||
|  |   export default { | ||||||
|  |     data() { | ||||||
|  |       return { | ||||||
|  |         showComponent: false, | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     components: { CodeDialog }, | ||||||
|  |     methods: {}, | ||||||
|  |   } | ||||||
| </script> | </script> | ||||||
|   | |||||||
| @@ -23,6 +23,10 @@ class Api { | |||||||
|     return this.apiImplementation.getPurchasesForReconciliation(); |     return this.apiImplementation.getPurchasesForReconciliation(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   isValidAdminCode(code) { | ||||||
|  |     return this.apiImplementation.isValidAdminCode(code); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   createPurchase(purchase) { |   createPurchase(purchase) { | ||||||
|     return this.apiImplementation.createPurchase(purchase); |     return this.apiImplementation.createPurchase(purchase); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -24,6 +24,11 @@ class DjangoApi { | |||||||
|     return this.getRequest(url); |     return this.getRequest(url); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   isValidAdminCode(code) { | ||||||
|  |     const url = `/don_confiao/api/admin_code/validate/${code}` | ||||||
|  |     return this.getRequest(url) | ||||||
|  |     } | ||||||
|  |  | ||||||
|   createPurchase(purchase) { |   createPurchase(purchase) { | ||||||
|     const url = '/don_confiao/api/sales/'; |     const url = '/don_confiao/api/sales/'; | ||||||
|     return this.postRequest(url, purchase); |     return this.postRequest(url, purchase); | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								tienda_ilusion/don_confiao/migrations/0037_admincode.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								tienda_ilusion/don_confiao/migrations/0037_admincode.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | # Generated by Django 5.0.6 on 2025-01-11 23:52 | ||||||
|  |  | ||||||
|  | from django.db import migrations, models | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|  |     dependencies = [ | ||||||
|  |         ('don_confiao', '0036_merge_20241228_2212'), | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  |     operations = [ | ||||||
|  |         migrations.CreateModel( | ||||||
|  |             name='AdminCode', | ||||||
|  |             fields=[ | ||||||
|  |                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||||
|  |                 ('value', models.CharField(max_length=255)), | ||||||
|  |             ], | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
| @@ -198,3 +198,7 @@ class Payment(models.Model): | |||||||
| class PaymentSale(models.Model): | class PaymentSale(models.Model): | ||||||
|     payment = models.ForeignKey(Payment, on_delete=models.CASCADE) |     payment = models.ForeignKey(Payment, on_delete=models.CASCADE) | ||||||
|     sale = models.ForeignKey(Sale, on_delete=models.CASCADE) |     sale = models.ForeignKey(Sale, on_delete=models.CASCADE) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class AdminCode(models.Model): | ||||||
|  |     value = models.CharField(max_length=255, null=False, blank=False) | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								tienda_ilusion/don_confiao/tests/test_admin_code.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								tienda_ilusion/don_confiao/tests/test_admin_code.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | from django.test import TestCase, Client | ||||||
|  |  | ||||||
|  | from ..models import AdminCode | ||||||
|  |  | ||||||
|  | import json | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestAdminCode(TestCase): | ||||||
|  |     def setUp(self): | ||||||
|  |         self.valid_code = 'some valid code' | ||||||
|  |         admin_code = AdminCode() | ||||||
|  |         admin_code.value = self.valid_code | ||||||
|  |         admin_code.clean() | ||||||
|  |         admin_code.save() | ||||||
|  |  | ||||||
|  |         self.client = Client() | ||||||
|  |  | ||||||
|  |     def test_validate_code(self): | ||||||
|  |         url = '/don_confiao/api/admin_code/validate/' + self.valid_code | ||||||
|  |         response = self.client.get(url) | ||||||
|  |         self.assertEqual(response.status_code, 200) | ||||||
|  |  | ||||||
|  |         content = json.loads(response.content.decode('utf-8')) | ||||||
|  |         self.assertTrue(content['validCode']) | ||||||
|  |  | ||||||
|  |     def test_invalid_code(self): | ||||||
|  |         invalid_code = 'some invalid code' | ||||||
|  |         url = '/don_confiao/api/admin_code/validate/' + invalid_code | ||||||
|  |  | ||||||
|  |         response = self.client.get(url) | ||||||
|  |         self.assertEqual(response.status_code, 200) | ||||||
|  |  | ||||||
|  |         content = json.loads(response.content.decode('utf-8')) | ||||||
|  |         self.assertFalse(content['validCode']) | ||||||
|  |  | ||||||
|  |     def test_empty_code(self): | ||||||
|  |         empty_code = '' | ||||||
|  |         url = '/don_confiao/api/admin_code/validate/' + empty_code | ||||||
|  |  | ||||||
|  |         response = self.client.get(url) | ||||||
|  |         self.assertEqual(response.status_code, 404) | ||||||
| @@ -28,5 +28,6 @@ urlpatterns = [ | |||||||
|     path("payment_methods/all/select_format", api_views.PaymentMethodView.as_view(), name="payment_methods_to_select"), |     path("payment_methods/all/select_format", api_views.PaymentMethodView.as_view(), name="payment_methods_to_select"), | ||||||
|     path('purchases/for_reconciliation', api_views.SalesForReconciliationView.as_view(), name='sales_for_reconciliation'), |     path('purchases/for_reconciliation', api_views.SalesForReconciliationView.as_view(), name='sales_for_reconciliation'), | ||||||
|     path('reconciliate_jar', api_views.ReconciliateJarView.as_view()), |     path('reconciliate_jar', api_views.ReconciliateJarView.as_view()), | ||||||
|  |     path('api/admin_code/validate/<code>', api_views.AdminCodeValidateView.as_view()), | ||||||
|     path('api/', include(router.urls)), |     path('api/', include(router.urls)), | ||||||
| ] | ] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user