def setUp(self):

        # Use a the gateway definition for configuring the provider
        identifier = "mySmppGW"
        id = set_smsgateway(identifier, self.provider_module, description="test",
                            options=self.config)
        self.assertTrue(id > 0)
        self.provider = create_sms_instance(identifier=identifier)
        self.assertEqual(type(self.provider), SmppSMSProvider)
    def test_00_errors(self):
        # No smsgateway defined
        s = SmppSMSProvider()
        self.assertRaises(SMSError, s.submit_message, "phone", "message")

        # No host defined
        set_smsgateway("missing_host", self.provider_module,
                       options={"SMSC_PORT": "1234"})
        p = create_sms_instance(identifier="missing_host")
        self.assertRaises(SMSError, p.submit_message, "phone", "message")
        delete_smsgateway("missing_host")

        # No port defined
        set_smsgateway("missing_port", self.provider_module,
                       options={"SMSC_HOST": "1.1.1.1"})
        p = create_sms_instance(identifier="missing_port")
        self.assertRaises(SMSError, p.submit_message, "phone", "message")
        delete_smsgateway("missing_port")
    def test_02_create_modify_delete_smsgateway_configuration(self):
        identifier = "myGW"
        provider_module = "privacyidea.lib.smsprovider.HTTPSmsPrpvoder"
        id = set_smsgateway(identifier, provider_module, description="test",
                            options={"HTTP_METHOD": "POST",
                                     "URL": "example.com"})
        self.assertTrue(id > 0)

        gw = get_smsgateway(id=id)
        self.assertEqual(gw[0].description, "test")
        # update the description
        set_smsgateway(identifier, provider_module,
                       description="This is a sensible description")
        gw = get_smsgateway(id=id)
        self.assertEqual(gw[0].description, "This is a sensible description")

        # update some options
        set_smsgateway(identifier, provider_module,
                       options={"HTTP_METHOD": "POST",
                                "URL": "example.com",
                                "new key": "value"})
        gw = get_smsgateway(id=id)
        self.assertEqual(len(gw[0].option_dict), 3)
        self.assertEqual(gw[0].option_dict.get("HTTP_METHOD"), "POST")
        self.assertEqual(gw[0].option_dict.get("URL"), "example.com")
        self.assertEqual(gw[0].option_dict.get("new key"), "value")

        # delete a single option
        r = delete_smsgateway_option(id, "URL")
        gw = get_smsgateway(id=id)
        self.assertEqual(len(gw[0].option_dict), 2)
        self.assertEqual(gw[0].option_dict.get("HTTP_METHOD"), "POST")
        self.assertEqual(gw[0].option_dict.get("URL"), None)
        self.assertEqual(gw[0].option_dict.get("new key"), "value")

        # finally delete the gateway definition
        r = delete_smsgateway(identifier)
        self.assertEqual(r, id)

        # delete successful?
        gw = get_smsgateway()
        self.assertEqual(len(gw), 0)
 def test_08_smsgateway_success(self):
     responses.add(responses.POST,
                   self.url)
     identifier = "mySMS"
     provider_module = "privacyidea.lib.smsprovider.SipgateSMSProvider" \
                       ".SipgateSMSProvider"
     id = set_smsgateway(identifier, provider_module, description="test",
                         options=self.config)
     self.assertTrue(id > 0)
     sms = create_sms_instance(identifier)
     r = sms.submit_message("123456", "Hello")
     self.assertTrue(r)
Beispiel #5
0
    def test_03_sendsms(self):
        # setup realms
        self.setUp_user_realms()

        r = set_smsgateway(identifier="myGW",
                           providermodule="privacyidea.lib.smsprovider."
                           "SmtpSMSProvider.SmtpSMSProvider",
                           options={
                               "SMTPIDENTIFIER": "myserver",
                               "MAILTO": "*****@*****.**"
                           })
        self.assertTrue(r > 0)

        smtpmock.setdata(response={"*****@*****.**": (200, "OK")},
                         support_tls=False)

        g = FakeFlaskG()
        audit_object = FakeAudit()
        audit_object.audit_data["serial"] = "123456"

        g.logged_in_user = {"user": "******", "role": "admin", "realm": ""}
        g.audit_object = audit_object

        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})

        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        g.client_ip = env["REMOTE_ADDR"]
        req = Request(env)
        req.all_data = {"serial": "SomeSerial", "user": "******"}
        req.User = User("cornelius", self.realm1)
        resp = Response()
        resp.data = """{"result": {"value": true}}"""
        options = {
            "g": g,
            "request": req,
            "response": resp,
            "handler_def": {
                "options": {
                    "smsconfig": "myGW"
                }
            }
        }

        un_handler = UserNotificationEventHandler()
        res = un_handler.do("sendsms", options=options)
        self.assertTrue(res)
Beispiel #6
0
    def test_03_create_instance_by_identifier(self):
        # SMS gateway definition
        identifier = "myGW"
        provider_module = "privacyidea.lib.smsprovider.HttpSMSProvider" \
                          ".HttpSMSProvider"
        id = set_smsgateway(identifier, provider_module, description="test",
                            options={"HTTP_METHOD": "POST",
                                     "URL": "example.com"})
        self.assertTrue(id > 0)

        sms = create_sms_instance(identifier)

        self.assertEqual(sms.smsgateway.option_dict.get("URL"), "example.com")
        self.assertEqual(sms.smsgateway.option_dict.get("HTTP_METHOD"),
                         "POST")
Beispiel #7
0
 def test_02_fail(self):
     # The script returns a failing rcode
     identifier = "myScriptSMS"
     config = {"background": SCRIPT_WAIT, "script": "fail.sh"}
     provider_module = "privacyidea.lib.smsprovider.ScriptSMSProvider" \
                       ".ScriptSMSProvider"
     id = set_smsgateway(identifier,
                         provider_module,
                         description="test",
                         options=config)
     self.assertTrue(id > 0)
     sms = ScriptSMSProvider(smsgateway=get_smsgateway(identifier)[0],
                             directory=self.directory)
     self.assertRaises(SMSError, sms.submit_message, "123456", "Hello")
     delete_smsgateway(identifier)
    def test_03_create_instance_by_identifier(self):
        # SMS gateway definition
        identifier = "myGW"
        provider_module = "privacyidea.lib.smsprovider.HttpSMSProvider" \
                          ".HttpSMSProvider"
        id = set_smsgateway(identifier, provider_module, description="test",
                            options={"HTTP_METHOD": "POST",
                                     "URL": "example.com"})
        self.assertTrue(id > 0)

        sms = create_sms_instance(identifier)

        self.assertEqual(sms.smsgateway.option_dict.get("URL"), "example.com")
        self.assertEqual(sms.smsgateway.option_dict.get("HTTP_METHOD"),
                         "POST")
Beispiel #9
0
 def test_02_success(self):
     # the script runs successfully
     identifier = "myScriptSMS"
     config = {"background": SCRIPT_WAIT, "script": "success.sh"}
     provider_module = "privacyidea.lib.smsprovider.ScriptSMSProvider" \
                       ".ScriptSMSProvider"
     id = set_smsgateway(identifier,
                         provider_module,
                         description="test",
                         options=config)
     self.assertTrue(id > 0)
     sms = ScriptSMSProvider(smsgateway=get_smsgateway(identifier)[0],
                             directory=self.directory)
     r = sms.submit_message("123456", "Hello")
     self.assertTrue(r)
     delete_smsgateway(identifier)
Beispiel #10
0
 def test_08_smsgateway_success(self):
     identifier = "mySMS"
     provider_module = "privacyidea.lib.smsprovider.SmppSMSProvider" \
                       ".SmppSMSProvider"
     id = set_smsgateway(identifier,
                         provider_module,
                         description="test",
                         options=self.config)
     self.assertTrue(id > 0)
     sms = create_sms_instance(identifier)
     try:
         r = sms.submit_message("123456", "Hello")
         self.assertTrue(r)
     except:
         r = False
         self.assertFalse(r)
Beispiel #11
0
    def test_08_smsgateway_success(self):
        r = add_smtpserver("myServer", "1.2.3.4", sender="*****@*****.**")
        self.assertTrue(r > 0)
        smtpmock.setdata(response={"*****@*****.**": (200, "OK")})

        identifier = "myMail"
        provider_module = "privacyidea.lib.smsprovider.SmtpSMSProvider" \
                          ".SmtpSMSProvider"
        id = set_smsgateway(identifier, provider_module, description="test",
                            options={"SMTPIDENTIFIER": "myServer",
                                     "MAILTO": "*****@*****.**",
                                     "SUBJECT": "{phone}",
                                     "BODY": "{otp}"})
        self.assertTrue(id > 0)
        sms = create_sms_instance(identifier)
        r = sms.submit_message("123456", "Halo")
        self.assertTrue(r)
    def test_08_smsgateway_success(self):
        r = add_smtpserver("myServer", "1.2.3.4", sender="*****@*****.**")
        self.assertTrue(r > 0)
        smtpmock.setdata(response={"*****@*****.**": (200, "OK")})

        identifier = "myMail"
        provider_module = "privacyidea.lib.smsprovider.SmtpSMSProvider" \
                          ".SmtpSMSProvider"
        id = set_smsgateway(identifier, provider_module, description="test",
                            options={"SMTPIDENTIFIER": "myServer",
                                     "MAILTO": "*****@*****.**",
                                     "SUBJECT": "{phone}",
                                     "BODY": "{otp}"})
        self.assertTrue(id > 0)
        sms = create_sms_instance(identifier)
        r = sms.submit_message("123456", "Halo")
        self.assertTrue(r)
Beispiel #13
0
    def test_03_sendsms(self):
        # setup realms
        self.setUp_user_realms()

        r = set_smsgateway(identifier="myGW",
                           providermodule="privacyidea.lib.smsprovider."
                                          "SmtpSMSProvider.SmtpSMSProvider",
                           options={"SMTPIDENTIFIER": "myserver",
                                    "MAILTO": "*****@*****.**"})
        self.assertTrue(r > 0)

        smtpmock.setdata(response={"*****@*****.**": (200, "OK")},
                         support_tls=False)

        g = FakeFlaskG()
        audit_object = FakeAudit()
        audit_object.audit_data["serial"] = "123456"

        g.logged_in_user = {"user": "******",
                            "role": "admin",
                            "realm": ""}
        g.audit_object = audit_object

        builder = EnvironBuilder(method='POST',
                                 data={'serial': "OATH123456"},
                                 headers={})

        env = builder.get_environ()
        # Set the remote address so that we can filter for it
        env["REMOTE_ADDR"] = "10.0.0.1"
        g.client_ip = env["REMOTE_ADDR"]
        req = Request(env)
        req.all_data = {"serial": "SomeSerial",
                        "user": "******"}

        options = {"g": g,
                   "request": req,
                   "smsconfig": "myGW"}

        un_handler = UserNotificationEventHandler()
        res = un_handler.do("sendsms", options=options)
        self.assertTrue(res)
Beispiel #14
0
    def test_01_fail_no_script(self):
        # The script does not exist
        identifier = "myScriptSMS"
        config = {
            "background": SCRIPT_WAIT,
            "script": "sms-script-does-not-exist.sh"
        }
        provider_module = "privacyidea.lib.smsprovider.ScriptSMSProvider" \
                          ".ScriptSMSProvider"
        id = set_smsgateway(identifier,
                            provider_module,
                            description="test",
                            options=config)
        self.assertTrue(id > 0)
        sms = ScriptSMSProvider(smsgateway=get_smsgateway(identifier)[0],
                                directory=self.directory)
        self.assertRaises(SMSError, sms.submit_message, "123456", "Hello")
        delete_smsgateway(identifier)

        # We bail out, fi no smsgateway definition is given!
        sms = ScriptSMSProvider(directory=self.directory)
        self.assertRaises(SMSError, sms.submit_message, "123456", "Hello")
    def test_10_new_smsgateway(self):
        identifier = "myGW"
        provider_module = "privacyidea.lib.smsprovider.HttpSMSProvider" \
                          ".HttpSMSProvider"
        id = set_smsgateway(identifier, provider_module, description="test",
                            options={"HTTP_METHOD": "POST",
                                     "URL": "http://example.com",
                                     "RETURN_SUCCESS": "ID",
                                     "text": "{otp}",
                                     "phone": "{phone}"})
        self.assertTrue(id > 0)

        sms = create_sms_instance(identifier)

        responses.add(responses.POST,
                      "http://example.com",
                      body=self.success_body)
        # Here we need to send the SMS
        r = sms.submit_message("123456", "Hello")
        self.assertTrue(r)

        delete_smsgateway(identifier)
Beispiel #16
0
    def test_10_new_smsgateway(self):
        identifier = "myGW"
        provider_module = "privacyidea.lib.smsprovider.HttpSMSProvider" \
                          ".HttpSMSProvider"
        id = set_smsgateway(identifier, provider_module, description="test",
                            options={"HTTP_METHOD": "POST",
                                     "URL": "http://example.com",
                                     "RETURN_SUCCESS": "ID",
                                     "text": "{otp}",
                                     "phone": "{phone}"})
        self.assertTrue(id > 0)

        sms = create_sms_instance(identifier)

        responses.add(responses.POST,
                      "http://example.com",
                      body=self.success_body)
        # Here we need to send the SMS
        r = sms.submit_message("123456", "Hello")
        self.assertTrue(r)

        delete_smsgateway(identifier)
Beispiel #17
0
def set_gateway():
    """
    This creates a new SMS gateway definition or updates an existing one.

    :jsonparam name: The unique identifier of the SMS gateway definition
    :jsonparam module: The providermodule name
    :jsonparam description: An optional description of the definition
    :jsonparam options.*: Additional options for the provider module (module
        specific)
    """
    param = request.all_data
    identifier = getParam(param, "name", optional=False)
    providermodule = getParam(param, "module", optional=False)
    description = getParam(param, "description", optional=True)
    options = {}
    for k, v in param.iteritems():
        if k.startswith("option."):
            options[k[7:]] = v

    res = set_smsgateway(identifier, providermodule, description,
                         options=options)
    g.audit_object.log({"success": True,
                        "info": res})
    return send_result(res)
Beispiel #18
0
    def test_02_create_modify_delete_smsgateway_configuration(self):
        identifier = "myGW"
        provider_module = "privacyidea.lib.smsprovider.HttpSMSProvider.HttpSMSProvider"
        id = set_smsgateway(identifier,
                            provider_module,
                            description="test",
                            options={
                                "HTTP_METHOD": "POST",
                                "URL": "example.com"
                            },
                            headers={
                                "Authorization": "QWERTZ",
                                "BANANA": "will be eaten"
                            })
        self.assertTrue(id > 0)

        gw = get_smsgateway(id=id)
        self.assertEqual(gw[0].description, "test")
        # update the description
        set_smsgateway(identifier,
                       provider_module,
                       description="This is a sensible description")
        gw = get_smsgateway(id=id)
        self.assertEqual(gw[0].description, "This is a sensible description")

        # update some options
        set_smsgateway(identifier,
                       provider_module,
                       options={
                           "HTTP_METHOD": "POST",
                           "URL": "example.com",
                           "IDENTICAL_KEY": "new option"
                       },
                       headers={
                           "Authorization": "ValueChanged",
                           "IDENTICAL_KEY": "new header",
                           "URL": "URL_in_headers"
                       })
        gw = get_smsgateway(id=id)
        self.assertEqual(len(gw[0].option_dict), 3)
        self.assertEqual(gw[0].option_dict.get("HTTP_METHOD"), "POST")
        self.assertEqual(gw[0].option_dict.get("URL"), "example.com")
        self.assertEqual(gw[0].option_dict.get("IDENTICAL_KEY"), "new option")
        self.assertEqual(gw[0].header_dict.get("Authorization"),
                         "ValueChanged")
        self.assertEqual(gw[0].header_dict.get("BANANA"), None)
        self.assertEqual(gw[0].header_dict.get("IDENTICAL_KEY"), "new header")
        self.assertEqual(gw[0].header_dict.get("URL"), "URL_in_headers")

        # delete a single option
        r = delete_smsgateway_option(id, "URL")
        gw = get_smsgateway(id=id)
        self.assertEqual(len(gw[0].option_dict), 2)
        self.assertEqual(gw[0].option_dict.get("HTTP_METHOD"), "POST")
        self.assertEqual(gw[0].option_dict.get("URL"), None)
        self.assertEqual(gw[0].option_dict.get("IDENTICAL_KEY"), "new option")

        # delete a single header
        r = delete_smsgateway_header(id, "IDENTICAL_KEY")
        gw = get_smsgateway(id=id)
        self.assertEqual(gw[0].header_dict.get("IDENTICAL_KEY"), None)

        # delete a single header via generic function
        r = delete_smsgateway_key_generic(id, "URL", Type="header")
        gw = get_smsgateway(id=id)
        self.assertEqual(gw[0].header_dict.get("URL"), None)

        # finally delete the gateway definition
        r = delete_smsgateway(identifier)
        self.assertEqual(r, id)

        # delete successful?
        gw = get_smsgateway()
        self.assertEqual(len(gw), 0)
    def test_01_push_token_reorder_list(self):
        """
        * Policy push_wait
        * The user has two tokens. SPASS and Push with the same PIN.

        A /validate/check request is sent with this PIN.
        The PIN could trigger a challenge response with the Push, but since the
        token list is reordered and the Spass token already successfully authenticates,
        the push token is not evaluated anymore.
        """
        # set policy
        set_policy("push1",
                   action="{0!s}=20".format(PUSH_ACTION.WAIT),
                   scope=SCOPE.AUTH)
        set_policy("push2",
                   scope=SCOPE.ENROLL,
                   action="{0!s}={1!s},{2!s}={3!s},{4!s}={5!s}".format(
                       PUSH_ACTION.FIREBASE_CONFIG, self.firebase_config_name,
                       PUSH_ACTION.REGISTRATION_URL, REGISTRATION_URL,
                       PUSH_ACTION.TTL, TTL))
        # Create push config
        r = set_smsgateway(
            self.firebase_config_name,
            u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider',
            "myFB", FB_CONFIG_VALS)
        self.assertTrue(r > 0)

        # create push token for user
        # 1st step
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={
                                               "type": "push",
                                               "pin": "otppin",
                                               "user": "******",
                                               "realm": self.realm1,
                                               "serial": self.serial_push,
                                               "genkey": 1
                                           },
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertEqual(res.status_code, 200)
            detail = res.json.get("detail")
            serial = detail.get("serial")
            self.assertEqual(detail.get("rollout_state"), "clientwait")
            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")

        # 2nd step: as performed by the smartphone
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "enrollment_credential": enrollment_credential,
                    "serial": serial,
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            detail = res.json.get("detail")
            # still the same serial number
            self.assertEqual(serial, detail.get("serial"))
            self.assertEqual(detail.get("rollout_state"), "enrolled")
            # Now the smartphone gets a public key from the server
            augmented_pubkey = "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----\n".format(
                detail.get("public_key"))
            parsed_server_pubkey = serialization.load_pem_public_key(
                to_bytes(augmented_pubkey), default_backend())
            self.assertIsInstance(parsed_server_pubkey, RSAPublicKey)
            pubkey = detail.get("public_key")

            # Now check, what is in the token in the database
            toks = get_tokens(serial=serial)
            self.assertEqual(len(toks), 1)
            token_obj = toks[0]
            self.assertEqual(token_obj.token.rollout_state, u"enrolled")
            self.assertTrue(token_obj.token.active)
            tokeninfo = token_obj.get_tokeninfo()
            self.assertEqual(tokeninfo.get("public_key_smartphone"),
                             self.smartphone_public_key_pem_urlsafe)
            self.assertEqual(tokeninfo.get("firebase_token"), u"firebaseT")
            self.assertEqual(
                tokeninfo.get("public_key_server").strip().strip(
                    "-BEGIN END RSA PUBLIC KEY-").strip(), pubkey)
            # The token should also contain the firebase config
            self.assertEqual(tokeninfo.get(PUSH_ACTION.FIREBASE_CONFIG),
                             self.firebase_config_name)

        # create spass token for user
        init_token({
            "serial": "spass01",
            "type": "spass",
            "pin": "otppin"
        },
                   user=User("selfservice", self.realm1))

        # check, if the user has two tokens, now
        toks = get_tokens(user=User("selfservice", self.realm1))
        self.assertEqual(2, len(toks))
        self.assertEqual("push", toks[0].type)
        self.assertEqual("spass", toks[1].type)
        # authenticate with spass
        with self.app.test_request_context('/validate/check',
                                           method='POST',
                                           data={
                                               "user": "******",
                                               "realm": self.realm1,
                                               "pass": "******"
                                           }):
            res = self.app.full_dispatch_request()
            self.assertEqual(res.status_code, 200)
            data = res.json
            self.assertTrue(data.get("result").get("value"))
            # successful auth with spass
            self.assertEqual("spass", data.get("detail").get("type"))

        remove_token(self.serial_push)
        remove_token("spass01")
        delete_policy("push1")
        delete_policy("push2")
    def test_01_create_token(self):
        db_token = Token(self.serial1, tokentype="push")
        db_token.save()
        token = PushTokenClass(db_token)
        self.assertEqual(token.token.serial, self.serial1)
        self.assertEqual(token.token.tokentype, "push")
        self.assertEqual(token.type, "push")
        class_prefix = token.get_class_prefix()
        self.assertEqual(class_prefix, "PIPU")
        self.assertEqual(token.get_class_type(), "push")

        # Test to do the 2nd step, although the token is not yet in clientwait
        self.assertRaises(ParameterError, token.update, {
            "otpkey": "1234",
            "pubkey": "1234",
            "serial": self.serial1
        })

        # Run enrollment step 1
        token.update({"genkey": 1})

        # Now the token is in the state clientwait, but insufficient parameters would still fail
        self.assertRaises(ParameterError, token.update, {"otpkey": "1234"})
        self.assertRaises(ParameterError, token.update, {
            "otpkey": "1234",
            "pubkey": "1234"
        })

        # Unknown config
        self.assertRaises(ParameterError,
                          token.get_init_detail,
                          params={"firebase_config": "bla"})

        fb_config = {
            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.APP_ID: "2",
            FIREBASE_CONFIG.PROJECT_NUMBER: "3",
            FIREBASE_CONFIG.PROJECT_ID: "4"
        }

        # Wrong JSON file
        self.assertRaises(
            ConfigAdminError, set_smsgateway, "fb1",
            u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider',
            "myFB", fb_config)

        # Wrong Project number
        fb_config[FIREBASE_CONFIG.JSON_CONFIG] = FIREBASE_FILE
        self.assertRaises(
            ConfigAdminError, set_smsgateway, "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", fb_config)
        self.assertTrue(r > 0)

        detail = token.get_init_detail(
            params={"firebase_config": self.firebase_config_name})
        self.assertEqual(detail.get("serial"), self.serial1)
        self.assertEqual(detail.get("rollout_state"), "clientwait")
        enrollment_credential = detail.get("enrollment_credential")
        self.assertTrue("pushurl" in detail)
        self.assertFalse("otpkey" in detail)

        # Run enrollment step 2
        token.update({
            "enrollment_credential": enrollment_credential,
            "serial": self.serial1,
            "fbtoken": "firebasetoken",
            "pubkey": self.smartphone_public_key_pem_urlsafe
        })
        self.assertEqual(token.get_tokeninfo("firebase_token"),
                         "firebasetoken")
        self.assertEqual(token.get_tokeninfo("public_key_smartphone"),
                         self.smartphone_public_key_pem_urlsafe)
        self.assertTrue(
            token.get_tokeninfo("public_key_server").startswith(
                u"-----BEGIN RSA PUBLIC KEY-----\n"),
            token.get_tokeninfo("public_key_server"))
        parsed_server_pubkey = serialization.load_pem_public_key(
            to_bytes(token.get_tokeninfo("public_key_server")),
            default_backend())
        self.assertIsInstance(parsed_server_pubkey, RSAPublicKey)
        self.assertTrue(
            token.get_tokeninfo("private_key_server").startswith(
                u"-----BEGIN RSA PRIVATE KEY-----\n"),
            token.get_tokeninfo("private_key_server"))
        parsed_server_privkey = serialization.load_pem_private_key(
            to_bytes(token.get_tokeninfo("private_key_server")), None,
            default_backend())
        self.assertIsInstance(parsed_server_privkey, RSAPrivateKey)

        detail = token.get_init_detail()
        self.assertEqual(detail.get("rollout_state"), "enrolled")
        augmented_pubkey = "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----\n".format(
            detail.get("public_key"))
        parsed_stripped_server_pubkey = serialization.load_pem_public_key(
            to_bytes(augmented_pubkey), default_backend())
        self.assertEqual(parsed_server_pubkey.public_numbers(),
                         parsed_stripped_server_pubkey.public_numbers())
        remove_token(self.serial1)
    def test_02_api_enroll(self):
        self.authenticate()

        # Failed enrollment due to missing policy
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={
                                               "type": "push",
                                               "genkey": 1
                                           },
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertNotEqual(res.status_code, 200)
            error = res.json.get("result").get("error")
            self.assertEqual(
                error.get("message"),
                "Missing enrollment policy for push token: push_firebase_configuration"
            )
            self.assertEqual(error.get("code"), 303)

        r = set_smsgateway(
            self.firebase_config_name,
            u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider',
            "myFB", {
                FIREBASE_CONFIG.REGISTRATION_URL: "http://test/ttype/push",
                FIREBASE_CONFIG.TTL: 10,
                FIREBASE_CONFIG.API_KEY: "1",
                FIREBASE_CONFIG.APP_ID: "2",
                FIREBASE_CONFIG.PROJECT_NUMBER: "3",
                FIREBASE_CONFIG.PROJECT_ID: "test-123456",
                FIREBASE_CONFIG.JSON_CONFIG: FIREBASE_FILE
            })
        self.assertTrue(r > 0)
        set_policy("push1",
                   scope=SCOPE.ENROLL,
                   action="{0!s}={1!s}".format(PUSH_ACTION.FIREBASE_CONFIG,
                                               self.firebase_config_name))

        # 1st step
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={
                                               "type": "push",
                                               "genkey": 1
                                           },
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertEqual(res.status_code, 200)
            detail = res.json.get("detail")
            serial = detail.get("serial")
            self.assertEqual(detail.get("rollout_state"), "clientwait")
            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")

        # 2nd step. Failing with wrong serial number
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "serial": "wrongserial",
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 404, res)
            status = res.json.get("result").get("status")
            self.assertFalse(status)
            error = res.json.get("result").get("error")
            self.assertEqual(
                error.get("message"),
                "No token with this serial number in the rollout state 'clientwait'."
            )

        # 2nd step. Fails with missing enrollment credential
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "serial": serial,
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT",
                    "enrollment_credential": "WRonG"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 400, res)
            status = res.json.get("result").get("status")
            self.assertFalse(status)
            error = res.json.get("result").get("error")
            self.assertEqual(
                error.get("message"),
                "ERR905: Invalid enrollment credential. You are not authorized to finalize this token."
            )

        # 2nd step: as performed by the smartphone
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "enrollment_credential": enrollment_credential,
                    "serial": serial,
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            detail = res.json.get("detail")
            # still the same serial number
            self.assertEqual(serial, detail.get("serial"))
            self.assertEqual(detail.get("rollout_state"), "enrolled")
            # Now the smartphone gets a public key from the server
            augmented_pubkey = "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----\n".format(
                detail.get("public_key"))
            parsed_server_pubkey = serialization.load_pem_public_key(
                to_bytes(augmented_pubkey), default_backend())
            self.assertIsInstance(parsed_server_pubkey, RSAPublicKey)
            pubkey = detail.get("public_key")

            # Now check, what is in the token in the database
            toks = get_tokens(serial=serial)
            self.assertEqual(len(toks), 1)
            token_obj = toks[0]
            self.assertEqual(token_obj.token.rollout_state, u"enrolled")
            self.assertTrue(token_obj.token.active)
            tokeninfo = token_obj.get_tokeninfo()
            self.assertEqual(tokeninfo.get("public_key_smartphone"),
                             self.smartphone_public_key_pem_urlsafe)
            self.assertEqual(tokeninfo.get("firebase_token"), u"firebaseT")
            self.assertEqual(
                tokeninfo.get("public_key_server").strip().strip(
                    "-BEGIN END RSA PUBLIC KEY-").strip(), pubkey)
            # The token should also contain the firebase config
            self.assertEqual(tokeninfo.get(PUSH_ACTION.FIREBASE_CONFIG),
                             self.firebase_config_name)
    def test_02_api_enroll(self):
        self.authenticate()

        # Failed enrollment due to missing policy
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={"type": "push",
                                                 "genkey": 1},
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertNotEqual(res.status_code,  200)
            error = json.loads(res.data.decode("utf8")).get("result").get("error")
            self.assertEqual(error.get("message"), "Missing enrollment policy for push token: push_firebase_configuration")
            self.assertEqual(error.get("code"), 303)

        r = set_smsgateway(self.firebase_config_name, u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider', "myFB",
                           {FIREBASE_CONFIG.REGISTRATION_URL: "http://test/ttype/push",
                            FIREBASE_CONFIG.TTL: 10,
                            FIREBASE_CONFIG.API_KEY: "1",
                            FIREBASE_CONFIG.APP_ID: "2",
                            FIREBASE_CONFIG.PROJECT_NUMBER: "3",
                            FIREBASE_CONFIG.PROJECT_ID: "test-123456",
                            FIREBASE_CONFIG.JSON_CONFIG: FIREBASE_FILE})
        self.assertTrue(r > 0)
        set_policy("push1", scope=SCOPE.ENROLL,
                   action="{0!s}={1!s}".format(PUSH_ACTION.FIREBASE_CONFIG,
                                               self.firebase_config_name))

        # 1st step
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={"type": "push",
                                                 "genkey": 1},
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertEqual(res.status_code,  200)
            detail = json.loads(res.data.decode('utf8')).get("detail")
            serial = detail.get("serial")
            self.assertEqual(detail.get("rollout_state"), "clientwait")
            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")

        # 2nd step. Failing with wrong serial number
        with self.app.test_request_context('/ttype/push',
                                           method='POST',
                                           data={"serial": "wrongserial",
                                                 "pubkey": self.smartphone_public_key_pem_urlsafe,
                                                 "fbtoken": "firebaseT"}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 404, res)
            status = json.loads(res.data.decode('utf8')).get("result").get("status")
            self.assertFalse(status)
            error = json.loads(res.data.decode('utf8')).get("result").get("error")
            self.assertEqual(error.get("message"),
                             "No token with this serial number in the rollout state 'clientwait'.")

        # 2nd step. Fails with missing enrollment credential
        with self.app.test_request_context('/ttype/push',
                                           method='POST',
                                           data={"serial": serial,
                                                 "pubkey": self.smartphone_public_key_pem_urlsafe,
                                                 "fbtoken": "firebaseT",
                                                 "enrollment_credential": "WRonG"}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 400, res)
            status = json.loads(res.data.decode('utf8')).get("result").get("status")
            self.assertFalse(status)
            error = json.loads(res.data.decode('utf8')).get("result").get("error")
            self.assertEqual(error.get("message"),
                             "ERR905: Invalid enrollment credential. You are not authorized to finalize this token.")

        # 2nd step: as performed by the smartphone
        with self.app.test_request_context('/ttype/push',
                                           method='POST',
                                           data={"enrollment_credential": enrollment_credential,
                                                 "serial": serial,
                                                 "pubkey": self.smartphone_public_key_pem_urlsafe,
                                                 "fbtoken": "firebaseT"}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            detail = json.loads(res.data.decode('utf8')).get("detail")
            # still the same serial number
            self.assertEqual(serial, detail.get("serial"))
            self.assertEqual(detail.get("rollout_state"), "enrolled")
            # Now the smartphone gets a public key from the server
            augmented_pubkey = "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----\n".format(
                detail.get("public_key"))
            parsed_server_pubkey = serialization.load_pem_public_key(
                to_bytes(augmented_pubkey),
                default_backend())
            self.assertIsInstance(parsed_server_pubkey, RSAPublicKey)
            pubkey = detail.get("public_key")

            # Now check, what is in the token in the database
            toks = get_tokens(serial=serial)
            self.assertEqual(len(toks), 1)
            token_obj = toks[0]
            self.assertEqual(token_obj.token.rollout_state, u"enrolled")
            self.assertTrue(token_obj.token.active)
            tokeninfo = token_obj.get_tokeninfo()
            self.assertEqual(tokeninfo.get("public_key_smartphone"), self.smartphone_public_key_pem_urlsafe)
            self.assertEqual(tokeninfo.get("firebase_token"), u"firebaseT")
            self.assertEqual(tokeninfo.get("public_key_server").strip().strip("-BEGIN END RSA PUBLIC KEY-").strip(), pubkey)
            # The token should also contain the firebase config
            self.assertEqual(tokeninfo.get(PUSH_ACTION.FIREBASE_CONFIG), self.firebase_config_name)
    def test_01_create_token(self):
        db_token = Token(self.serial1, tokentype="push")
        db_token.save()
        token = PushTokenClass(db_token)
        self.assertEqual(token.token.serial, self.serial1)
        self.assertEqual(token.token.tokentype, "push")
        self.assertEqual(token.type, "push")
        class_prefix = token.get_class_prefix()
        self.assertEqual(class_prefix, "PIPU")
        self.assertEqual(token.get_class_type(), "push")

        # Test to do the 2nd step, although the token is not yet in clientwait
        self.assertRaises(ParameterError, token.update, {"otpkey": "1234", "pubkey": "1234", "serial": self.serial1})

        # Run enrollment step 1
        token.update({"genkey": 1})

        # Now the token is in the state clientwait, but insufficient parameters would still fail
        self.assertRaises(ParameterError, token.update, {"otpkey": "1234"})
        self.assertRaises(ParameterError, token.update, {"otpkey": "1234", "pubkey": "1234"})

        # Unknown config
        self.assertRaises(ParameterError, token.get_init_detail, params={"firebase_config": "bla"})

        fb_config = {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.APP_ID: "2",
                     FIREBASE_CONFIG.PROJECT_NUMBER: "3",
                     FIREBASE_CONFIG.PROJECT_ID: "4"}

        # Wrong JSON file
        self.assertRaises(ConfigAdminError, set_smsgateway,
                          "fb1", u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider', "myFB",
                          fb_config)

        # Wrong Project number
        fb_config[FIREBASE_CONFIG.JSON_CONFIG] = FIREBASE_FILE
        self.assertRaises(ConfigAdminError, set_smsgateway,
                          "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",
                           fb_config)
        self.assertTrue(r > 0)

        detail = token.get_init_detail(params={"firebase_config": self.firebase_config_name})
        self.assertEqual(detail.get("serial"), self.serial1)
        self.assertEqual(detail.get("rollout_state"), "clientwait")
        enrollment_credential = detail.get("enrollment_credential")
        self.assertTrue("pushurl" in detail)
        self.assertFalse("otpkey" in detail)

        # Run enrollment step 2
        token.update({"enrollment_credential": enrollment_credential,
                      "serial": self.serial1,
                      "fbtoken": "firebasetoken",
                      "pubkey": self.smartphone_public_key_pem_urlsafe})
        self.assertEqual(token.get_tokeninfo("firebase_token"), "firebasetoken")
        self.assertEqual(token.get_tokeninfo("public_key_smartphone"), self.smartphone_public_key_pem_urlsafe)
        self.assertTrue(token.get_tokeninfo("public_key_server").startswith(u"-----BEGIN RSA PUBLIC KEY-----\n"),
                        token.get_tokeninfo("public_key_server"))
        parsed_server_pubkey = serialization.load_pem_public_key(
            to_bytes(token.get_tokeninfo("public_key_server")),
            default_backend())
        self.assertIsInstance(parsed_server_pubkey, RSAPublicKey)
        self.assertTrue(token.get_tokeninfo("private_key_server").startswith(u"-----BEGIN RSA PRIVATE KEY-----\n"),
                        token.get_tokeninfo("private_key_server"))
        parsed_server_privkey = serialization.load_pem_private_key(
            to_bytes(token.get_tokeninfo("private_key_server")),
            None,
            default_backend())
        self.assertIsInstance(parsed_server_privkey, RSAPrivateKey)

        detail = token.get_init_detail()
        self.assertEqual(detail.get("rollout_state"), "enrolled")
        augmented_pubkey = "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----\n".format(
            detail.get("public_key"))
        parsed_stripped_server_pubkey = serialization.load_pem_public_key(
            to_bytes(augmented_pubkey),
            default_backend())
        self.assertEqual(parsed_server_pubkey.public_numbers(), parsed_stripped_server_pubkey.public_numbers())
        remove_token(self.serial1)
    def test_02_api_push_poll(self):
        r = set_smsgateway(
            self.firebase_config_name,
            u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider',
            "myFB", FB_CONFIG_VALS)
        self.assertGreater(r, 0)

        # create a new push token
        tokenobj = self._create_push_token()
        serial = tokenobj.get_serial()

        # set PIN
        tokenobj.set_pin("pushpin")
        tokenobj.add_user(User("cornelius", self.realm1))

        # We mock the ServiceAccountCredentials, since we can not directly contact the Google API
        with mock.patch(
                'privacyidea.lib.smsprovider.FirebaseProvider.service_account.Credentials'
                '.from_service_account_file') as mySA:
            # alternative: side_effect instead of return_value
            mySA.return_value = _create_credential_mock()

            # add responses, to simulate the communication to firebase
            responses.add(
                responses.POST,
                'https://fcm.googleapis.com/v1/projects/test-123456/messages:send',
                body="""{}""",
                content_type="application/json")

            # Send the first authentication request to trigger the challenge.
            # No push notification is submitted to firebase, but a challenge is created anyway
            with self.app.test_request_context('/validate/check',
                                               method='POST',
                                               data={
                                                   "user": "******",
                                                   "realm": self.realm1,
                                                   "pass": "******"
                                               }):
                res = self.app.full_dispatch_request()
                self.assertTrue(res.status_code == 400, res)
                jsonresp = res.json
                self.assertFalse(jsonresp.get("result").get("status"))
                self.assertEqual(
                    jsonresp.get("result").get("error").get("code"), 401)
                self.assertEqual(
                    jsonresp.get("result").get("error").get("message"),
                    "ERR401: Failed to submit message to Firebase service.")

        # first create a signature
        ts = datetime.utcnow().isoformat()
        sign_string = u"{serial}|{timestamp}".format(serial=serial,
                                                     timestamp=ts)
        sig = self.smartphone_private_key.sign(sign_string.encode('utf8'),
                                               padding.PKCS1v15(),
                                               hashes.SHA256())
        # now check that we receive the challenge when polling
        with self.app.test_request_context('/ttype/push',
                                           method='GET',
                                           data={
                                               "serial": serial,
                                               "timestamp": ts,
                                               "signature": b32encode(sig)
                                           }):
            res = self.app.full_dispatch_request()

            # check that the serial was set in flask g (via before_request in ttype.py)
            self.assertTrue(self.app_context.g.serial, serial)
            self.assertTrue(res.status_code == 200, res)
            self.assertTrue(res.json['result']['status'])
            chall = res.json['result']['value'][0]
            self.assertTrue(chall)

            challenge = chall["nonce"]
            # This is what the smartphone answers.
            # create the signature:
            sign_data = "{0!s}|{1!s}".format(challenge, serial)
            signature = b32encode_and_unicode(
                self.smartphone_private_key.sign(sign_data.encode("utf-8"),
                                                 padding.PKCS1v15(),
                                                 hashes.SHA256()))

            # Answer the challenge
            with self.app.test_request_context('/ttype/push',
                                               method='POST',
                                               data={
                                                   "serial": serial,
                                                   "nonce": challenge,
                                                   "signature": signature
                                               }):
                res = self.app.full_dispatch_request()
                self.assertTrue(res.status_code == 200, res)
                self.assertTrue(res.json['result']['status'])
                self.assertTrue(res.json['result']['value'])
    def test_03_unfinished_enrolled_push_token(self):
        """
        * The user has a push token where the enrollment process was not completed

        A /validate/check request is sent with this PIN.
        """
        # set policy
        set_policy("push2",
                   scope=SCOPE.ENROLL,
                   action="{0!s}={1!s},{2!s}={3!s}".format(
                       PUSH_ACTION.FIREBASE_CONFIG, self.firebase_config_name,
                       PUSH_ACTION.REGISTRATION_URL, REGISTRATION_URL))
        # Create push config
        r = set_smsgateway(
            self.firebase_config_name,
            u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider',
            "myFB", FB_CONFIG_VALS)
        self.assertTrue(r > 0)

        # create push token for user
        # 1st step
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={
                                               "type": "push",
                                               "pin": "otppin",
                                               "user": "******",
                                               "realm": self.realm1,
                                               "serial": self.serial_push,
                                               "genkey": 1
                                           },
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertEqual(res.status_code, 200)
            detail = res.json.get("detail")
            serial = detail.get("serial")
            self.assertEqual(detail.get("rollout_state"), "clientwait")
            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")

        # We skip the 2nd step of the enrollment!
        # But we activate the token on purpose!
        enable_token(self.serial_push)

        # authenticate with push
        with self.app.test_request_context('/validate/check',
                                           method='POST',
                                           data={
                                               "user": "******",
                                               "realm": self.realm1,
                                               "pass": "******"
                                           }):
            res = self.app.full_dispatch_request()
            self.assertEqual(res.status_code, 200)
            data = res.json
            self.assertFalse(data.get("result").get("value"))
            detail = data.get("detail")
            self.assertEqual(detail.get("message"),
                             "Token is not yet enrolled")

        remove_token(self.serial_push)
        delete_policy("push2")