From b9cb25a3259a8e2ed118b36a8c7c5b0a708f4d28 Mon Sep 17 00:00:00 2001
From: Benjami <benjami94@gmail.com>
Date: Fri, 16 Jun 2023 10:18:09 +0200
Subject: [PATCH] Added reset password endpoint and method

---
 .../models/auth_oauth_provider.py             | 19 +++++++++++++++++++
 energy_communities/models/res_users.py        | 17 +++++++++++++++++
 energy_communities/views/auth_oauth_views.xml |  4 ++++
 3 files changed, 40 insertions(+)

diff --git a/energy_communities/models/auth_oauth_provider.py b/energy_communities/models/auth_oauth_provider.py
index cdba53cfb..cb710aa70 100644
--- a/energy_communities/models/auth_oauth_provider.py
+++ b/energy_communities/models/auth_oauth_provider.py
@@ -8,6 +8,7 @@ URL_AUTH = "{root_endpoint}realms/{realm_name}/protocol/openid-connect/auth"
 URL_VALIDATION = "{root_endpoint}realms/{realm_name}/protocol/openid-connect/userinfo"
 URL_TOKEN = "{root_endpoint}realms/{realm_name}/protocol/openid-connect/token"
 URL_JWKS = "{root_endpoint}realms/{realm_name}/protocol/openid-connect/certs"
+URL_RESET_PASSWORD = "{root_endpoint}admin/realms/{realm_name}/users/{kc_uid}/execute-actions-email?redirect_uri={odoo_url}&client_id={cliend_id}"
 
 
 class OAuthProvider(models.Model):
@@ -22,6 +23,8 @@ class OAuthProvider(models.Model):
     admin_user_endpoint = fields.Char(string='User admin URL', required=True)
     root_endpoint = fields.Char(string='Root URL', required=True, default='http://keycloak-ccee.local:8080/auth/')
     realm_name = fields.Char(string='Realm name', required=True, default='0')
+    reset_password_endpoint = fields.Char(string='Reset password URL', required=True)
+    redirect_admin_url = fields.Char(string='Redirect Link after update password', required=True)
 
     def validate_admin_provider(self):
         if not self.client_secret:
@@ -31,6 +34,7 @@ class OAuthProvider(models.Model):
 
     @api.onchange('root_endpoint')
     def _onchange_root_endpoint(self):
+        # TODO: Duplicated code? 🤔
         if self.is_keycloak_provider and self.root_endpoint and self.realm_name:
             self.admin_user_endpoint = URL_ADMIN_USERS.format(**{'root_endpoint': self.root_endpoint,
                                                                  'realm_name': self.realm_name})
@@ -42,9 +46,17 @@ class OAuthProvider(models.Model):
                                                       'realm_name': self.realm_name})
             self.jwks_uri = URL_JWKS.format(**{'root_endpoint': self.root_endpoint,
                                                'realm_name': self.realm_name})
+            self.reset_password_endpoint = URL_RESET_PASSWORD.format(
+                root_endpoint=self.root_endpoint,
+                realm_name=self.realm_name,
+                kc_uid='{kc_uid}',
+                odoo_url=self.redirect_admin_url,
+                cliend_id=self.client_id,
+            )
 
     @api.onchange('realm_name')
     def _onchange_realm_name(self):
+        # TODO: Duplicated code? 🤔
         if self.is_keycloak_provider and self.root_endpoint and self.realm_name:
             self.admin_user_endpoint = URL_ADMIN_USERS.format(**{'root_endpoint': self.root_endpoint,
                                                                  'realm_name': self.realm_name})
@@ -56,6 +68,13 @@ class OAuthProvider(models.Model):
                                                       'realm_name': self.realm_name})
             self.jwks_uri = URL_JWKS.format(**{'root_endpoint': self.root_endpoint,
                                                'realm_name': self.realm_name})
+            self.reset_password_endpoint = URL_RESET_PASSWORD.format(
+                root_endpoint=self.root_endpoint,
+                realm_name=self.realm_name,
+                kc_uid='{kc_uid}',
+                odoo_url=self.redirect_admin_url,
+                cliend_id=self.client_id,
+            )
 
     def get_auth_link(self):
         self.ensure_one()
diff --git a/energy_communities/models/res_users.py b/energy_communities/models/res_users.py
index 0ee9529c4..86ff5027a 100644
--- a/energy_communities/models/res_users.py
+++ b/energy_communities/models/res_users.py
@@ -193,3 +193,20 @@ class ResUsers(models.Model):
             for company in role_line.allowed_company_ids:
                 communities.append(company.id)
         return communities
+
+    def send_reset_password_mail(self):
+        provider_id = self.env.ref('energy_communities.keycloak_admin_provider')
+        provider_id.validate_admin_provider()
+        headers = {
+            'Authorization': 'Bearer %s' % self._get_admin_token(provider_id)
+        }
+        headers['Content-Type'] = "application/json"
+
+        endpoint = provider_id.reset_password_endpoint.format(
+            kc_uid = self.oauth_uid
+        )
+        response = requests.put(endpoint, headers=headers, data='["UPDATE_PASSWORD"]')
+        if response.status_code != 204:
+            raise exceptions.UserError(
+                _('Something went wrong. Mail can not be sended. More details: {}').format(response.json())
+            )
diff --git a/energy_communities/views/auth_oauth_views.xml b/energy_communities/views/auth_oauth_views.xml
index 5a010371f..14d04a26b 100644
--- a/energy_communities/views/auth_oauth_views.xml
+++ b/energy_communities/views/auth_oauth_views.xml
@@ -16,6 +16,10 @@
                 ('is_keycloak_provider', '=', False)]}"/>
                 <field name="admin_user_endpoint" attrs="{'invisible': ['|', ('is_admin_provider','=',False),
                 ('is_keycloak_provider', '=', False)]}"/>
+                <field name="redirect_admin_url" attrs="{'invisible': ['|', ('is_admin_provider','=',False),
+                ('is_keycloak_provider', '=', False)]}"/>
+                <field name="reset_password_endpoint" attrs="{'invisible': ['|', ('is_admin_provider','=',False),
+                ('is_keycloak_provider', '=', False)]}"/>
             </xpath>
         </field>
     </record>
-- 
GitLab