From e23e1e37addd75a4a1350a5cc7536890f4d0e37f Mon Sep 17 00:00:00 2001
From: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date: Tue, 25 Oct 2022 08:20:51 +0200
Subject: [PATCH 01/13] sql: add user phone field migration (#69838)

---
 tests/test_sql.py | 17 +++++++++++++++++
 wcs/sql.py        | 30 ++++++++++++++++++++++++++++--
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/tests/test_sql.py b/tests/test_sql.py
index 77182f205..5c3ab81ae 100644
--- a/tests/test_sql.py
+++ b/tests/test_sql.py
@@ -558,6 +558,23 @@ def test_get_users_with_name_identifier(pub):
     assert sql.SqlUser.get_users_with_name_identifier('foo')[0].name == 'Pierre'
 
 
+def test_get_users_with_phone(pub):
+    sql.SqlUser.wipe()
+
+    user = sql.SqlUser()
+    user.name = 'Pierre'
+    user.phone = '+33123456789'
+    user.store()
+
+    user = sql.SqlUser()
+    user.name = 'Papier'
+    user.phone = '+33987654321'
+    user.store()
+
+    assert len(sql.SqlUser.get_users_with_phone('+33123456789')) == 1
+    assert sql.SqlUser.get_users_with_phone('+33123456789')[0].name == 'Pierre'
+
+
 def test_get_users_fts(pub):
     sql.SqlUser.wipe()
 
diff --git a/wcs/sql.py b/wcs/sql.py
index 32217df98..3653e73f6 100644
--- a/wcs/sql.py
+++ b/wcs/sql.py
@@ -1057,6 +1057,7 @@ def do_user_table():
                                     name varchar,
                                     ascii_name varchar,
                                     email varchar,
+                                    phone varchar,
                                     roles text[],
                                     is_active bool,
                                     is_admin bool,
@@ -1081,6 +1082,7 @@ def do_user_table():
         'id',
         'name',
         'email',
+        'phone',
         'roles',
         'is_admin',
         'anonymous',
@@ -3077,6 +3079,7 @@ class SqlUser(SqlMixin, wcs.users.User):
         ('id', 'serial'),
         ('name', 'varchar'),
         ('email', 'varchar'),
+        ('phone', 'varchar'),
         ('roles', 'varchar[]'),
         ('is_admin', 'bool'),
         ('anonymous', 'bool'),
@@ -3104,6 +3107,7 @@ class SqlUser(SqlMixin, wcs.users.User):
             'name': self.name,
             'ascii_name': self.ascii_name,
             'email': self.email,
+            'phone': self.phone,
             'roles': self.roles,
             'is_admin': self.is_admin,
             'anonymous': self.anonymous,
@@ -3200,6 +3204,7 @@ class SqlUser(SqlMixin, wcs.users.User):
             o.id,
             o.name,
             o.email,
+            o.phone,
             o.roles,
             o.is_admin,
             o.anonymous,
@@ -3210,7 +3215,7 @@ class SqlUser(SqlMixin, wcs.users.User):
             ascii_name,  # XXX what's this ? pylint: disable=unused-variable
             o.deleted_timestamp,
             o.is_active,
-        ) = (str_encode(x) for x in tuple(row[:13]))
+        ) = (str_encode(x) for x in tuple(row[:14]))
         if o.last_seen:
             o.last_seen = time.mktime(o.last_seen.timetuple())
         if o.roles:
@@ -3285,6 +3290,25 @@ class SqlUser(SqlMixin, wcs.users.User):
 
         return objects
 
+    @classmethod
+    @guard_postgres
+    def get_users_with_phone(cls, phone):
+        conn, cur = get_connection_and_cursor()
+
+        sql_statement = '''SELECT %s
+                             FROM %s
+                            WHERE deleted_timestamp IS NULL
+                              AND phone = %%(value)s''' % (
+            ', '.join([x[0] for x in cls._table_static_fields] + cls.get_data_fields()),
+            cls._table_name,
+        )
+        cur.execute(sql_statement, {'value': phone})
+        objects = cls.get_objects(cur)
+        conn.commit()
+        cur.close()
+
+        return objects
+
     @classmethod
     @guard_postgres
     def get_users_with_role(cls, role_id):
@@ -4420,7 +4444,7 @@ def get_period_total(
 # latest migration, number + description (description is not used
 # programmaticaly but will make sure git conflicts if two migrations are
 # separately added with the same number)
-SQL_LEVEL = (67, 're-migrate legacy tokens')
+SQL_LEVEL = (68, 'add user phone field')
 
 
 def migrate_global_views(conn, cur):
@@ -4599,6 +4623,8 @@ def migrate():
         # 67: re-migrate legacy tokens
         do_tokens_table()
         migrate_legacy_tokens()
+    if sql_level < 68:
+        do_user_table()
     if sql_level < 52:
         # 2: introduction of formdef_id in views
         # 5: add concerned_roles_array, is_at_endpoint and fts to views
-- 
2.37.2

