From a8a0d9b901a03ab3a8277de72d1d18e6fd79d558 Mon Sep 17 00:00:00 2001
From: Juliana <juliana@le-filament.com>
Date: Thu, 21 Apr 2022 15:40:07 +0200
Subject: [PATCH] [UPD]Add signup route
---
security/ir.model.access.csv | 1 +
services/auth_services.py | 264 ++++++++++++++++++++++++++++++++++-
2 files changed, 261 insertions(+), 4 deletions(-)
diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv
index 77661d7..f7b609e 100644
--- a/security/ir.model.access.csv
+++ b/security/ir.model.access.csv
@@ -5,3 +5,4 @@ id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
"access_acc_actu_group_portal","acc_actu group_portal","acc_actus.model_acc_actu","base.group_portal",1,0,0,0
"access_acc_account_group_portal","acc_account group_portal","acc_account.model_acc_account","base.group_portal",1,0,0,0
"access_acc_contract_group_portal","acc_contract group_portal","acc_operation.model_acc_contract","base.group_portal",1,0,0,0
+"access_mail_template_group_portal","mail_template group_portal","mail.model_mail_template","base.group_portal",1,0,0,0
diff --git a/services/auth_services.py b/services/auth_services.py
index 85bab21..b4e5e1d 100644
--- a/services/auth_services.py
+++ b/services/auth_services.py
@@ -1,6 +1,9 @@
# © 2021 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+import logging
+import werkzeug
+
from datetime import datetime, timedelta
import jwt
@@ -8,6 +11,8 @@ import jwt
from odoo.addons.base_rest import restapi
from odoo.addons.component.core import Component
+_logger = logging.getLogger(__name__)
+
class AuthService(Component):
_inherit = "base.rest.service"
@@ -68,6 +73,187 @@ class AuthService(Component):
}
return datas
+ # A faire pour gestion User
+ @restapi.method(
+ [(["/reset-password"], "POST")],
+ input_param=restapi.CerberusValidator("_validator_reset"),
+ output_param=restapi.CerberusValidator("_validator_return_reset"),
+ auth="none",
+ save_session=True,
+ cors="*",
+ crsf=False,
+ )
+ def reset_password(self, **params):
+ """
+ Log user and return user data & JWT token
+ """
+ User = self.env["res.users"].sudo()
+ login = params.get("login", False)
+ datas = {}
+ if login:
+ user = User.search([("login", "=", login)])
+ if user:
+ jwt_validator = self.env.ref("acc_rest_api.elo_validator").sudo()
+ exp = datetime.now() + timedelta(
+ hours=(jwt_validator.token_expiration * 24))
+ payload = {
+ "aud": jwt_validator.audience,
+ "iss": jwt_validator.issuer,
+ "exp": exp,
+ "email": user.login,
+ "id": user.id,
+ "partner_id": user.partner_id.id,
+ }
+ token = jwt.encode(
+ payload,
+ key=jwt_validator.secret_key,
+ algorithm=jwt_validator.secret_algorithm,
+ )
+ datas = {
+ # "user": user_datas,
+ "token": {"access_token": token,
+ "expiration_date": payload.get("exp")},
+ }
+ # send email to users with their signup url
+ template = False
+ if not template:
+ template = self.env.ref('acc_portal.acc_reset_password_email')
+ assert template._name == 'mail.template'
+
+ # template.sudo().write(template_values)
+ try:
+
+ lang = user.lang
+
+ query = dict(db=self.request.env.cr.dbname)
+ query['login'] = user.login
+ route = 'signup'
+ signup_url = "/%s?%s" % (route, werkzeug.urls.url_encode(query))
+ signup_url = werkzeug.urls.url_join(user.company_id.url_app, signup_url)
+
+ user.partner_id.sudo().signup_prepare()
+
+ template.sudo().with_context(
+ portal_url=signup_url,
+ lang=lang
+ ).send_mail(
+ user.id,
+ force_send=True,
+ raise_exception=True)
+ except Exception as e:
+ datas['error'] = str(e)
+ _logger.info("Password reset email sent for user <%s> to <%s>",
+ user.login, user.email)
+ else:
+ datas['info'] = "Veuillez réinitialiser votre mot de passe: adresse email incorrecte"
+ return datas
+
+ @restapi.method(
+ [(["/get-password"], "GET")],
+ input_param=restapi.CerberusValidator("_validator_get_password"),
+ output_param=restapi.CerberusValidator("_validator_return_password"),
+ cors="*",
+ crsf=False,
+ )
+ def get_password(self):
+ user_id = self.env["res.users"].browse(self.request.uid)
+ user = {
+ "login": user_id.login,
+ }
+ return user
+
+ @restapi.method(
+ [(["/get-signup"], "GET")],
+ input_param=restapi.CerberusValidator("_validator_get_password"),
+ output_param=restapi.CerberusValidator("_validator_return_password"),
+ cors="*",
+ crsf=False,
+ )
+ def get_signup(self, **params):
+ user_id = self.env["res.users"].browse(self.request.uid)
+ user = {
+ "login": user_id.login,
+ }
+ return user
+
+ @restapi.method(
+ [(["/set-password"], "POST")],
+ input_param=restapi.CerberusValidator("_validator_set_password"),
+ output_param=restapi.CerberusValidator("_validator_return_password"),
+ auth="none",
+ save_session=True,
+ cors="*",
+ crsf=False,
+ )
+ def set_password(self, **params):
+ User = self.env["res.users"].sudo()
+ login = params.get("login", False)
+ password = params.get("password", False)
+ confirm_password = params.get("confirm_password", False)
+ datas = {}
+ if login:
+ user = User.search([("login", "=", login)])
+ if user:
+ if password == confirm_password:
+ user.write({'password': password})
+ else:
+ datas['error'] = "Les mots de passe ne correspondent pas, veuillez les saisir à nouveau."
+ return datas
+
+ @restapi.method(
+ [(["/signup"], "POST")],
+ input_param=restapi.CerberusValidator("_validator_signup"),
+ output_param=restapi.CerberusValidator("_validator_return_signup"),
+ auth="none",
+ save_session=True,
+ cors="*",
+ crsf=False,
+ )
+ def signup(self, **params):
+ User = self.env["res.users"].sudo()
+ login = params.get("login", False)
+ password = params.get("password", False)
+ confirm_password = params.get("confirm_password", False)
+ datas = {}
+ if login:
+ user = User.search([("login", "=", login)])
+ if user:
+ user_datas = user.mapped(
+ lambda u: {
+ "userId": u.id,
+ "userEmail": u.login,
+ "userName": u.name,
+ "userCompany": u.parent_id.name if u.parent_id else None,
+ }
+ )[0]
+ if password == confirm_password:
+ jwt_validator = self.env.ref("acc_rest_api.elo_validator").sudo()
+ exp = datetime.now() + timedelta(
+ hours=(jwt_validator.token_expiration * 24))
+ payload = {
+ "aud": jwt_validator.audience,
+ "iss": jwt_validator.issuer,
+ "exp": exp,
+ "email": user.login,
+ "id": user.id,
+ "partner_id": user.partner_id.id,
+ }
+ token = jwt.encode(
+ payload,
+ key=jwt_validator.secret_key,
+ algorithm=jwt_validator.secret_algorithm,
+ )
+ datas = {
+ "user": user_datas,
+ "token": {"access_token": token,
+ "expiration_date": payload.get("exp")},
+ }
+ user.write({'password': password})
+ else:
+ datas["error"] = "Les mots de passe ne correspondent pas, veuillez les saisir à nouveau."
+ datas["user"] = user_datas
+ return datas
+
@restapi.method(
[(["/logout"], "GET")],
cors="*",
@@ -150,6 +336,31 @@ class AuthService(Component):
},
}
+ def _validator_reset(self):
+ return {
+ "login": {"type": "string"},
+ }
+
+ def _validator_return_reset(self):
+ return {
+ # "user": {
+ # "type": "dict",
+ # "schema": {
+ # "userId": {"type": "integer"},
+ # "userEmail": {"type": "string"},
+ # "userName": {"type": "string"},
+ # "userCompany": {"type": "string", "nullable": True},
+ # },
+ # },
+ "token": {
+ "type": "dict",
+ "schema": {
+ "access_token": {"type": "string", "nullable": True},
+ "expiration_date": {"type": "datetime", "nullable": True},
+ },
+ },
+ }
+
def _validator_logout(self):
return {}
@@ -162,15 +373,60 @@ class AuthService(Component):
def _validator_set_my_account(self):
return {
"login": {"type": "string"},
- "firstname": {"type": "string"},
- "lastname": {"type": "string"},
+ "firstname": {"type": "string", "nullable": True},
+ "lastname": {"type": "string", "nullable": True},
+ }
+
+ def _validator_get_password(self):
+ return {}
+
+ def _validator_set_password(self):
+ return {
+ "login": {"type": "string"},
+ "password": {"type": "string", "nullable": True},
+ "confirm_password": {"type": "string", "nullable": True},
+ }
+
+ def _validator_signup(self):
+ return {
+ "login": {"type": "string"},
+ "password": {"type": "string", "nullable": True},
+ "confirm_password": {"type": "string", "nullable": True},
}
def _validator_return_my_account(self):
return {
"login": {"type": "string"},
- "firstname": {"type": "string"},
- "lastname": {"type": "string"},
+ "firstname": {"type": "string", "nullable": True},
+ "lastname": {"type": "string", "nullable": True},
"name": {"type": "string"},
"company": {"type": "string", "nullable": True},
}
+
+ def _validator_return_password(self):
+ return {
+ "login": {"type": "string"},
+ }
+
+ def _validator_return_signup(self):
+ return {
+ "user": {
+ "type": "dict",
+ "schema": {
+ "userId": {"type": "integer"},
+ "userEmail": {"type": "string"},
+ "userName": {"type": "string"},
+ "userCompany": {"type": "string", "nullable": True},
+ },
+ },
+ "login": {"type": "string"},
+ "error": {"type": "string"},
+ "token": {
+ "type": "dict",
+ "schema": {
+ "access_token": {"type": "string", "nullable": True},
+ "expiration_date": {"type": "datetime", "nullable": True},
+ },
+ "nullable": True
+ },
+ }
--
GitLab