From 4f5b3ca6c0adeaddb14e5ddc171c3b792530b129 Mon Sep 17 00:00:00 2001 From: Patricio Kumagae <pkumagae@boletinoficial.gov.ar> Date: Mon, 21 Jan 2019 10:25:50 -0300 Subject: [PATCH] Tarea #17479 - Fixes --- api/admin.py | 3 +- api/models.py | 27 ++- dapp/managers.py | 6 + dapp/models.py | 2 - frontend/templates/dapp/account_list.html | 151 +++++++----- .../activation_complete.html | 4 +- .../activation_email_body.html | 217 ++++++++++++++++++ .../activation_email_body.txt | 16 -- .../activation_email_subject.txt | 9 - .../registration_form.html | 16 +- .../django_registration/update_user.html | 132 +++++++++++ .../registration/change_password.html | 103 +++++++++ .../registration/forgot_password.html | 95 ++++++++ .../forgot_password_complete.html | 29 +++ .../registration/forgot_password_confirm.html | 66 ++++++ .../registration/forgot_password_done.html | 41 ++++ .../forgot_password_email_body.html | 217 ++++++++++++++++++ .../registration/forgot_password_subject.txt | 1 + frontend/templates/registration/login.html | 17 +- frontend/templates/topnav-deslogueado.html | 10 - frontend/templates/topnav-logueado.html | 17 +- frontend/urls.py | 16 ++ frontend/views.py | 93 +++++++- locale/en/LC_MESSAGES/django.mo | Bin 474 -> 474 bytes locale/en/LC_MESSAGES/django.po | 125 ++++++---- locale/es/LC_MESSAGES/django.mo | Bin 2371 -> 2873 bytes locale/es/LC_MESSAGES/django.po | 133 +++++++---- logica_cuentas/models.py | 1 - requirements.txt | 5 +- 29 files changed, 1300 insertions(+), 252 deletions(-) create mode 100644 frontend/templates/django_registration/activation_email_body.html delete mode 100644 frontend/templates/django_registration/activation_email_body.txt create mode 100644 frontend/templates/django_registration/update_user.html create mode 100644 frontend/templates/registration/change_password.html create mode 100644 frontend/templates/registration/forgot_password.html create mode 100644 frontend/templates/registration/forgot_password_complete.html create mode 100644 frontend/templates/registration/forgot_password_confirm.html create mode 100644 frontend/templates/registration/forgot_password_done.html create mode 100644 frontend/templates/registration/forgot_password_email_body.html create mode 100644 frontend/templates/registration/forgot_password_subject.txt diff --git a/api/admin.py b/api/admin.py index 3a723bd..5d0fd82 100644 --- a/api/admin.py +++ b/api/admin.py @@ -8,7 +8,8 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ """ from django.contrib import admin -from api.models import CustomUser, Institution +from api.models import CustomUser, Institution, Section admin.site.register(CustomUser) admin.site.register(Institution) +admin.site.register(Section) diff --git a/api/models.py b/api/models.py index 58f6346..0e37c5e 100644 --- a/api/models.py +++ b/api/models.py @@ -25,6 +25,8 @@ class Institution(models.Model): class Meta: db_table = 'institution' + verbose_name = 'Institución' + verbose_name_plural = 'Instituciones' class Service(models.Model): @@ -35,18 +37,27 @@ class Service(models.Model): class Meta: db_table = 'service' + verbose_name = 'Servicio' + verbose_name_plural = 'Servicios' + + +class Section(models.Model): + name = models.CharField(max_length=255, null=True, blank=True) + + def __str__(self): + return self.name + + class Meta: + db_table = 'section' + verbose_name = 'Sección' + verbose_name_plural = 'Secciones' class CustomUser(models.Model): - SECTION_CHOICES = ( - (1, _('public')), - (2, _('private')), - (3, _('academic')), - (4, _('person')), - ) - - section = models.IntegerField(choices=SECTION_CHOICES, null=True, blank=True) + + section = models.ForeignKey(Section, on_delete=models.PROTECT, null=True, blank=True) organization = models.CharField(max_length=255, null=True, blank=True) + rol = models.CharField(max_length=255, null=True, blank=True) cuit = models.CharField(max_length=20, null=True, blank=True) user = models.ForeignKey(User, on_delete=models.PROTECT, ) enabled_institutions = models.ManyToManyField(Institution, verbose_name='Instituciones habilitadas', blank=True) diff --git a/dapp/managers.py b/dapp/managers.py index 8d9ab5b..4b8c012 100644 --- a/dapp/managers.py +++ b/dapp/managers.py @@ -16,12 +16,16 @@ class StatusManager(models.Manager): def get_pendiente_distribucion(self): try: return self.filter(descripcion="Pendiente de distribucion").first() + except Exception as e: + pass except OperationalError as oe: return None def get_esperando_transaccion(self): try: return self.filter(descripcion="Esperando transaccion").first() + except Exception as e: + pass except OperationalError as oe: return None @@ -34,6 +38,8 @@ class StatusManager(models.Manager): def get_esperando_desvinculado(self): try: return self.filter(descripcion="Esperando desvinculacion").first() + except Exception as e: + pass except OperationalError as oe: return None diff --git a/dapp/models.py b/dapp/models.py index dcd0054..17d900b 100644 --- a/dapp/models.py +++ b/dapp/models.py @@ -15,7 +15,6 @@ from dapp.managers import AccountManager, StatusManager class Status(models.Model): - id = models.IntegerField(primary_key=True, ) descripcion = models.CharField(max_length=60) objects = StatusManager() @@ -29,7 +28,6 @@ class Status(models.Model): class Account(models.Model): - id = models.IntegerField(primary_key=True, ) address = models.CharField(max_length=42, validators=[validators.validate_address], unique=True) status = models.ForeignKey(Status, null=False, default=5, on_delete=models.PROTECT, ) institution = models.ForeignKey(Institution, on_delete=models.PROTECT, null=True, blank=True) diff --git a/frontend/templates/dapp/account_list.html b/frontend/templates/dapp/account_list.html index 6a920b2..3d43edf 100644 --- a/frontend/templates/dapp/account_list.html +++ b/frontend/templates/dapp/account_list.html @@ -24,17 +24,25 @@ You should have received a copy of the GNU General Public License along with thi <main class="container admin" id="main-content"> <div class="row"> {% for message in messages %} - <div class="alert alert-{{ message.tags }}" style="display: block !important;" id="main-message"> + <div class="alert alert-{{ message.tags }} alert-dismissible" style="display: block !important;" id="main-message"> {{ message|safe }} + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> </div> {% endfor %} <section> - - <h1 class="page-header">Cuentas</h1> - <a href="#" class="btn-default btn btn-lg btn-header" id="agregarCuenta" data-toggle="modal" data-target="#modalAgregarCuenta">+ Agregar cuenta</a> - <div class="alert alert-success" role="alert"> - <p>Su solicitud de carga será evaluada por los administradores. Nos contactaremos a la brevedad.</p> + <div> + <div><h1 class="page-header">Cuentas</h1></div> + <div> + <div style="margin-right: 266px;"> + <a href="#" class="btn-default btn btn-lg btn-header" id="agregarNuevaCuenta" data-toggle="modal" data-target="#modalNuevaCuenta">+ Agregar nueva cuenta</a></li> + </div> + <div> + <a href="#" class="btn-default btn btn-lg btn-header" id="agregarCuentaExistente" data-toggle="modal" data-target="#modalCuentaExistente">+ Agregar cuenta existente</a></li> + </div> + </div> </div> <div class="table-responsive"> @@ -47,7 +55,6 @@ You should have received a copy of the GNU General Public License along with thi <tr> <th>Cuenta</th> <th>Estado</th> - <th>Servicio</th> <th>Cantidad de Ether</th> <th>LÃmite de Carga</th> <th>Acciones</th> @@ -59,14 +66,14 @@ You should have received a copy of the GNU General Public License along with thi <tr> <form action="/accounts/require_ether/" method="post" id="form-{{ item.id }}"> {% csrf_token %} - <td> + <td class="sorting_1"> + <div class="nombreCuenta">{{ item.account.service.name }}</div> <div class="direccionCuenta"> <input type="hidden" name="address" id="address-{{ item.account.id }}" value="{{ item.account.address }}" /> {{ item.account.address }} </div> </td> <td>{{ item.account.status.descripcion }}</td> - <td>{{ item.account.service.name }}</td> <td>{{ item.account.balance }} <span class="mwei">Wei</span></td> <td>{{ item.account.tope }} <span class="mwei">Wei</span></td> <td> @@ -85,12 +92,12 @@ You should have received a copy of the GNU General Public License along with thi </form> </tr> {% empty %} - <tr><td>{% trans "no_se_encontraron_cuentas" %}.</td></tr> + <div class="feedback">{% trans "no_se_encontraron_cuentas" %}.</div> {% endfor %} </tbody> </table> {% else %} - <tr><td>{% trans "no_se_encontraron_cuentas" %}.</td></tr> + <div class="feedback">{% trans "no_se_encontraron_cuentas" %}</div> {% endif %} </div> </section> @@ -102,27 +109,15 @@ You should have received a copy of the GNU General Public License along with thi <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h2 class="modal-title">Instrucciones</h2> + <h2 class="modal-title">Instrucciones para verificar mi cuenta</h2> </div> <div class="modal-body"> - <pre> - <label>Desde la consola de geth ejecutar los siguientes comandos:</label> - - abi = [ { "anonymous": false, "inputs": [ { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "proofOfControlWeiAmountChanged", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "addBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "add", "type": "address" }, { "name": "password", "type": "bytes32" } ], "name": "addSuitor", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "changeLimit", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "ben", "type": "address" }, { "indexed": false, "name": "newLimit", "type": "uint256" } ], "name": "limitChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorNotApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" }, { "indexed": true, "name": "distr", "type": "address" } ], "name": "suitorAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "limit", "type": "uint256" } ], "name": "addedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "top", "type": "uint256" } ], "name": "addedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "replenished", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "top", "type": "uint256" } ], "name": "addDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "key", "type": "string" } ], "name": "proveControl", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "replenish", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [], "name": "replenishAll", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "accs", "type": "address[]" }, { "name": "amounts", "type": "uint256[]" } ], "name": "replenishList", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "amount", "type": "uint256" } ], "name": "setProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": true, "stateMutability": "payable", "type": "constructor" }, { "constant": true, "inputs": [], "name": "getBeneficiariesCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getBeneficiaryLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getDistributorLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "key", "type": "string" } ], "name": "hash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ] - - var contractInstance = eth.contract(abi).at("<label id="label-contract-address"></label>") - - eth.defaultAccount = "<label id="label-cuenta"></label>" - - personal.unlockAccount(eth.defaultAccount, "PASSPHRASE DE LA CUENTA") // es necesario desbloquear la cuenta con la passphrase, OJO SI EL ATTACH ES CON HTTP - - var tx = contractInstance.proveControl.sendTransaction("<label id="label-clave"></label>", {gas:eth.getBalance(eth.defaultAccount), gasPrice:1}) // efectivamente la transaccion - - eth.getTransactionReceipt(tx) //esto puede devolver undefined, porque depende de si se sello el bloque con la transaccion + <label>Desde la consola de geth ejecutar los siguientes comandos:</label> + <pre>abi = [ { "anonymous": false, "inputs": [ { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "proofOfControlWeiAmountChanged", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "addBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "add", "type": "address" }, { "name": "password", "type": "bytes32" } ], "name": "addSuitor", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "limit", "type": "uint256" } ], "name": "changeLimit", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" } ], "name": "kickDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "ben", "type": "address" }, { "indexed": false, "name": "newLimit", "type": "uint256" } ], "name": "limitChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" } ], "name": "suitorNotApproved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "suitor", "type": "address" }, { "indexed": true, "name": "distr", "type": "address" } ], "name": "suitorAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "limit", "type": "uint256" } ], "name": "addedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": true, "name": "kicked", "type": "address" } ], "name": "kickedBeneficiary", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "added", "type": "address" }, { "indexed": false, "name": "top", "type": "uint256" } ], "name": "addedDistributor", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "distr", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "replenished", "type": "event" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "top", "type": "uint256" } ], "name": "addDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "key", "type": "string" } ], "name": "proveControl", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "acc", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "replenish", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [], "name": "replenishAll", "outputs": [ { "name": "", "type": "bool" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "accs", "type": "address[]" }, { "name": "amounts", "type": "uint256[]" } ], "name": "replenishList", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": false, "inputs": [ { "name": "amount", "type": "uint256" } ], "name": "setProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": true, "stateMutability": "payable", "type": "constructor" }, { "constant": true, "inputs": [], "name": "getBeneficiariesCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getBeneficiaryLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "acc", "type": "address" } ], "name": "getDistributorLimit", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getProofOfControlWeiAmount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "key", "type": "string" } ], "name": "hash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isBeneficiary", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "add", "type": "address" } ], "name": "isDistributor", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ]<br /><br />var contractInstance = eth.contract(abi).at("<label id="label-contract-address"></label>")<br/><br/>eth.defaultAccount = "<label id="label-cuenta"></label>"<br /><br/>personal.unlockAccount(eth.defaultAccount, "<i><b>PASSPHRASE DE LA CUENTA</b></i>") // es necesario desbloquear la cuenta con la passphrase, OJO SI EL ATTACH ES CON HTTP<br/><br/>var tx = contractInstance.proveControl.sendTransaction("<label id="label-clave"></label>", {gas:eth.getBalance(eth.defaultAccount), gasPrice:1}) // efectivamente la transaccion<br/><br/>eth.getTransactionReceipt(tx) //esto puede devolver undefined, porque depende de si se sello el bloque con la transaccion </pre> </div> <div class="modal-footer"> - <button type="button" class="btn btn-default btn-lg" data-dismiss="modal">Cancelar</button> + <button type="button" class="btn btn-default btn-lg" data-dismiss="modal">Cerrar</button> </div> </div> @@ -148,21 +143,25 @@ You should have received a copy of the GNU General Public License along with thi <div class="modal fade" id="modalNuevaCuenta" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg" role="document"> - <form action="/accounts/create/" method="post" class="modal-content"> + <form action="/accounts/create/" method="post" class="modal-content" id="formNuevaCuenta"> {% csrf_token %} <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h2 class="modal-title">Nueva cuenta</h2> </div> <div class="modal-body"> - <div class="alert alert-danger" role="alert"> + <div class="alert alert-danger" role="alert" id="containerNuevaCuenta"> <p>Comprobá los siguientes errores del formulario:</p> <ul></ul> </div> + <div class="form-group form-group-lg"> + <label for="service_name" class="form-required">Nombre de Servicio</label> + <input class="form-control" type="text" id="service_name" name="service_name" size="60" placeholder="Nombre de Servicio" maxlength="42" aria-required="true"> + </div> <div class="form-group form-group-lg"> <label for="direccionCuenta" class="form-required">Dirección </label> <a role="button" target="_blank" data-container="body" data-toggle="popover" data-placement="right" data-content="Para saber tu dirección debés tener instalado el núcleo de BFA. Visitá nuestro <a href='https://gitlab.bfa.ar/' target='_blank'>GitLab</a> para saber cómo instalar el núcleo y obtenerla."><i class="far fa-question-circle" aria-hidden="true"></i><span class="sr-only">Más información</span></a> - <input class="form-control" type="text" id="address" name="address" size="60" placeholder="0x + 40 caractéres hexadecimales" maxlength="42" required="required" aria-required="true"> + <input class="form-control" type="text" id="address" name="address" size="60" placeholder="0x + 40 caractéres hexadecimales" maxlength="42" aria-required="true"> </div> <div class="form-group form-group-lg"> <label for="institucion" class="form-required">Institución </label> @@ -173,10 +172,7 @@ You should have received a copy of the GNU General Public License along with thi {% endfor %} </select> </div> - <div class="form-group form-group-lg"> - <label for="service_name" class="form-required">Nombre de Servicio</label> - <input class="form-control" type="text" id="service_name" name="service_name" size="60" placeholder="Nombre de Servicio" maxlength="42" required="required" aria-required="true"> - </div> + </div> <div class="modal-footer"> <button type="button" class="btn btn-default btn-lg" data-dismiss="modal">Cancelar</button> @@ -188,35 +184,43 @@ You should have received a copy of the GNU General Public License along with thi <div class="modal fade" id="modalCuentaExistente" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg" role="document"> - <form action="/accounts/create_existing/" method="post" class="modal-content"> + <form action="/accounts/create_existing/" method="post" class="modal-content" id="formCuentaExistente"> {% csrf_token %} <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h2 class="modal-title">Agregar cuenta existente</h2> </div> <div class="modal-body"> - <div class="alert alert-danger" role="alert"> + <div class="alert alert-danger" role="alert" id="containerCuentaExistente"> <p>Comprobá los siguientes errores del formulario:</p> <ul></ul> </div> - <div class="form-group form-group-lg"> - <label for="institucion" class="form-required">Servicio </label> - <select class="form-control" id="service" name="service"> - <option>Seleccione</option> - {% for service in services %} - <option value="{{ service.id }}">{{ service.name }}</option> - {% endfor %} - </select> - </div> - <div class="form-group form-group-lg"> - <label for="direccionCuenta" class="form-required">Dirección </label> - <a role="button" target="_blank" data-container="body" data-toggle="popover" data-placement="right" data-content="Para saber tu dirección debés tener instalado el núcleo de BFA. Visitá nuestro <a href='https://gitlab.bfa.ar/' target='_blank'>GitLab</a> para saber cómo instalar el núcleo y obtenerla."><i class="far fa-question-circle" aria-hidden="true"></i><span class="sr-only">Más información</span></a> - <input class="form-control" type="text" id="address-existing" name="address-existing" size="60" maxlength="42" required="required" aria-required="true" readonly> - </div> + {% if services %} + <div class="form-group form-group-lg"> + <label for="institucion" class="form-required">Servicio </label> + <select class="form-control" id="service" name="service"> + <option>Seleccione</option> + {% for service in services %} + <option value="{{ service.id }}">{{ service.name }}</option> + {% endfor %} + </select> + </div> + <div class="form-group form-group-lg"> + <label for="direccionCuenta" class="form-required">Dirección </label> + <a role="button" target="_blank" data-container="body" data-toggle="popover" data-placement="right" data-content="Para saber tu dirección debés tener instalado el núcleo de BFA. Visitá nuestro <a href='https://gitlab.bfa.ar/' target='_blank'>GitLab</a> para saber cómo instalar el núcleo y obtenerla."><i class="far fa-question-circle" aria-hidden="true"></i><span class="sr-only">Más información</span></a> + <input class="form-control" type="text" id="address_existing" name="address_existing" size="60" maxlength="42" required="required" aria-required="true" readonly> + </div> + {% else %} + <div class="form-group form-group-lg"> + <label for="direccionCuenta">{% trans "no_se_encontraron_cuentas_existentes" %}</label> + </div> + {% endif %} </div> <div class="modal-footer"> <button type="button" class="btn btn-default btn-lg" data-dismiss="modal">Cancelar</button> - <button type="submit" id="btnAgregarExistente" class="btn btn-primary btn-lg">Agregar</button> + {% if services %} + <button type="submit" id="btnAgregarExistente" class="btn btn-primary btn-lg">Agregar</button> + {% endif %} </div> </form> </div> @@ -330,7 +334,7 @@ You should have received a copy of the GNU General Public License along with thi method: 'POST', data: {'service':$('#service').val()}, success: function(data, status, xhr ){ - $('#address-existing').val(data.address); + $('#address_existing').val(data.address); } }); }); @@ -361,7 +365,8 @@ You should have received a copy of the GNU General Public License along with thi }); - var container = $('div.alert'); + var containerNuevaCuenta = $('#containerNuevaCuenta'); + var containerCuentaExistente = $('#containerCuentaExistente'); /** * Chequea que empiece con 0x */ @@ -370,10 +375,10 @@ You should have received a copy of the GNU General Public License along with thi }, "La dirección debe empezar con 0x"); - $("form").validate({ + $("#formNuevaCuenta").validate({ focusInvalid: false, - errorContainer: container, - errorLabelContainer: $("ul", container), + errorContainer: containerNuevaCuenta, + errorLabelContainer: $("ul", containerNuevaCuenta), wrapper: 'li', highlight: function(element) { $(element).closest('.form-group').addClass('has-error'); @@ -382,8 +387,8 @@ You should have received a copy of the GNU General Public License along with thi $(element).closest('.form-group').removeClass('has-error'); }, messages: { - nombreCuenta: "Ingresá un nombre para la cuenta", - direccionCuenta: { + service_name: "Ingresá un nombre de servicio para la cuenta", + address: { required: "Ingresá una dirección válida", minlength: "La dirección debe tener 42 caractéres incluidos el 0x.", maxlength: "La dirección debe tener 42 caractéres incluidos el 0x." @@ -391,8 +396,34 @@ You should have received a copy of the GNU General Public License along with thi }, rules:{ - nombreCuenta: "required", - direccionCuenta: { + service_name: "required", + address: { + required: true, + checkInit: true, + minlength: 42, + maxlength: 42 + } + } + + }); + + $("#formCuentaExistente").validate({ + focusInvalid: false, + errorContainer: containerCuentaExistente, + errorLabelContainer: $("ul", containerCuentaExistente), + wrapper: 'li', + highlight: function(element) { + $(element).closest('.form-group').addClass('has-error'); + }, + unhighlight: function(element) { + $(element).closest('.form-group').removeClass('has-error'); + }, + messages: { + address_existing: "Seleccioná un servicio para agregar", + }, + rules:{ + service_name: "required", + address: { required: true, checkInit: true, minlength: 42, diff --git a/frontend/templates/django_registration/activation_complete.html b/frontend/templates/django_registration/activation_complete.html index 7969da3..4657e73 100644 --- a/frontend/templates/django_registration/activation_complete.html +++ b/frontend/templates/django_registration/activation_complete.html @@ -13,11 +13,9 @@ You should have received a copy of the GNU General Public License along with thi {% block title %}{% trans "cuenta_verificada" %}{% endblock %} -{% include 'topnav-logueado.html' %} - {% block content %} - {% include 'topnav-logueado.html' %} + {% include 'topnav-deslogueado.html' %} <main class="container" id="main-content"> <div class="row"> <section> diff --git a/frontend/templates/django_registration/activation_email_body.html b/frontend/templates/django_registration/activation_email_body.html new file mode 100644 index 0000000..7fda46a --- /dev/null +++ b/frontend/templates/django_registration/activation_email_body.html @@ -0,0 +1,217 @@ +{% autoescape off %} + + + + +<!DOCTYPE html> +<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="x-apple-disable-message-reformatting"> + <title>Blockchain Federal Argentina</title> + <style> + html, + body { + margin: 0 auto !important; + padding: 0 !important; + height: 100% !important; + width: 100% !important; + } + * { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + } + div[style*="margin: 16px 0"] { + margin: 0 !important; + } + table, + td { + mso-table-lspace: 0pt !important; + mso-table-rspace: 0pt !important; + } + table { + border-spacing: 0 !important; + border-collapse: collapse !important; + table-layout: fixed !important; + margin: 0 auto !important; + } + table table table { + table-layout: auto; + } + img { + -ms-interpolation-mode:bicubic; + } + *[x-apple-data-detectors], /* iOS */ + .x-gmail-data-detectors, /* Gmail */ + .x-gmail-data-detectors *, + .aBn { + border-bottom: 0 !important; + cursor: default !important; + color: inherit !important; + text-decoration: none !important; + font-size: inherit !important; + font-family: inherit !important; + line-height: inherit !important; + } + .a6S { + display: none !important; + opacity: 0.01 !important; + } + img.g-img + div { + display: none !important; + } + .button-link { + text-decoration: none !important; + } + @media only screen and (min-device-width: 320px) and (max-device-width: 374px) { + .email-container { + min-width: 320px !important; + } + } + @media only screen and (min-device-width: 375px) and (max-device-width: 413px) { + .email-container { + min-width: 375px !important; + } + } + @media only screen and (min-device-width: 414px) { + .email-container { + min-width: 414px !important; + } + } + + </style> + <!-- CSS Reset : END --> + + <!-- Progressive Enhancements : BEGIN --> + <style> + + /* What it does: Hover styles for buttons */ + .button-td, + .button-a { + transition: all 100ms ease-in; + } + .button-td:hover, + .button-a:hover, .button-a:visited { + color: #FFFFFF !important; + background: #0094d4 !important; + border-color: #0094d4 !important; + } + + /* Media Queries */ + @media screen and (max-width: 600px) { + + .email-container { + width: 100% !important; + margin: auto !important; + } + + /* What it does: Forces elements to resize to the full width of their container. Useful for resizing images beyond their max-width. */ + .fluid { + max-width: 100% !important; + height: auto !important; + margin-left: auto !important; + margin-right: auto !important; + } + + /* What it does: Forces table cells into full-width rows. */ + .stack-column, + .stack-column-center { + display: block !important; + width: 100% !important; + max-width: 100% !important; + direction: ltr !important; + } + /* And center justify these ones. */ + .stack-column-center { + text-align: center !important; + } + + /* What it does: Generic utility class for centering. Useful for images, buttons, and nested tables. */ + .center-on-narrow { + text-align: center !important; + display: block !important; + margin-left: auto !important; + margin-right: auto !important; + float: none !important; + } + table.center-on-narrow { + display: inline-block !important; + } + + /* What it does: Adjust typography on small screens to improve readability */ + .email-container p { + font-size: 17px !important; + } + } + + </style> + <!-- Progressive Enhancements : END --> + + <!-- What it does: Makes background images in 72ppi Outlook render at correct size. --> + <!--[if gte mso 9]> + <xml> + <o:OfficeDocumentSettings> + <o:AllowPNG/> + <o:PixelsPerInch>96</o:PixelsPerInch> + </o:OfficeDocumentSettings> + </xml> + <![endif]--> + +</head> +<body width="100%" style="margin: 0; mso-line-height-rule: exactly;"> + <center style="width: 100%; text-align: left;"> + + <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" bgcolor="#EEEEEE"> + <tr> + <td> + + <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" width="400" style="margin: auto;" class="email-container"> + <tr> + <td style="padding: 30px; text-align: center; border-bottom: #DDD 1px solid" bgcolor="#ffffff" width="100px"> + <a href="https://bfa.ar"><img src="data:image/png;base64,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 +" width="139" height="100" alt="NIC Argentina" border="0" style="background: #dddddd; color: #555555;"></a> + </td> + </tr> + </table> + <table role="presentation" cellspacing="0" cellpadding="" border="0" align="center" width="400" style="margin: auto;" class="email-container"> + <tr> + <td bgcolor="#ffffff" style="padding: 30px 30px; font-family: sans-serif; font-size: 16px; line-height: 190%; color: #555555; text-align: center;"> + <h1>¡Bienvenido a BFA!</h1> + <p>Para continuar es necesario que verifiques tu dirección de correo electrónico.</p> + <p>Hace click en el botón para poder completar el registro en Blockchain Federal Argentina.</p> + </td> + </tr> + <tr> + <td bgcolor="#ffffff" style="margin-top: 15px; padding: 0 40px 40px; font-family: sans-serif; font-size: 15px; line-height: 140%; color: #555555; border-bottom: #DDD 1px solid"> + <!-- Button : BEGIN --> + <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" style="margin: auto"> + <tr> + <td style="border-radius: 50px; background: #1C5D82; text-align: center;" class="button-td"> + <a href="{{ scheme }}://{{ site.domain }}/accounts/activate/{{ activation_key }}" style="color:#ffffff; background: #0094d4; border: 15px solid #0094d4; font-family: sans-serif; font-size: 16px; line-height: 110%; text-align: center; text-decoration: none; display: block; border-radius: 50px; " class="button-a"> + <span style="color:#ffffff !important; font-weight: bold">Verificar cuenta</span> + </a> + </td> + </tr> + </table> + </td> + </tr> + </table> + <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" width="100%" style="max-width: 680px; font-family: sans-serif; color: #333333; font-size: 14px; line-height: 140%;"> + <tr> + <td style="padding: 20px; width: 100%; font-family: sans-serif; font-size: 14px; line-height: 140%; text-align: center; color: #333333;" class="x-gmail-data-detectors"> + <span style="font-weight: bold !important;">Blockchain Federal Argentina</span><br> + <a href="https://bfa.ar" style=" color: #333333; text-decoration: underline !important;">https://bfa.ar</a> + </td> + </tr> + </table> + + </td> + </tr> + </table> + </center> +</body> +</html> + +{% endautoescape %} \ No newline at end of file diff --git a/frontend/templates/django_registration/activation_email_body.txt b/frontend/templates/django_registration/activation_email_body.txt deleted file mode 100644 index d8767a0..0000000 --- a/frontend/templates/django_registration/activation_email_body.txt +++ /dev/null @@ -1,16 +0,0 @@ -{# -Copyright 2019 de la Dirección General de Sistemas Informáticos – SecretarÃa Legal y Técnica - Nación. - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ -#} -{% autoescape off %} -Hola {{ user.first_name }} {{ user.last_name }}, -Por favor confirmá tu suscripción haciendo click en el siguiente link, -{{ scheme }}://{{ site.domain }}/accounts/activate/{{ activation_key }} - - -{% endautoescape %} \ No newline at end of file diff --git a/frontend/templates/django_registration/activation_email_subject.txt b/frontend/templates/django_registration/activation_email_subject.txt index b50ec69..a1e2d8b 100644 --- a/frontend/templates/django_registration/activation_email_subject.txt +++ b/frontend/templates/django_registration/activation_email_subject.txt @@ -1,10 +1 @@ -{# -Copyright 2019 de la Dirección General de Sistemas Informáticos – SecretarÃa Legal y Técnica - Nación. - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ -#} Verificar cuenta BFA \ No newline at end of file diff --git a/frontend/templates/django_registration/registration_form.html b/frontend/templates/django_registration/registration_form.html index cd9daeb..62a5e6d 100644 --- a/frontend/templates/django_registration/registration_form.html +++ b/frontend/templates/django_registration/registration_form.html @@ -25,40 +25,38 @@ You should have received a copy of the GNU General Public License along with thi <div class="row"> <section> <h1 class="page-">{% trans "registro_de_usuarios" %}</h1> - {% for message in messages %} - <div class="alert alert-{{ message.tags }}" style="display: block !important;">{{ message }}</div> - {% endfor %} - + {% if form.non_field_errors %} + <div class="alert alert-danger" style="display: block !important;">{{ form.non_field_errors }}</div> + {% endif %} <p>Todos los campos son obligatorios.</p> <form method="post"> {% csrf_token %} - <div class="alert alert-danger" role="alert"> <p>Comprobá los siguientes errores del formulario:</p> <ul></ul> </div> <div class="form-group form-group-lg col-sm-6"> <label class="control-label" for="id_first_name">Nombre</label> - <input type="text" name="first_name" class="form-control" id="id_first_name" placeholder="Nombre" title="" maxlength="255" required> + <input type="text" name="first_name" class="form-control" id="id_first_name" placeholder="Nombre" title="" value="{{ form.first_name.value|default_if_none:"" }}" maxlength="255" required> </div> <div class="form-group form-group-lg col-sm-6"> <label class="control-label" for="id_last_name">Apellido</label> - <input type="text" name="last_name" class="form-control" id="id_last_name" placeholder="Apellido" title="" maxlength="255" required> + <input type="text" name="last_name" class="form-control" id="id_last_name" placeholder="Apellido" title="" value="{{ form.last_name.value|default_if_none:"" }}" maxlength="255" required> </div> <div class="form-group form-group-lg col-sm-12"> <label class="control-label" for="id_email">E-Mail</label> - <input type="email" name="email" class="form-control" id="id_email" placeholder="E-Mail" title="" value="" required> + <input type="email" name="email" class="form-control" id="id_email" placeholder="E-Mail" value="{{ form.email.value|default_if_none:"" }}" required> </div> <div class="form-group form-group-lg col-sm-12"> <label class="control-label" for="id_email">Usuario</label> - <input type="text" name="username" class="form-control" id="username" placeholder="Usuario" title="" value="" required> + <input type="text" name="username" class="form-control" id="username" placeholder="Usuario" value="{{ form.username.value|default_if_none:"" }}" required> </div> <div class="form-group form-group-lg col-sm-12"> diff --git a/frontend/templates/django_registration/update_user.html b/frontend/templates/django_registration/update_user.html new file mode 100644 index 0000000..695a82b --- /dev/null +++ b/frontend/templates/django_registration/update_user.html @@ -0,0 +1,132 @@ +{% extends 'header.html' %} +{% load i18n %} +{% load static %} +{% load bootstrap3 %} +{% bootstrap_css %} +{% bootstrap_javascript %} +{% bootstrap_messages %} + +{% block title %} + {% trans "mis_datos" %} +{% endblock %} + +{% block content %} + {% include 'topnav-logueado.html' %} + + <main class="container" id="main-content"> + <div class="row"> + <section> + <h1 class="page-header">Mis datos</h1> + + {% if messages %} + {% for message in messages %} + <div class="alert alert-{{ message.tags }}" style="display: block !important;"> + {{ message }} + </div> + {% endfor %} + {% else %} + <div class="alert alert-{{ message.tags }}" style="display: block !important;"></div> + {% endif %} + + + + <p>Los campos marcados con un asterisco (*) son obligatorios.</p> + <form novalidate="novalidate" method="post"> + {% csrf_token %} + <div class="alert alert-danger" role="alert"> + <p>Comprobá los siguientes errores del formulario:</p> + <ul></ul> + </div> + <div class="form-group form-group-lg col-sm-6"> + <label for="nombre" class="form-required">Nombre</label> + <input class="form-control" type="text" id="first_name" name="first_name" value="{{ user.first_name }}" size="60" maxlength="255" required="required"> + </div> + <div class="form-group form-group-lg col-sm-6"> + <label for="apellido" class="form-required">Apellido</label> + <input class="form-control" type="text" id="last_name" name="last_name" value="{{ user.last_name }}" size="60" maxlength="255" required="required" aria-required="true"> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="email" class="form-required">Correo electrónico</label> + <input class="form-control" type="text" id="email" name="email" value="{{ user.email }}" size="60" maxlength="255" required="required" aria-required="true"> + </div> + <div class="form-group form-group-lg col-sm-12"> + <a href="/change_password/">Cambiar contraseña</a> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="cuit">CUIT</label> + <input class="form-control" type="text" id="cuit" name="cuit" value="{{ custom_user.cuit|default_if_none:"" }}" size="60" maxlength="13"> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="org">Organización</label> + <input class="form-control" type="text" id="organization" name="organization" value="{{ custom_user.organization|default_if_none:"" }}" size="60" maxlength="255"> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="rol">Rol</label> + <input class="form-control" type="text" id="rol" name="rol" value="{{ custom_user.rol|default_if_none:"" }}" size="60" maxlength="255"> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="sector">Sector</label> + <select name="section" id="section" class="form-control"> + <option value="">Seleccione un sector</option> + {% for section in sections %} + <option value="{{ section.id }}" {% if section.id == custom_user.section_id %}selected="selected"{% endif %}>{{ section.name }}</option> + {% endfor %} + </select> + </div> + <div class="form-group col-sm-6 col-sm-push-6 form-footer"> + <button class="btn-primary btn btn-block" type="submit" id="submit" value="Guardar">Guardar</button> + </div> + <div class="form-group form-group-lg col-sm-6 col-sm-pull-6 font_small form-footer"> + <button class="btn-default btn btn-lg btn-block" type="button" id="cancel" value="Cancelar">Cancelar</button> + </div> + + </form> + </section> + </div> + </main> + {% include 'footer.html' %} + + <script> + + + + $(document).ready(function(){ + $('#cancel').click(function(){ + window.location.href = '/accounts/list/'; + }); + }); + + var container = $('div.alert'); + + + + + $("form").validate({ + focusInvalid: false, + errorContainer: container, + errorLabelContainer: $("ul", container), + wrapper: 'li', + highlight: function(element) { + $(element).closest('.form-group').addClass('has-error'); + }, + unhighlight: function(element) { + $(element).closest('.form-group').removeClass('has-error'); + }, + messages: { + first_name: "Ingresá tu nombre", + last_name: "Ingresá tu apellido", + email: "Ingresá una dirección de correo electrónico válida", + }, + rules:{ + first_name: "required", + last_name: "required", + email: { + required: true, + email: true + } + } + + }); + + </script> +{% endblock %} \ No newline at end of file diff --git a/frontend/templates/registration/change_password.html b/frontend/templates/registration/change_password.html new file mode 100644 index 0000000..2fe7037 --- /dev/null +++ b/frontend/templates/registration/change_password.html @@ -0,0 +1,103 @@ +{% extends 'header.html' %} +{% load i18n %} +{% load static %} +{% load bootstrap3 %} +{% bootstrap_css %} +{% bootstrap_javascript %} +{% bootstrap_messages %} + +{% block title %}{% trans "password_reset" %}{% endblock %} + +{% block content %} + + {% include 'topnav-logueado.html' %} + + <main class="container" id="main-content"> + <div class="row"> + <section> + <h1 class="page-header">Cambiá tu contraseña</h1> + + {% if form.new_password2.errors %} + <div class="alert alert-danger" style="display: block !important;">{{ form.new_password2.errors }}</div> + {% endif %} + + <form method="post"> + {% csrf_token %} + + + <div class="alert alert-danger" role="alert"> + <p>Comprobá los siguientes errores de la nueva contraseña:</p> + <ul></ul> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="password" class="form-required">Nueva Contraseña</label> + <div class="input-group"> + <input class="form-control" type="password" id="new_password1" name="new_password1" size="60" maxlength="255" required="required" aria-required="true"> + <div class="input-group-addon"> + <button id="toggle-password" class="toggle-button"><i class="fa fa-eye fa-lg toggle-icon"></i><span class="sr-only">Mostrar y ocultar contraseña</span></button> + </div> + </div> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="newPassword" class="form-required">Nueva contraseña (Confirmación)</label> + <div class="input-group"> + <input class="form-control" type="password" id="new_password2" name="new_password2" size="60" maxlength="255" required="required" aria-required="true"> + <div class="input-group-addon"> + <button id="toggle-newPassword" class="toggle-button"><i class="fa fa-eye fa-lg toggle-icon"></i><span class="sr-only">Mostrar y ocultar contraseña</span></button> + </div> + </div> + </div> + <div class="col-sm-12 font_small"> + <p>Utilizá ocho caracteres como mÃnimo con una combinación de letras, números y sÃmbolos.</p> + </div> + <div class="form-group col-sm-6 col-sm-push-6 form-footer"> + <button class="btn-primary btn btn-block" type="submit" id="submit" value="Restablecer contraseña">Cambiar contraseña</button> + </div> + </form> + </section> + </div> + </main> + + {% include 'footer.html' %} + <script> + + var container = $('div.alert'); + + $("form").validate({ + focusInvalid: false, + errorContainer: container, + errorLabelContainer: $("ul", container), + wrapper: 'li', + highlight: function(element) { + $(element).closest('.form-group').addClass('has-error'); + }, + unhighlight: function(element) { + $(element).closest('.form-group').removeClass('has-error'); + }, + messages: { + new_password1: { + required: "Ingresá una contraseña", + minlength: "La contraseña debe tener al menos 8 caracteres" + }, + new_password2: { + required: "Ingresá la confirmación de la contraseña", + minlength: "La confirmación de la contraseña debe tener al menos 8 caracteres", + equalTo: "Ingresá el mismo valor en la confirmación" + } + }, + rules:{ + new_password1: { + required: true, + minlength: 8, + maxlength: 40 + }, + new_password2: { + required: true, + equalTo: '#new_password1' + } + + } + }); + + </script> +{% endblock %} diff --git a/frontend/templates/registration/forgot_password.html b/frontend/templates/registration/forgot_password.html new file mode 100644 index 0000000..76d68a5 --- /dev/null +++ b/frontend/templates/registration/forgot_password.html @@ -0,0 +1,95 @@ +<!-- +Copyright 2019 de la Dirección General de Sistemas Informáticos – SecretarÃa Legal y Técnica - Nación. + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ +--> +{% extends 'header.html' %} +{% load i18n %} +{% load static %} +{% load bootstrap3 %} +{% bootstrap_css %} +{% bootstrap_javascript %} +{% bootstrap_messages %} + +{% block title %} + {% trans "forgot_password" %} +{% endblock %} + +{% block content %} + {% include 'topnav-deslogueado.html' %} + + <main class="container" id="main-content"> + <div class="row"> + <section> + <h1 class="page-header">Restablecé tu contraseña </h1> + <form novalidate="novalidate" method="post"> + {% csrf_token %} + <div class="alert alert-danger" role="alert"> + <p>El correo electrónico que ingresaste es inválido.</p> + <ul></ul> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="email" class="form-required">Correo electrónico</label> + <input class="form-control" type="text" id="email" name="email" value="" size="60" maxlength="255" required="required" aria-required="true"> + </div> + <div class="form-group col-sm-6 col-sm-push-6 form-footer"> + <button class="btn-primary btn btn-block" type="submit" id="submit" value="Restablecer contraseña">Restablecer contraseña</button> + </div> + <div class="form-group form-group-lg col-sm-6 col-sm-pull-6 font_small form-footer"> + <p>¿No tenés usuario? <a href="/accounts/register/">Registrate</a></p> + </div> + + </form> + </section> + </div> + </main> + + {% include 'footer.html' %} + + <script> + + var container = $('div.alert'); + + + $("form").validate({ + focusInvalid: false, + errorContainer: container, + errorLabelContainer: $("ul", container), + wrapper: 'li', + highlight: function(element) { + $(element).closest('.form-group').addClass('has-error'); + }, + unhighlight: function(element) { + $(element).closest('.form-group').removeClass('has-error'); + }, + messages: { + email: "Ingresá una dirección de correo electrónico válida", + }, + rules:{ + first_name: "required", + last_name: "required", + username: "required", + password: { + required: true, + atLeastOneLowercaseLetter: true, + atLeastOneUppercaseLetter: true, + atLeastOneNumber: true, + atLeastOneSymbol: true, + minlength: 8, + maxlength: 40 + }, + email: { + required: true, + email: true + } + } + + }); + + </script> + +{% endblock %} \ No newline at end of file diff --git a/frontend/templates/registration/forgot_password_complete.html b/frontend/templates/registration/forgot_password_complete.html new file mode 100644 index 0000000..e8be2dc --- /dev/null +++ b/frontend/templates/registration/forgot_password_complete.html @@ -0,0 +1,29 @@ +{% extends 'header.html' %} +{% load i18n %} +{% load static %} +{% load bootstrap3 %} +{% bootstrap_css %} +{% bootstrap_javascript %} +{% bootstrap_messages %} + +{% block title %}{% trans "password_reset_complete" %}{% endblock %} + +{% block content %} + + {% include 'topnav-deslogueado.html' %} + + <main class="container" id="main-content"> + <div class="row"> + <section> + <div class="feedback"> + <img src="images/check.svg" alt="" width="200px"> + <h1>Tu contraseña ha sido cambiada</h1> + <p>Ahora podés acceder a tu cuenta de BFA con tu nueva contraseña.</p> + <a href="/accounts/login/" class="btn btn-primary">Ingresar</a> + </div> + </section> + </div> + </main> + + {% include 'footer.html' %} +{% endblock %} \ No newline at end of file diff --git a/frontend/templates/registration/forgot_password_confirm.html b/frontend/templates/registration/forgot_password_confirm.html new file mode 100644 index 0000000..83fe82c --- /dev/null +++ b/frontend/templates/registration/forgot_password_confirm.html @@ -0,0 +1,66 @@ +{% extends 'header.html' %} +{% load i18n %} +{% load static %} +{% load bootstrap3 %} +{% bootstrap_css %} +{% bootstrap_javascript %} +{% bootstrap_messages %} + +{% block title %}{% trans "password_reset" %}{% endblock %} + +{% block content %} + + {% include 'topnav-deslogueado.html' %} + + <main class="container" id="main-content"> + <div class="row"> + <section> + <h1 class="page-header">Cambiá tu contraseña</h1> + + {% if form.new_password2.errors %} + <div class="alert alert-danger" style="display: block !important;">{{ form.new_password2.errors }}</div> + {% endif %} + + <form method="post"> + {% csrf_token %} + + + <div class="alert alert-danger" role="alert"> + <p>Comprobá los siguientes errores de la nueva contraseña:</p> + <ul></ul> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="password" class="form-required">Nueva Contraseña</label> + <div class="input-group"> + <input class="form-control" type="password" id="pwd" name="new_password1" size="60" maxlength="255" required="required" aria-required="true"> + <div class="input-group-addon"> + <button id="toggle-password" class="toggle-button"><i class="fa fa-eye fa-lg toggle-icon"></i><span class="sr-only">Mostrar y ocultar contraseña</span></button> + </div> + </div> + </div> + <div class="form-group form-group-lg col-sm-12"> + <label for="newPassword" class="form-required">Nueva contraseña (Confirmación)</label> + <div class="input-group"> + <input class="form-control" type="password" id="newPwd" name="new_password2" size="60" maxlength="255" required="required" aria-required="true"> + <div class="input-group-addon"> + <button id="toggle-newPassword" class="toggle-button"><i class="fa fa-eye fa-lg toggle-icon"></i><span class="sr-only">Mostrar y ocultar contraseña</span></button> + </div> + </div> + </div> + <div class="col-sm-12 font_small"> + <p>Utilizá ocho caracteres como mÃnimo con una combinación de letras, números y sÃmbolos.</p> + </div> + <div class="form-group col-sm-6 col-sm-push-6 form-footer"> + <button class="btn-primary btn btn-block" type="submit" id="submit" value="Restablecer contraseña">Cambiar contraseña</button> + </div> + </form> + </section> + </div> + </main> + + {% include 'footer.html' %} + </body> + +</html> + +{% endblock %} diff --git a/frontend/templates/registration/forgot_password_done.html b/frontend/templates/registration/forgot_password_done.html new file mode 100644 index 0000000..4ae7faf --- /dev/null +++ b/frontend/templates/registration/forgot_password_done.html @@ -0,0 +1,41 @@ +<!-- +Copyright 2019 de la Dirección General de Sistemas Informáticos – SecretarÃa Legal y Técnica - Nación. + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ +--> +{% extends 'header.html' %} +{% load i18n %} +{% load static %} +{% load bootstrap3 %} +{% bootstrap_css %} +{% bootstrap_javascript %} +{% bootstrap_messages %} + +{% block title %} + {% trans "check_email" %} +{% endblock %} + +{% block content %} + {% include 'topnav-deslogueado.html' %} + + <main class="container" id="main-content"> + <div class="row"> + <section> + <div class="feedback"> + <img src="images/email.svg" alt="" width="200px"> + <h1>Chequeá tu correo electrónico</h1> + <p>Hemos enviado a tu correo electrónico los pasos para restablecer tu contraseña.</p> + <a href="#" class="btn btn-default btn-lg">Reenviar correo</a> + <a href="/accounts/login/" class="btn btn-primary">Ir al inicio</a> + </div> + + </section> + </div> + </main> + {% include 'footer.html' %} + +{% endblock %} \ No newline at end of file diff --git a/frontend/templates/registration/forgot_password_email_body.html b/frontend/templates/registration/forgot_password_email_body.html new file mode 100644 index 0000000..0427285 --- /dev/null +++ b/frontend/templates/registration/forgot_password_email_body.html @@ -0,0 +1,217 @@ +{% autoescape off %} + +<!DOCTYPE html> +<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="x-apple-disable-message-reformatting"> + <title>Blockchain Federal Argentina</title> + <style> + html, + body { + margin: 0 auto !important; + padding: 0 !important; + height: 100% !important; + width: 100% !important; + } + * { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + } + div[style*="margin: 16px 0"] { + margin: 0 !important; + } + table, + td { + mso-table-lspace: 0pt !important; + mso-table-rspace: 0pt !important; + } + table { + border-spacing: 0 !important; + border-collapse: collapse !important; + table-layout: fixed !important; + margin: 0 auto !important; + } + table table table { + table-layout: auto; + } + img { + -ms-interpolation-mode:bicubic; + } + *[x-apple-data-detectors], /* iOS */ + .x-gmail-data-detectors, /* Gmail */ + .x-gmail-data-detectors *, + .aBn { + border-bottom: 0 !important; + cursor: default !important; + color: inherit !important; + text-decoration: none !important; + font-size: inherit !important; + font-family: inherit !important; + line-height: inherit !important; + } + .a6S { + display: none !important; + opacity: 0.01 !important; + } + img.g-img + div { + display: none !important; + } + .button-link { + text-decoration: none !important; + } + @media only screen and (min-device-width: 320px) and (max-device-width: 374px) { + .email-container { + min-width: 320px !important; + } + } + @media only screen and (min-device-width: 375px) and (max-device-width: 413px) { + .email-container { + min-width: 375px !important; + } + } + @media only screen and (min-device-width: 414px) { + .email-container { + min-width: 414px !important; + } + } + + </style> + <!-- CSS Reset : END --> + + <!-- Progressive Enhancements : BEGIN --> + <style> + + /* What it does: Hover styles for buttons */ + .button-td, + .button-a { + transition: all 100ms ease-in; + } + .button-td:hover, + .button-a:hover, .button-a:visited { + color: #FFFFFF !important; + background: #0094d4 !important; + border-color: #0094d4 !important; + } + + /* Media Queries */ + @media screen and (max-width: 600px) { + + .email-container { + width: 100% !important; + margin: auto !important; + } + + /* What it does: Forces elements to resize to the full width of their container. Useful for resizing images beyond their max-width. */ + .fluid { + max-width: 100% !important; + height: auto !important; + margin-left: auto !important; + margin-right: auto !important; + } + + /* What it does: Forces table cells into full-width rows. */ + .stack-column, + .stack-column-center { + display: block !important; + width: 100% !important; + max-width: 100% !important; + direction: ltr !important; + } + /* And center justify these ones. */ + .stack-column-center { + text-align: center !important; + } + + /* What it does: Generic utility class for centering. Useful for images, buttons, and nested tables. */ + .center-on-narrow { + text-align: center !important; + display: block !important; + margin-left: auto !important; + margin-right: auto !important; + float: none !important; + } + table.center-on-narrow { + display: inline-block !important; + } + + /* What it does: Adjust typography on small screens to improve readability */ + .email-container p { + font-size: 17px !important; + } + } + + </style> + <!-- Progressive Enhancements : END --> + + <!-- What it does: Makes background images in 72ppi Outlook render at correct size. --> + <!--[if gte mso 9]> + <xml> + <o:OfficeDocumentSettings> + <o:AllowPNG/> + <o:PixelsPerInch>96</o:PixelsPerInch> + </o:OfficeDocumentSettings> + </xml> + <![endif]--> + +</head> +<body width="100%" style="margin: 0; mso-line-height-rule: exactly;"> + <center style="width: 100%; text-align: left;"> + <!--[if mso | IE]> + <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" bgcolor="#EEEEEE"> + <tr> + <td> + <![endif]--> + <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" width="400" style="margin: auto;" class="email-container"> + <tr> + <td style="padding: 30px; text-align: center; border-bottom: #DDD 1px solid" bgcolor="#ffffff" width="100px"> + <a href="https://bfa.ar"><img src="data:image/png;base64,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 +" width="139" height="100" alt="NIC Argentina" border="0" style="background: #dddddd; color: #555555;"></a> + </td> + </tr> + </table> + <table role="presentation" cellspacing="0" cellpadding="" border="0" align="center" width="400" style="margin: auto;" class="email-container"> + <tr> + <td bgcolor="#ffffff" style="padding: 30px 30px; font-family: sans-serif; font-size: 16px; line-height: 190%; color: #555555; text-align: center;"> + <h1>Cambiá tu contraseña</h1> + <p>Si solicitaste restablecer tu contraseña para acceder a BFA, hace click en el botón Cambiar contraseña.</b></p> + <p>Si no lo solicitaste, ignorá este correo.</p> + </td> + </tr> + <tr> + <td bgcolor="#ffffff" style="margin-top: 15px; padding: 0 40px 40px; font-family: sans-serif; font-size: 15px; line-height: 140%; color: #555555; border-bottom: #DDD 1px solid"> + <!-- Button : BEGIN --> + <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" style="margin: auto"> + <tr> + <td style="border-radius: 50px; background: #1C5D82; text-align: center;" class="button-td"> + <a href="{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} +" style="color:#ffffff; background: #0094d4; border: 15px solid #0094d4; font-family: sans-serif; font-size: 16px; line-height: 110%; text-align: center; text-decoration: none; display: block; border-radius: 50px; " class="button-a"> + <span style="color:#ffffff !important; font-weight: bold">Cambiar contraseña</span> + </a> + </td> + </tr> + </table> + </td> + </tr> + </table> + <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" width="100%" style="max-width: 680px; font-family: sans-serif; color: #333333; font-size: 14px; line-height: 140%;"> + <tr> + <td style="padding: 20px; width: 100%; font-family: sans-serif; font-size: 14px; line-height: 140%; text-align: center; color: #333333;" class="x-gmail-data-detectors"> + <span style="font-weight: bold !important;">Blockchain Federal Argentina</span><br> + <a href="https://bfa.ar" style=" color: #333333; text-decoration: underline !important;">https://bfa.ar</a> + </td> + </tr> + </table> + <!--[CONTENT]--> + <!--[if mso | IE]> + </td> + </tr> + </table> + <![endif]--> + </center> +</body> +</html> + +{% endautoescape %} \ No newline at end of file diff --git a/frontend/templates/registration/forgot_password_subject.txt b/frontend/templates/registration/forgot_password_subject.txt new file mode 100644 index 0000000..1a7d3cd --- /dev/null +++ b/frontend/templates/registration/forgot_password_subject.txt @@ -0,0 +1 @@ +Restablecer contraseña \ No newline at end of file diff --git a/frontend/templates/registration/login.html b/frontend/templates/registration/login.html index 094a698..d055832 100644 --- a/frontend/templates/registration/login.html +++ b/frontend/templates/registration/login.html @@ -1,12 +1,3 @@ -<!-- -Copyright 2019 de la Dirección General de Sistemas Informáticos – SecretarÃa Legal y Técnica - Nación. - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ ---> {% extends 'header.html' %} {% load i18n %} {% load static %} @@ -69,12 +60,12 @@ You should have received a copy of the GNU General Public License along with thi </div> </div> </div> - <!--<div class="col-sm-12 font_small"> - <a href="#">¿Olvidaste tu contraseña?</a> - </div>--> + <div class="col-sm-12 font_small"> + <a href="/password_reset/">¿Olvidaste tu contraseña?</a> + </div> <script src='https://www.google.com/recaptcha/api.js'></script> - <div class="g-recaptcha col-sm-12" data-sitekey="{{ data_sitekey }}"></div> + <div class="g-recaptcha col-sm-12" data-sitekey="{{ data_sitekey }}" style="margin-top: 10px;"></div> <div class="form-group col-sm-6 col-sm-push-6 form-footer"> <button class="btn-primary btn btn-block" type="submit" id="submit" value="{% trans "ingresar" %}">{% trans "ingresar" %}</button> diff --git a/frontend/templates/topnav-deslogueado.html b/frontend/templates/topnav-deslogueado.html index a4d976c..cbe0cbb 100644 --- a/frontend/templates/topnav-deslogueado.html +++ b/frontend/templates/topnav-deslogueado.html @@ -1,12 +1,3 @@ -<!-- -Copyright 2019 de la Dirección General de Sistemas Informáticos – SecretarÃa Legal y Técnica - Nación. - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ ---> {% load i18n %} {% load static %} <nav id="navbar" role="banner" class="navbar navbar-default navbar-fixed-top navbar-content"> @@ -22,7 +13,6 @@ You should have received a copy of the GNU General Public License along with thi <nav role="navigation" class="" aria-labelledby="block-bfa-main-menu-menu" id="block-bfa-main-menu"> <ul class="menu nav navbar-nav navbar-right"> <li> - <a href="https://bfa.ar/">Cancelar</a> </li> </ul> </nav> diff --git a/frontend/templates/topnav-logueado.html b/frontend/templates/topnav-logueado.html index 3f1defa..b36c15b 100644 --- a/frontend/templates/topnav-logueado.html +++ b/frontend/templates/topnav-logueado.html @@ -1,12 +1,3 @@ -<!-- -Copyright 2019 de la Dirección General de Sistemas Informáticos – SecretarÃa Legal y Técnica - Nación. - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ ---> {% load i18n %} {% load static %} <nav id="navbar" role="banner" class="navbar navbar-default navbar-fixed-top navbar-content"> @@ -29,15 +20,15 @@ You should have received a copy of the GNU General Public License along with thi <nav role="navigation" aria-labelledby="block-bfa-main-menu-menu" id="block-bfa-main-menu"> <ul class="menu nav navbar-nav navbar-right"> <li class="active"> - <a href="#" class="is-active">Cuentas</a> + <a href="/accounts/list/" class="is-active">Cuentas</a> </li> <li class="expanded dropdown"> <a href="" class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-user-circle"></i> {{ user.first_name }} {{ user.last_name }} <span class="caret"></span></a> <ul class="menu dropdown-menu"> - <!--<li> - <a href="#">Mis datos</a> - </li>--> + <li> + <a href="/mis_datos/">Mis datos</a> + </li> <li class="logout"> <a href="/accounts/logout/" >Salir</a> </li> diff --git a/frontend/urls.py b/frontend/urls.py index b96407f..37290ae 100644 --- a/frontend/urls.py +++ b/frontend/urls.py @@ -8,6 +8,8 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ """ from django.conf.urls import include, url +from django.urls import path + from frontend.views import CaptchaLoginView from . import views @@ -15,6 +17,7 @@ from .forms import CustomUserForm from django.views.generic import RedirectView from django.contrib.auth import views as auth_views + urlpatterns = [ url(r'^$', RedirectView.as_view(url='/accounts/login')), url(r'^accounts/register/$', views.RegistrationView.as_view(form_class=CustomUserForm), @@ -27,7 +30,20 @@ urlpatterns = [ url(r'^accounts/get_service_address/$', views.get_service_address), url(r'^accounts/approve/(?P<pk>[\w]+)/$', views.approve_account), url(r'^accounts/approved/$', views.account_approved), + url(r'^mis_datos/$', views.update_user), url(r'^accounts/', include('django_registration.backends.activation.urls')), + url('change_password/$', views.change_password, name='change_password'), + url('^password_reset/$', auth_views.PasswordResetView.as_view( + template_name='registration/forgot_password.html', + subject_template_name='registration/forgot_password_subject.txt', + html_email_template_name='registration/forgot_password_email_body.html'), + name='forgot_password'), + url('^password_reset/done/$', auth_views.PasswordResetDoneView.as_view(template_name='registration/forgot_password_done.html'), name='password_reset_done'), + path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='registration/forgot_password_confirm.html'), name='password_reset_confirm'), + path('reset/done/', auth_views.PasswordResetCompleteView.as_view(template_name='registration/forgot_password_complete.html'), name='password_reset_complete'), + + + #url('^', include('django.contrib.auth.urls')), url('login/', CaptchaLoginView.as_view(redirect_authenticated_user=True), name='login'), url('logout/', auth_views.LogoutView.as_view(), name='logout'), ] \ No newline at end of file diff --git a/frontend/views.py b/frontend/views.py index 005b9ef..c3468b4 100644 --- a/frontend/views.py +++ b/frontend/views.py @@ -11,13 +11,15 @@ import logging import requests from django.views.generic.list import ListView -from django.views.generic.edit import CreateView, DeleteView +from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.views.decorators.csrf import csrf_exempt from django.http import HttpResponseRedirect from django.http.response import JsonResponse from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.views import LoginView from django.contrib.auth.models import User +from django.contrib.auth.decorators import login_required + from django.contrib import messages from django.utils.translation import ugettext as _ from django.db import transaction, IntegrityError @@ -31,7 +33,7 @@ from django_registration.backends.activation.views import RegistrationView from raven.contrib.django.raven_compat.models import client from Poppins import settings -from api.models import CustomUser, Institution, Service +from api.models import CustomUser, Institution, Service, Section from api.managers import RegistrationManager, ServiceManager from dapp.models import Account from dapp.services import AsociacionCuenta, PetitorioEtherCuenta, NotValidAddressException @@ -43,6 +45,8 @@ logger = logging.getLogger('logger') class RegistrationView(RegistrationView): + email_body_template = 'django_registration/activation_email_body.html' + def post(self, request, *args, **kwargs): """ Handle POST requests: instantiate a form instance with the passed @@ -93,9 +97,37 @@ class RegistrationView(RegistrationView): messages.error(self.request, _('error_register'), extra_tags='danger') return HttpResponseRedirect('/accounts/register/') - def form_invalid(self, form): - messages.error(self.request, form.errors['__all__'][0], extra_tags='danger') - return HttpResponseRedirect('/accounts/register/') + # def form_invalid(self, form): + # messages.error(self.request, form.errors['__all__'][0], extra_tags='danger') + # return HttpResponseRedirect('/accounts/register/') + + def send_activation_email(self, user): + """ + Send the activation email. The activation key is the username, + signed using TimestampSigner. + + """ + activation_key = self.get_activation_key(user) + context = self.get_email_context(activation_key) + context['user'] = user + subject = render_to_string( + template_name=self.email_subject_template, + context=context, + request=self.request + ) + # Force subject to a single line to avoid header-injection + # issues. + subject = ''.join(subject.splitlines()) + message = render_to_string( + template_name=self.email_body_template, + context=context, + request=self.request + ) + + try: + user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL, html_message=message) + except Exception: + pass class AccountListView(LoginRequiredMixin, ListView): @@ -146,7 +178,7 @@ class AccountCreateView(LoginRequiredMixin, CreateView): except NotValidAddressException: messages.error(request, _('address_not_valid') % request.POST['address'], extra_tags='danger') except IntegrityError as e: - if 'service.name' in str(e): + if 'service_name_key' in str(e): messages.error(request, _('error_create_view') + ': ' + _('existing_service') % request.POST['service_name'], extra_tags='danger') else: messages.error(request, _('error_create_view'), extra_tags='danger') @@ -200,8 +232,8 @@ class CustomUserAccountCreateView(LoginRequiredMixin, CreateView): messages.success(request, (_('existing_account_added') % (account.address))) except IntegrityError as e: - if 'UNIQUE constraint failed' in str(e): - messages.error(request, _('user_already_has_account'), extra_tags='danger') + if 'duplicate key value violates unique constraint' in str(e): + messages.error(request, _('user_already_has_account') % (account.address), extra_tags='danger') else: messages.error(request, _('error_create_view'), extra_tags='danger') except Exception as e: @@ -284,3 +316,48 @@ def account_approved(request): return render(request, 'django_registration/account_approved.html') +@login_required(login_url='/accounts/login/') +def update_user(request): + + custom_user = CustomUser.objects.get(user_id=request.user.id) + + user = request.user + + if request.method == 'GET': + + context = { + 'custom_user': custom_user, + 'sections': Section.objects.all() + } + + return render(request, 'django_registration/update_user.html', context) + else: + + user.first_name = request.POST['first_name'] + user.last_name = request.POST['last_name'] + user.email = request.POST['email'] + user.save() + + custom_user.cuit = request.POST['cuit'] + custom_user.organization = request.POST['organization'] + custom_user.rol = request.POST['rol'] + custom_user.section_id = request.POST['section'] + custom_user.save() + + messages.success(request, _('user_updated')) + + return HttpResponseRedirect('/mis_datos/') + +@login_required(login_url='/accounts/login/') +def change_password(request): + + if request.method == 'GET': + return render(request, 'registration/change_password.html', {}) + else: + user = request.user + user.set_password(request.POST['new_password1']) + user.save() + + messages.success(request, _('password_changed')) + + return HttpResponseRedirect('/mis_datos/') \ No newline at end of file diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo index 114a7d48d572ad7f561aaaba66a955c707f9de13..cdfd3daabd565290dd3fb5a9da395327559eff16 100644 GIT binary patch delta 24 fcmcb`e2aO)CSFTj14CUy3k5?{D+9BQ`=uEHVc7>6 delta 24 fcmcb`e2aO)CSD6&LnB=SGX+C4D<i{=`=uEHVZH|y diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index 8d949d3..f34a4d0 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-06 16:21-0300\n" +"POT-Creation-Date: 2019-01-18 15:06-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -18,149 +18,180 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: Poppins/settings.py:118 +#: Poppins/settings.py:127 msgid "Spanish" msgstr "" -#: api/models.py:32 frontend/forms.py:12 +#: dapp/validators.py:19 +#, python-format +msgid "%(address)s is not a valid address" +msgstr "" + +#: frontend/forms.py:22 msgid "public" msgstr "" -#: api/models.py:33 frontend/forms.py:13 +#: frontend/forms.py:23 msgid "private" msgstr "" -#: api/models.py:34 frontend/forms.py:14 +#: frontend/forms.py:24 msgid "academic" msgstr "" -#: api/models.py:35 frontend/forms.py:15 +#: frontend/forms.py:25 msgid "person" msgstr "" -#: dapp/validators.py:10 -#, python-format -msgid "%(address)s is not a valid address" -msgstr "" - -#: frontend/forms.py:18 +#: frontend/forms.py:28 msgid "first_name" msgstr "" -#: frontend/forms.py:19 +#: frontend/forms.py:29 msgid "last_name" msgstr "" -#: frontend/forms.py:21 +#: frontend/forms.py:31 msgid "email" msgstr "" -#: frontend/forms.py:28 +#: frontend/forms.py:38 msgid "ya_existe_usuario_email" msgstr "" -#: frontend/forms.py:31 +#: frontend/forms.py:41 msgid "ya_existe_usuario_username" msgstr "" -#: frontend/templates/dapp/account_form.html:14 -#: frontend/templates/dapp/account_form.html:21 +#: frontend/templates/dapp/account_form.html:23 +#: frontend/templates/dapp/account_form.html:30 msgid "agregar_cuenta" msgstr "" -#: frontend/templates/dapp/account_form.html:14 -#: frontend/templates/header.html:12 +#: frontend/templates/dapp/account_form.html:23 +#: frontend/templates/header.html:21 msgid "site_name" msgstr "" -#: frontend/templates/dapp/account_form.html:26 -#: frontend/templates/dapp/account_form.html:27 +#: frontend/templates/dapp/account_form.html:35 +#: frontend/templates/dapp/account_form.html:36 msgid "address" msgstr "" -#: frontend/templates/dapp/account_form.html:30 +#: frontend/templates/dapp/account_form.html:39 msgid "agregar" msgstr "" -#: frontend/templates/dapp/account_form.html:33 +#: frontend/templates/dapp/account_form.html:42 msgid "cancelar" msgstr "" -#: frontend/templates/dapp/account_list.html:10 +#: frontend/templates/dapp/account_list.html:19 msgid "cuentas" msgstr "" -#: frontend/templates/dapp/account_list.html:62 -#: frontend/templates/dapp/account_list.html:67 +#: frontend/templates/dapp/account_list.html:95 +#: frontend/templates/dapp/account_list.html:100 msgid "no_se_encontraron_cuentas" msgstr "" -#: frontend/templates/django_registration/activation_complete.html:5 -#: frontend/templates/django_registration/activation_complete.html:17 -msgid "cuenta_verificada" +#: frontend/templates/dapp/account_list.html:215 +msgid "no_se_encontraron_cuentas_existentes" msgstr "" -#: frontend/templates/django_registration/registration_complete.html:5 +#: frontend/templates/django_registration/account_approved.html:14 +#: frontend/templates/django_registration/registration_complete.html:14 +#: frontend/templates/registration/forgot_password_done.html:19 msgid "check_email" msgstr "" -#: frontend/templates/django_registration/registration_form.html:10 -#: frontend/templates/django_registration/registration_form.html:18 +#: frontend/templates/django_registration/activation_complete.html:14 +#: frontend/templates/django_registration/activation_complete.html:24 +msgid "cuenta_verificada" +msgstr "" + +#: frontend/templates/django_registration/registration_form.html:19 +#: frontend/templates/django_registration/registration_form.html:27 msgid "registro_de_usuarios" msgstr "" -#: frontend/templates/login.html:9 frontend/templates/login.html:18 +#: frontend/templates/django_registration/update_user.html:10 +msgid "mis_datos" +msgstr "" + +#: frontend/templates/login.html:18 frontend/templates/login.html:27 #: frontend/templates/registration/login.html:9 #: frontend/templates/registration/login.html:18 msgid "iniciar_sesion" msgstr "" -#: frontend/templates/login.html:43 +#: frontend/templates/login.html:52 #: frontend/templates/registration/login.html:71 msgid "ingresar" msgstr "" -#: frontend/views.py:55 frontend/views.py:238 +#: frontend/templates/registration/change_password.html:9 +#: frontend/templates/registration/forgot_password_confirm.html:9 +msgid "password_reset" +msgstr "" + +#: frontend/templates/registration/forgot_password.html:19 +msgid "forgot_password" +msgstr "" + +#: frontend/templates/registration/forgot_password_complete.html:9 +msgid "password_reset_complete" +msgstr "" + +#: frontend/views.py:72 frontend/views.py:298 msgid "invalid_captcha" msgstr "No reCAPTCHA" -#: frontend/views.py:81 +#: frontend/views.py:99 msgid "error_register" msgstr "" -#: frontend/views.py:131 +#: frontend/views.py:177 msgid "account_added" msgstr "" -#: frontend/views.py:133 +#: frontend/views.py:179 msgid "existing_account" msgstr "" -#: frontend/views.py:135 +#: frontend/views.py:181 msgid "address_not_valid" msgstr "" -#: frontend/views.py:138 frontend/views.py:140 frontend/views.py:143 -#: frontend/views.py:182 frontend/views.py:185 +#: frontend/views.py:184 frontend/views.py:186 frontend/views.py:189 +#: frontend/views.py:240 frontend/views.py:243 msgid "error_create_view" msgstr "" -#: frontend/views.py:138 +#: frontend/views.py:184 msgid "existing_service" msgstr "" -#: frontend/views.py:177 +#: frontend/views.py:235 msgid "existing_account_added" msgstr "" -#: frontend/views.py:180 +#: frontend/views.py:238 msgid "user_already_has_account" msgstr "" -#: frontend/views.py:201 +#: frontend/views.py:259 msgid "ether_solicitado" msgstr "" -#: frontend/views.py:204 +#: frontend/views.py:262 msgid "error_peticion_ether" msgstr "" + +#: frontend/views.py:351 +msgid "user_updated" +msgstr "" + +#: frontend/views.py:365 +msgid "password_changed" +msgstr "" diff --git a/locale/es/LC_MESSAGES/django.mo b/locale/es/LC_MESSAGES/django.mo index 4badeebd1c224f17b164e7f94e335c8ed6196484..6b614a627db8ceb5226669a2de9014e2c36a993b 100644 GIT binary patch delta 1443 zcmaKrJ!}+56vxN-0Gm(a#0DG#1K5NVCOE_h2oeHINC*%gG99oQcE`smcf04Ey(6Z` zi2_J03dG5xK_EyKB!m!^g#;2O8VZV}L<)$C3PF=Pzqhy8K#|eT{N~Ngy!pR3@0#5+ zz4d>(3)70Wnch!7*{0M8yfKe~R%utN15UuD@H|`ye}gOF)!e=Vmto(9vVR6HhEJjF zdjaL#Yd9aiZLQbUJ0@SVpb9MqJ+KRNAm<3|#onLWr{E&&2rh?{P%iu(ihyhR`fb>W z{UGNfxElKz9DuK2m#T9wa^zqSTnPu@0=OHB;?dkb2u0{|D2|J86`X)e;1rbe*I^&L z4}T_`&!Gt3j<asK7m7Uw*K)t|nDD7z8AQk>C=pG=b?_#XiyuQi^*4hEd<nmYZ=i<V z9QqD!gB5rRehXi~jqqQnVIS({{7<m{4U>IL_)VRLlF}lS3(w{2S0JC7X7~Z#g2V7H zD78``9C@N$Py`=?Xi^h7C!zSi0HqeDpw!xpMdW`ylNlByH7}vO%{w><zoLT3VCGyL zi&IIt9F~2OZaFVmlaxy^Qlt`uM8286i7xfTE6ld6-ZG2)ODg33Hqa$anl6PR5sPZH zWK9J2(DOe=YcU_C(m!p~v|5`lWPvbWL#O7l3@GE9z?MV*j}P<OmXF6tF;2aTaqe84 z1daFY+v?@ed4Wk|r=r+%*0YfxM`>b`IP(0ejZ*VJzj*eS(4}m$PJQ(1`Daa3w87j$ zVx3LDFg-smS4uW*vyI(_BTK5zCSJ9I5F0e63Ky5|9NIcOG`vF(kL=pI{bB$7zV`al zCr3)PFfd%G)2eRCbhi1x>`@1zBDa`?N$7_r(ayTC`7lzWt!tXMwJmAiR8rKby%k$3 zg+Z(ihfcSGABzK1Yu+<DiZuZ>|8zQ!UK<zVGUzf+8@agZswN5JEsb(VUtP~-Kvzs+ zv_VJ_A){FqGkLlk2jO_gOPDSCXq@PAQ)3J>%_xhiwr0wbMKx;5XF`@fk57$#7Op;P xv_n4eEMPls8<#r{{CLRZlJ%g|lV)~TEsXqXiCyYMOZl9hxY6IauF=~$^dF>b3+Dg; delta 878 zcmYk)KWGzS7{~Fq=8sKmtHxTJXzN?sk}8&(fI%uE!9P?eRH=iLcr+(odtSoXh<3^1 zU=cw)L<bjfb}^Gn2OS*MK}X$01qYqP$?q>YiVwW^dEdKx?|trh-&aF#a;?v~<Re3j z(e}|MdW@OD!&|rz->?_IV?X}Jt$L6!W+(Kb#swU}1E}{)xD97f@0~@xcL`H?rF*|+ zuF@Ig#x2wb?&A)88v6o=7;nVmkC<ir6}8YW)V#mA9WzN9<}r`sn8p*R1Ww1}c^ot? zV;1RX!ZjSm5cl9cEZ}oop(-1wg%9zy93DlD=WrAkQ455qgw{|AuH$}ui2Bi&sQ2Dt zn)S^)Ix6`mw3z1UK`deeFJKX0<2e36ivxU}DP{(>P=$*sa1wXpLVVvvRU$y9n!B+N zuthUZxM+`_q0T@XwcvZ4z&|*NBb13kY{uATuiLSp%BX5eK*7{b^l{a`@9hpd36cD= z&QT{T9TqCwNkIFpKhZWQR9=-@<x?sDk6jFuyv~faQK9lHbcS_kM`*+C>xsUeXgyhu zz9jR}@zg@}ICZE0*mS8peWYSbmDzHsJ(VsbqRW~5Xy~4*p1(L(wL#s6uH$=aPOWaL z4cGU*T0Q!ZDMXFzx#Ah$Hg7bY(5u_qj$QTKz_mBMV5#XlHOKmnU23|)suTUp&i?~a C4p*80 diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po index b256ccc..a5ffff5 100644 --- a/locale/es/LC_MESSAGES/django.po +++ b/locale/es/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-06 16:21-0300\n" +"POT-Creation-Date: 2019-01-18 15:06-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -18,151 +18,182 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: Poppins/settings.py:118 +#: Poppins/settings.py:127 msgid "Spanish" msgstr "" -#: api/models.py:32 frontend/forms.py:12 +#: dapp/validators.py:19 +#, python-format +msgid "%(address)s is not a valid address" +msgstr "" + +#: frontend/forms.py:22 msgid "public" msgstr "Público" -#: api/models.py:33 frontend/forms.py:13 +#: frontend/forms.py:23 msgid "private" msgstr "Privado" -#: api/models.py:34 frontend/forms.py:14 +#: frontend/forms.py:24 msgid "academic" msgstr "Académico" -#: api/models.py:35 frontend/forms.py:15 +#: frontend/forms.py:25 msgid "person" msgstr "Persona" -#: dapp/validators.py:10 -#, python-format -msgid "%(address)s is not a valid address" -msgstr "" - -#: frontend/forms.py:18 +#: frontend/forms.py:28 msgid "first_name" msgstr "Nombre" -#: frontend/forms.py:19 +#: frontend/forms.py:29 msgid "last_name" msgstr "Apellido" -#: frontend/forms.py:21 +#: frontend/forms.py:31 msgid "email" msgstr "E-Mail" -#: frontend/forms.py:28 +#: frontend/forms.py:38 msgid "ya_existe_usuario_email" msgstr "Ya existe un registro con ese E-mail" -#: frontend/forms.py:31 +#: frontend/forms.py:41 msgid "ya_existe_usuario_username" msgstr "Ya existe un registro con ese usuario" -#: frontend/templates/dapp/account_form.html:14 -#: frontend/templates/dapp/account_form.html:21 +#: frontend/templates/dapp/account_form.html:23 +#: frontend/templates/dapp/account_form.html:30 msgid "agregar_cuenta" msgstr "Asociar cuenta" -#: frontend/templates/dapp/account_form.html:14 -#: frontend/templates/header.html:12 +#: frontend/templates/dapp/account_form.html:23 +#: frontend/templates/header.html:21 msgid "site_name" msgstr "Blockchain Federal Argentina" -#: frontend/templates/dapp/account_form.html:26 -#: frontend/templates/dapp/account_form.html:27 +#: frontend/templates/dapp/account_form.html:35 +#: frontend/templates/dapp/account_form.html:36 msgid "address" msgstr "Dirección" -#: frontend/templates/dapp/account_form.html:30 +#: frontend/templates/dapp/account_form.html:39 msgid "agregar" msgstr "Agregar" -#: frontend/templates/dapp/account_form.html:33 +#: frontend/templates/dapp/account_form.html:42 msgid "cancelar" msgstr "Cancelar" -#: frontend/templates/dapp/account_list.html:10 +#: frontend/templates/dapp/account_list.html:19 msgid "cuentas" msgstr "Cuentas" -#: frontend/templates/dapp/account_list.html:62 -#: frontend/templates/dapp/account_list.html:67 +#: frontend/templates/dapp/account_list.html:95 +#: frontend/templates/dapp/account_list.html:100 msgid "no_se_encontraron_cuentas" -msgstr "No se encontraron cuentas" +msgstr "TodavÃa no tenés cuentas asociadas a tu usuario." -#: frontend/templates/django_registration/activation_complete.html:5 -#: frontend/templates/django_registration/activation_complete.html:17 -msgid "cuenta_verificada" -msgstr "¡Cuenta verificada!" +#: frontend/templates/dapp/account_list.html:215 +msgid "no_se_encontraron_cuentas_existentes" +msgstr "No se encontraron cuentas existentes para agregar" -#: frontend/templates/django_registration/registration_complete.html:5 +#: frontend/templates/django_registration/account_approved.html:14 +#: frontend/templates/django_registration/registration_complete.html:14 +#: frontend/templates/registration/forgot_password_done.html:19 msgid "check_email" msgstr "Chequeá tu correo electrónico" -#: frontend/templates/django_registration/registration_form.html:10 -#: frontend/templates/django_registration/registration_form.html:18 +#: frontend/templates/django_registration/activation_complete.html:14 +#: frontend/templates/django_registration/activation_complete.html:24 +msgid "cuenta_verificada" +msgstr "¡Cuenta verificada!" + +#: frontend/templates/django_registration/registration_form.html:19 +#: frontend/templates/django_registration/registration_form.html:27 msgid "registro_de_usuarios" msgstr "Registrate en BFA" -#: frontend/templates/login.html:9 frontend/templates/login.html:18 +#: frontend/templates/django_registration/update_user.html:10 +msgid "mis_datos" +msgstr "Mis datos" + +#: frontend/templates/login.html:18 frontend/templates/login.html:27 #: frontend/templates/registration/login.html:9 #: frontend/templates/registration/login.html:18 msgid "iniciar_sesion" msgstr "Iniciar sesión" -#: frontend/templates/login.html:43 +#: frontend/templates/login.html:52 #: frontend/templates/registration/login.html:71 msgid "ingresar" msgstr "Ingresar" -#: frontend/views.py:55 frontend/views.py:238 +#: frontend/templates/registration/change_password.html:9 +#: frontend/templates/registration/forgot_password_confirm.html:9 +msgid "password_reset" +msgstr "Cambiá tu contraseña" + +#: frontend/templates/registration/forgot_password.html:19 +msgid "forgot_password" +msgstr "¿Olvidaste tu contraseña?" + +#: frontend/templates/registration/forgot_password_complete.html:9 +msgid "password_reset_complete" +msgstr "Tu contraseña ha sido cambiada" + +#: frontend/views.py:72 frontend/views.py:298 msgid "invalid_captcha" -msgstr "reCAPTHA no realizado" +msgstr "Completá el captcha" -#: frontend/views.py:81 +#: frontend/views.py:99 msgid "error_register" msgstr "Ocurrió un error al realizar el registro" -#: frontend/views.py:131 +#: frontend/views.py:177 msgid "account_added" msgstr "Cuenta %s agregada" -#: frontend/views.py:133 +#: frontend/views.py:179 msgid "existing_account" msgstr "La cuenta %s ya se encuentra registrada" -#: frontend/views.py:135 +#: frontend/views.py:181 msgid "address_not_valid" msgstr "La dirección %s no es válida" -#: frontend/views.py:138 frontend/views.py:140 frontend/views.py:143 -#: frontend/views.py:182 frontend/views.py:185 +#: frontend/views.py:184 frontend/views.py:186 frontend/views.py:189 +#: frontend/views.py:240 frontend/views.py:243 msgid "error_create_view" msgstr "Ocurrió un error al intentar agregar la cuenta" -#: frontend/views.py:138 +#: frontend/views.py:184 msgid "existing_service" msgstr "Ya existe un servicio llamado %s" -#: frontend/views.py:177 +#: frontend/views.py:235 msgid "existing_account_added" msgstr "La cuenta existente %s fue agregada" -#: frontend/views.py:180 +#: frontend/views.py:238 msgid "user_already_has_account" -msgstr "El usuario ya tiene vinculada la cuenta" +msgstr "La cuenta %s ya ha sido vinculada" -#: frontend/views.py:201 +#: frontend/views.py:259 msgid "ether_solicitado" msgstr "" "Su solicitud de carga para la cuenta %s será evaluada por los " "administradores. Nos contactaremos a la brevedad." -#: frontend/views.py:204 +#: frontend/views.py:262 msgid "error_peticion_ether" msgstr "No se pudo realizar la petición" + +#: frontend/views.py:351 +msgid "user_updated" +msgstr "Usuario modificado" + +#: frontend/views.py:365 +msgid "password_changed" +msgstr "Contraseña modificada. Por favor ingresá nuevamente" diff --git a/logica_cuentas/models.py b/logica_cuentas/models.py index 28ac5d9..f01ed2e 100644 --- a/logica_cuentas/models.py +++ b/logica_cuentas/models.py @@ -15,7 +15,6 @@ from logica_cuentas.managers import RelacionUsuarioAccountManager, RelacionUsuar class RelacionUsuarioAccountStatus(models.Model): - id = models.IntegerField(primary_key=True) descripcion = models.CharField(max_length=60) objects = RelacionUsuarioAccountStatusManager() diff --git a/requirements.txt b/requirements.txt index 2b507b5..d504a15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,6 +19,9 @@ hexbytes==0.1.0 idna==2.7 lru-dict==1.1.6 parsimonious==0.8.0 +pkg-resources==0.0.0 +psycopg2==2.7.6.1 +psycopg2-binary==2.7.6.1 pycryptodome==3.6.6 pytz==2018.5 raven==6.9.0 @@ -28,4 +31,4 @@ six==1.11.0 toolz==0.9.0 urllib3==1.23 web3==4.5.0 -websockets==5.0.1 +websockets==5.0.1 \ No newline at end of file -- GitLab