From de9cd9ca6df9a056d39e53d278c239fd4884f7f9 Mon Sep 17 00:00:00 2001
From: Michael Stambach <michael.stambach@protonmail.ch>
Date: Thu, 21 Nov 2024 18:55:34 +0000
Subject: [PATCH] remove gender

---
 amivapi/ldap.py                            |  4 ---
 amivapi/migrations/001_remove_gender.py    | 37 ++++++++++++++++++++++
 amivapi/tests/auth/test_link_methods.py    |  1 -
 amivapi/tests/test_ldap.py                 | 17 ----------
 amivapi/tests/users/test_security.py       |  8 ++---
 amivapi/tests/users/test_subscriberlist.py |  3 --
 amivapi/tests/users/test_user_cleanup.py   |  1 -
 amivapi/tests/users/test_users.py          |  1 -
 amivapi/users/model.py                     |  8 -----
 seeding_mongoinit.js                       |  3 --
 test_performance.py                        |  1 -
 11 files changed, 39 insertions(+), 45 deletions(-)
 create mode 100644 amivapi/migrations/001_remove_gender.py

diff --git a/amivapi/ldap.py b/amivapi/ldap.py
index 278bdeac..663ec87d 100644
--- a/amivapi/ldap.py
+++ b/amivapi/ldap.py
@@ -121,7 +121,6 @@ def _search(query):
         'swissEduPersonMatriculationNumber',
         'givenName',
         'sn',
-        'swissEduPersonGender',
         'ou',
         # Dept for old students in 'departmentNumber', for new in 'description'
         'departmentNumber',
@@ -165,9 +164,6 @@ def _process_data(data):
         # email can be removed when Eve switches to Cerberus 1.x, then
         # We could do this as a default value in the user model
         res['email'] = '%s@ethz.ch' % res['nethz']
-    if 'swissEduPersonGender' in data:
-        res['gender'] = \
-            u"male" if int(data['swissEduPersonGender']) == 1 else u"female"
 
     # See file docstring for explanation of `departmentNumber` field
     # In some rare cases, the departmentNumber field is either empty
diff --git a/amivapi/migrations/001_remove_gender.py b/amivapi/migrations/001_remove_gender.py
new file mode 100644
index 00000000..416d6544
--- /dev/null
+++ b/amivapi/migrations/001_remove_gender.py
@@ -0,0 +1,37 @@
+import argparse
+from pymongo import MongoClient
+
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(
+        prog='AMIVAPI Gender Remover 9000',
+        description='removes gender from all users in amivapi'
+    )
+    parser.add_argument('-H', '--host')
+    parser.add_argument('-P', '--port')
+    parser.add_argument('-u', '--user')
+    parser.add_argument('-p', '--password')
+    parser.add_argument('-s', '--suffix')
+    parser.add_argument('--undo', action='store_true')
+    args = parser.parse_args()
+
+    if args.suffix:
+        dbname = "amivapi_{}".format(args.suffix)
+    else:
+        dbname = "amivapi"
+
+    client = MongoClient(
+        host=args.host,
+        port=int(args.port),
+        username=args.user,
+        password=args.password,
+        authSource=dbname)
+    
+    db = client[dbname]
+
+    if not args.undo:
+        db.users.update_many({}, {'$unset': {'gender': ""}})
+        print("bye bye gender!!!")
+    else:
+        db.users.update_many({}, {'$set': {'gender': "female"}})
+        print("amiv frauenquote fixed!!")
diff --git a/amivapi/tests/auth/test_link_methods.py b/amivapi/tests/auth/test_link_methods.py
index 7a7111fb..1787d7b1 100644
--- a/amivapi/tests/auth/test_link_methods.py
+++ b/amivapi/tests/auth/test_link_methods.py
@@ -491,7 +491,6 @@ class LinkIntegrationTest(WebTest):
             'lastname': 'Pablone',
             'membership': 'regular',
             'email': 'pablo@pablomail.com',
-            'gender': 'male',
         }
 
         response = self.api.post("/users",
diff --git a/amivapi/tests/test_ldap.py b/amivapi/tests/test_ldap.py
index 7a437c6f..cc7133fa 100644
--- a/amivapi/tests/test_ldap.py
+++ b/amivapi/tests/test_ldap.py
@@ -84,7 +84,6 @@ class LdapTest(WebTestNoAuth):
             'swissEduPersonMatriculationNumber': '01234567',
             'givenName': ['P'],
             'sn': ['Ablo'],
-            'swissEduPersonGender': '0',
             'ou': ['VSETH Mitglied', 'other unrelated entry'],
             'some_random_field': 'abc',
         }
@@ -100,7 +99,6 @@ class LdapTest(WebTestNoAuth):
             'lastname': 'Ablo',
             'department': 'itet',
             'membership': 'regular',
-            'gender': 'female',
             'legi': '01234567',
             'send_newsletter': True,
         }
@@ -123,7 +121,6 @@ class LdapTest(WebTestNoAuth):
             ('swissEduPersonMatriculationNumber', ('legi')),
             ('givenName', ('firstname')),
             ('sn', ('lastname')),
-            ('swissEduPersonGender', ('gender')),
             ('departmentNumber', tuple(),
                 {'department': None, 'membership': 'none',
                  'send_newsletter': False}),
@@ -150,17 +147,6 @@ class LdapTest(WebTestNoAuth):
 
                 self.assertEqual(filtered, expected)
 
-    def test_process_gender(self):
-        """ Test parsing of gender field."""
-        with self.app.app_context():
-            female_data = self.fake_ldap_data(swissEduPersonGender='0')
-            female_filtered = ldap._process_data(female_data)
-            self.assertTrue(female_filtered['gender'] == 'female')
-
-            male_data = self.fake_ldap_data(swissEduPersonGender='1')
-            male_filtered = ldap._process_data(male_data)
-            self.assertTrue(male_filtered['gender'] == 'male')
-
     def test_process_department(self):
         """Test department filtering. Relies on 'departmentNUmber' field."""
         with self.app.app_context():
@@ -226,7 +212,6 @@ class LdapTest(WebTestNoAuth):
             ('firstname', 'old', 'new', True),
             ('lastname', 'old', 'new', True),
             ('department', 'mavt', 'itet', True),
-            ('gender', 'male', 'female', True),
             ('legi', '76543210', '01234567', True),
             # Membership is only upgraded
             ('membership', 'none', 'regular', True),
@@ -261,7 +246,6 @@ class LdapTest(WebTestNoAuth):
             'lastname': 'Ablo',
             'department': 'itet',
             'membership': 'none',
-            'gender': 'female',
             'legi': '01234567',
             'send_newsletter': False,
         }, status_code=201).json
@@ -280,7 +264,6 @@ class LdapTest(WebTestNoAuth):
             'swissEduPersonMatriculationNumber',
             'givenName',
             'sn',
-            'swissEduPersonGender',
             'ou',
             'departmentNumber',
             'description',
diff --git a/amivapi/tests/users/test_security.py b/amivapi/tests/users/test_security.py
index e2d5a588..e70e6f5c 100644
--- a/amivapi/tests/users/test_security.py
+++ b/amivapi/tests/users/test_security.py
@@ -82,7 +82,6 @@ class PasswordHashing(utils.WebTestNoAuth):
         post_data = {
             'firstname': 'T',
             'lastname': 'Estuser',
-            'gender': 'female',
             'membership': 'regular',
             'email': 'test@user.amiv',
             'password': "some_pw"
@@ -119,7 +118,6 @@ class UserFieldsTest(utils.WebTest):
                     'lastname': "AMIV",
                     'membership': "regular",
                     'legi': "12345678",
-                    'gender': 'female',
                     'department': 'itet',
                     'password': "userpass",
                     'email': "pabla@amiv.ch",
@@ -132,7 +130,6 @@ class UserFieldsTest(utils.WebTest):
                     'lastname': "AMIV",
                     'membership': "regular",
                     'legi': "87654321",
-                    'gender': 'male',
                     'department': 'mavt',
                     'password': "userpass2",
                     'email': "pablo@amiv.ch",
@@ -150,7 +147,7 @@ class UserFieldsTest(utils.WebTest):
     # Important: Nobody can see passwords
     BASIC_FIELDS = ['_id', '_updated', '_created', '_etag', '_links', 'nethz',
                     'firstname', 'lastname']
-    RESTRICTED_FIELDS = ['membership', 'legi', 'gender', 'department', 'email',
+    RESTRICTED_FIELDS = ['membership', 'legi', 'department', 'email',
                          'rfid', 'password_set', 'send_newsletter', 'phone']
     ALL_FIELDS = BASIC_FIELDS + RESTRICTED_FIELDS
 
@@ -260,7 +257,7 @@ class UserFieldsTest(utils.WebTest):
 
     def test_not_patchable_unless_admin(self):
         """Admin can change everything, user not."""
-        user = self.new_object('users', gender='female', department='itet',
+        user = self.new_object('users', department='itet',
                                membership="regular",
                                nethz='user', password="userpass")
         user_id = str(user['_id'])
@@ -272,7 +269,6 @@ class UserFieldsTest(utils.WebTest):
             {"legi": "10000000"},
             {"nethz": "coolkid"},
             {"department": "mavt"},
-            {"gender": "male"},
             {"membership": "none"},
         ]
 
diff --git a/amivapi/tests/users/test_subscriberlist.py b/amivapi/tests/users/test_subscriberlist.py
index c270dc9d..b75e14ea 100644
--- a/amivapi/tests/users/test_subscriberlist.py
+++ b/amivapi/tests/users/test_subscriberlist.py
@@ -30,7 +30,6 @@ class SubscriberlistTest(utils.WebTestNoAuth):
                 'lastname': "AMIV",
                 'membership': "regular",
                 'legi': "12345678",
-                'gender': 'female',
                 'department': 'itet',
                 'password': "userpass",
                 'email': "pabla@amiv.ch",
@@ -43,7 +42,6 @@ class SubscriberlistTest(utils.WebTestNoAuth):
                 'lastname': "AMIV",
                 'membership': "regular",
                 'legi': "87654321",
-                'gender': 'male',
                 'department': 'mavt',
                 'password': "userpass2",
                 'email': "pablo@amiv.ch",
@@ -56,7 +54,6 @@ class SubscriberlistTest(utils.WebTestNoAuth):
                 'lastname': "AMIV",
                 'membership': "regular",
                 'legi': "87654329",
-                'gender': 'male',
                 'department': 'itet',
                 'password': "userpass3",
                 'email': "pable@amiv.ch",
diff --git a/amivapi/tests/users/test_user_cleanup.py b/amivapi/tests/users/test_user_cleanup.py
index 7e2d1498..995f57d7 100644
--- a/amivapi/tests/users/test_user_cleanup.py
+++ b/amivapi/tests/users/test_user_cleanup.py
@@ -53,7 +53,6 @@ class UserCleanupTest(utils.WebTest):
                         'firstname': 'Pablo',
                         'lastname': "AMIV",
                         'email': f'pablo{str(idx)}@amiv.ch',
-                        'gender': 'male',
                         'membership': entry.get('membership')
                     }
                     self.api.post("/users", data=user, token=root_token)
diff --git a/amivapi/tests/users/test_users.py b/amivapi/tests/users/test_users.py
index 13033e8b..9d63beff 100644
--- a/amivapi/tests/users/test_users.py
+++ b/amivapi/tests/users/test_users.py
@@ -18,7 +18,6 @@ class UserTest(utils.WebTestNoAuth):
         post_data = {
             'firstname': 'T',
             'lastname': 'Estuser',
-            'gender': 'female',
             'membership': 'regular',
             'email': 'test@user.amiv'
         }
diff --git a/amivapi/users/model.py b/amivapi/users/model.py
index 783dafc9..4b91f1f6 100644
--- a/amivapi/users/model.py
+++ b/amivapi/users/model.py
@@ -33,7 +33,6 @@ Concretely, the following fields are synchronized:
 - `membership`
 - `legi`
 - `department`
-- `gender`
 
 <br />
 
@@ -141,13 +140,6 @@ userdomain = {
                 'default': None,
                 'example': 'itet'
             },
-            'gender': {
-                'type': 'string',
-                'allowed': ['male', 'female'],
-                'not_patchable_unless_admin': True,
-                'required': True,
-                'example': 'male',
-            },
 
             # Fields the user can modify himself
             'password': {
diff --git a/seeding_mongoinit.js b/seeding_mongoinit.js
index 47dd3fc3..813acfaa 100644
--- a/seeding_mongoinit.js
+++ b/seeding_mongoinit.js
@@ -19,7 +19,6 @@ let userId = db.users.insertOne({
     password: '$pbkdf2-sha256$5$OqfUmtNaq5UyRohxDuGckw$9H/UL5N5dA7JmUq7ohRPfmJ84OUnpRKjTgsMeuFilXM',
     email: "admin@example.com",
     membership: "regular",
-    gender: "female",
     firstname: "ad",
     lastname: "min",
     _etag: "27f987fd9dd45d491e5aea3e27730israndom",
@@ -65,7 +64,6 @@ for(let i = 0; i < 10; i++){
         email: "hans" + i.toString() + ".muster@example.com",
         membership: "regular",
         department: "itet",
-        gender: "male",
         firstname: "Hans" + i.toString(),
         lastname: "Muster",
         legi: null,
@@ -276,7 +274,6 @@ let blacklistUserId = db.users.insertOne({
     email: "black.listuser@ethz.ch",
     membership: "regular",
     departement: "itet",
-    gender: "male",
     firstname: "User",
     lastname: "Blacklist",
     legi: null,
diff --git a/test_performance.py b/test_performance.py
index 3ac60099..8b5ed8cb 100755
--- a/test_performance.py
+++ b/test_performance.py
@@ -71,7 +71,6 @@ def create_user():
     data = {
         'nethz': 'user%i' % next(counter),
         'password': 'pass',
-        'gender': random.choice(['male', 'female']),
         'firstname': 'Pablo%i' % next(counter),
         'lastname': 'AMIV%i' % next(counter),
         'membership': random.choice(['none', 'regular',
-- 
GitLab