Repository: privacyidea/privacyidea

Issue:
Allow to configure push for iOS
We need to be able to configure push for iOS.
We probalby need to add some APP ID and API KEy.


Discussion:
Thats right, the file for iOS is in .plist format which looks like this:
https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html

We need the values for the keys "GOOGLE_APP_ID" and "API_KEY".
@nilsbehlen So you are expecting the additional parameters ``apikeyios`` and appidios``?
Yes. I've updated the wiki:
https://github.com/privacyidea/privacyidea/wiki/concept%3A-PushToken#firebaseparameter-appidios

Resolving patch:
diff --git a/privacyidea/lib/smsprovider/FirebaseProvider.py b/privacyidea/lib/smsprovider/FirebaseProvider.py
--- a/privacyidea/lib/smsprovider/FirebaseProvider.py
+++ b/privacyidea/lib/smsprovider/FirebaseProvider.py
@@ -50,6 +50,8 @@ class FIREBASE_CONFIG:
     PROJECT_NUMBER = "projectnumber"
     APP_ID = "appid"
     API_KEY = "apikey"
+    APP_ID_IOS = "appidios"
+    API_KEY_IOS = "apikeyios"
 
 
 class FirebaseProvider(ISMSProvider):
@@ -119,6 +121,18 @@ def check_configuration(self):
         else:
             raise ConfigAdminError(description="Please check your configuration. Can not load JSON file.")
 
+        # We need at least
+        #         FIREBASE_CONFIG.API_KEY_IOS and FIREBASE_CONFIG.APP_ID_IOS
+        # or
+        #         FIREBASE_CONFIG.API_KEY and FIREBASE_CONFIG.APP_ID
+        android_configured = bool(self.smsgateway.option_dict.get(FIREBASE_CONFIG.APP_ID)) and \
+                             bool(self.smsgateway.option_dict.get(FIREBASE_CONFIG.API_KEY))
+        ios_configured = bool(self.smsgateway.option_dict.get(FIREBASE_CONFIG.APP_ID_IOS)) and \
+                             bool(self.smsgateway.option_dict.get(FIREBASE_CONFIG.API_KEY_IOS))
+        if not android_configured and not ios_configured:
+            raise ConfigAdminError(description="You need to at least configure either app_id and api_key or"
+                                               " app_id_ios and api_key_ios.")
+
     @classmethod
     def parameters(cls):
         """
@@ -148,14 +162,24 @@ def parameters(cls):
                               "The project number, that the client should use. Get it from your Firebase console.")
                       },
                       FIREBASE_CONFIG.APP_ID: {
-                          "required": True,
+                          "required": False,
                           "description": _(
-                              "The App ID, that the client should use. Get it from your Firebase console.")
+                              "The App ID, that the Android client should use. Get it from your Firebase console.")
                       },
                       FIREBASE_CONFIG.API_KEY: {
-                          "required": True,
+                          "required": False,
+                          "description": _(
+                              "The API Key, that the Android client should use. Get it from your Firebase console.")
+                      },
+                      FIREBASE_CONFIG.APP_ID_IOS:{
+                          "required": False,
+                          "description": _(
+                              "The App ID, that the iOS client should use. Get it from your Firebase console.")
+                      },
+                      FIREBASE_CONFIG.API_KEY_IOS: {
+                          "required": False,
                           "description": _(
-                              "The API Key, that the client should use. Get it from your Firebase console.")
+                              "The API Key, that the iOS client should use. Get it from your Firebase console.")
                       },
                       FIREBASE_CONFIG.JSON_CONFIG: {
                           "required": True,
diff --git a/privacyidea/lib/tokens/pushtoken.py b/privacyidea/lib/tokens/pushtoken.py
--- a/privacyidea/lib/tokens/pushtoken.py
+++ b/privacyidea/lib/tokens/pushtoken.py
@@ -339,7 +339,8 @@ def get_init_detail(self, params=None, user=None):
                 raise ParameterError("Unknown Firebase configuration!")
             fb_options = firebase_configs[0].option_dict
             for k in [FIREBASE_CONFIG.PROJECT_NUMBER, FIREBASE_CONFIG.PROJECT_ID,
-                      FIREBASE_CONFIG.APP_ID, FIREBASE_CONFIG.API_KEY]:
+                      FIREBASE_CONFIG.APP_ID, FIREBASE_CONFIG.API_KEY,
+                      FIREBASE_CONFIG.APP_ID_IOS, FIREBASE_CONFIG.API_KEY_IOS]:
                 extra_data[k] = fb_options.get(k)
             # this allows to upgrade our crypto
             extra_data["v"] = 1


Test patch:
diff --git a/tests/test_lib_tokens_push.py b/tests/test_lib_tokens_push.py
--- a/tests/test_lib_tokens_push.py
+++ b/tests/test_lib_tokens_push.py
@@ -105,6 +105,26 @@ def test_01_create_token(self):
                           "fb1", u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider', "myFB",
                           fb_config)
 
+        # Missing APP_ID
+        self.assertRaises(ConfigAdminError, set_smsgateway,
+                          "fb1", u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider', "myFB",
+                          {FIREBASE_CONFIG.REGISTRATION_URL: "http://test/ttype/push",
+                           FIREBASE_CONFIG.JSON_CONFIG: CLIENT_FILE,
+                           FIREBASE_CONFIG.TTL: 10,
+                           FIREBASE_CONFIG.API_KEY: "1",
+                           FIREBASE_CONFIG.PROJECT_NUMBER: "3",
+                           FIREBASE_CONFIG.PROJECT_ID: "4"})
+
+        # Missing API_KEY_IOS
+        self.assertRaises(ConfigAdminError, set_smsgateway,
+                          "fb1", u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider', "myFB",
+                          {FIREBASE_CONFIG.REGISTRATION_URL: "http://test/ttype/push",
+                           FIREBASE_CONFIG.JSON_CONFIG: CLIENT_FILE,
+                           FIREBASE_CONFIG.TTL: 10,
+                           FIREBASE_CONFIG.APP_ID_IOS: "1",
+                           FIREBASE_CONFIG.PROJECT_NUMBER: "3",
+                           FIREBASE_CONFIG.PROJECT_ID: "4"})
+
         # Everything is fine
         fb_config[FIREBASE_CONFIG.PROJECT_ID] = "test-123456"
         r = set_smsgateway("fb1", u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider', "myFB",
@@ -191,6 +211,9 @@ def test_02_api_enroll(self):
             self.assertTrue("pushurl" in detail)
             # check that the new URL contains the serial number
             self.assertTrue("&serial=PIPU" in detail.get("pushurl").get("value"))
+            self.assertTrue("appid=" in detail.get("pushurl").get("value"))
+            self.assertTrue("appidios=" in detail.get("pushurl").get("value"))
+            self.assertTrue("apikeyios=" in detail.get("pushurl").get("value"))
             self.assertFalse("otpkey" in detail)
             enrollment_credential = detail.get("enrollment_credential")