def _test_create_token(self, user): pin = "test" token = init_token({"type": "tiqr", "pin": pin, "serial": "TIQR1"}, User(user, self.realm1)) self.assertEqual(token.type, "tiqr") prefix = TiqrTokenClass.get_class_prefix() self.assertEqual(prefix, "TiQR") info = TiqrTokenClass.get_class_info() self.assertEqual(info.get("type"), "tiqr") info = TiqrTokenClass.get_class_info("type") self.assertEqual(info, "tiqr") idetail = token.get_init_detail() self.assertTrue("TiQR" in idetail.get("tiqrenroll").get("description")) self.assertTrue("serial" in idetail, idetail) self.assertTrue("img" in idetail.get("tiqrenroll"), idetail) self.assertTrue("value" in idetail.get("tiqrenroll"), idetail) # Check the challenge request r = token.is_challenge_request(pin) self.assertEqual(r, True) r = token.is_challenge_request(pin + "123456") self.assertEqual(r, False) # Check create_challenge r = token.create_challenge() self.assertEqual(r[0], True) self.assertEqual(r[1], _("Please scan the QR Code")) self.assertTrue("img" in r[3], r[3]) self.assertTrue("value" in r[3], r[3])
def _test_api_endpoint(self, user, expected_netloc): pin = "tiqr" token = init_token({ "type": "tiqr", "pin": pin, "user": user, "realm": self.realm1 }) idetail = token.get_init_detail() value = idetail.get("tiqrenroll").get("value") # 'tiqrenroll://None?action=metadata&session=b81ecdf74118dcf6fa1cd41d3d4b2fec56c9107f&serial=TiQR000163CB # get the serial and the session m = re.search('&serial=(.*)$', value) serial = m.group(1) m = re.search('&session=(.*)&', value) session = m.group(1) # test meta data builder = EnvironBuilder(method='POST', data={}, 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 = { "action": "metadata", "session": session, "serial": serial } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "json") self.assertTrue("identity" in r[1], r[1]) self.assertTrue("service" in r[1], r[1]) # Test invalid action req.all_data = {"action": "unknown"} self.assertRaises(Exception, TiqrTokenClass.api_endpoint, req, g) # test enrollment with invalid session req.all_data = { "action": "enrollment", "serial": serial, "session": "123", "secret": KEY20 } self.assertRaises(ParameterError, TiqrTokenClass.api_endpoint, req, g) # test enrollment with valid session req.all_data = { "action": "enrollment", "serial": serial, "session": session, "secret": KEY20 } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "plain") self.assertEqual(r[1], "OK") # test authentication endpoint # create a challenge by issuing validate/check with user and pin session = "" challenge = "" with self.app.test_request_context('/validate/check', method='GET', query_string=urlencode({ "user": user.encode('utf-8'), "realm": self.realm1, "pass": pin })): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data).get("result") detail = json.loads(res.data).get("detail") self.assertTrue(result.get("status") is True, result) self.assertTrue(result.get("value") is False, result) transaction_id = detail.get("transaction_id") image_url = detail.get("attributes").get("value") self.assertTrue(image_url.startswith("tiqrauth")) # u'tiqrauth://[email protected] # /12335970131032896263/e0fac7bb2e3ea4219ead' # session = 12335970131032896263 # challenge = e0fac7bb2e3ea4219ead r = image_url.split("/") session = r[3] challenge = r[4] # check the URL parsed_url = urlparse(image_url) self.assertEqual(parsed_url.netloc, expected_netloc) ocrasuite = token.get_tokeninfo("ocrasuite") ocra_object = OCRA(ocrasuite, key=binascii.unhexlify(KEY20)) # Calculate Response with the challenge. response = ocra_object.get_response(challenge) encoded_user_id = u"{!s}_{!s}".format(user, self.realm1).encode('utf-8') # First, send a wrong response req.all_data = { "response": "12345", "userId": encoded_user_id, "sessionKey": session, "operation": "login" } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "plain") self.assertEqual(r[1], "INVALID_RESPONSE") # Check that the OTP status is still incorrect r = token.check_challenge_response( options={"transaction_id": transaction_id}) self.assertEqual(r, -1) # Send the correct response req.all_data = { "response": response, "userId": encoded_user_id, "sessionKey": session, "operation": "login" } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "plain") self.assertEqual(r[1], "OK") # Send the same response a second time would not work # since the Challenge is marked as answered req.all_data = { "response": response, "userId": encoded_user_id, "sessionKey": session, "operation": "login" } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "plain") self.assertEqual(r[1], "INVALID_CHALLENGE") # Finally we check the OTP status: r = token.check_challenge_response( options={"transaction_id": transaction_id}) self.assertTrue(r > 0, r) # Check the same challenge again. It will fail, since the # challenge was deleted from the database r = token.check_challenge_response( options={"transaction_id": transaction_id}) self.assertTrue(r < 0, r)
def test_02_api_endpoint(self): pin = "tiqr" token = init_token({"type": "tiqr", "pin": pin, "user": "******", "realm": self.realm1}) idetail = token.get_init_detail() value = idetail.get("tiqrenroll").get("value") # 'tiqrenroll://None?action=metadata&session=b81ecdf74118dcf6fa1cd41d3d4b2fec56c9107f&serial=TiQR000163CB # get the serial and the session m = re.search('&serial=(.*)$', value) serial = m.group(1) m = re.search('&session=(.*)&', value) session = m.group(1) # test meta data builder = EnvironBuilder(method='POST', data={}, headers={}) env = builder.get_environ() # Set the remote address so that we can filter for it env["REMOTE_ADDR"] = "10.0.0.1" req = Request(env) req.all_data = {"action": "metadata", "session": session, "serial": serial} r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "json") self.assertTrue("identity" in r[1], r[1]) self.assertTrue("service" in r[1], r[1]) # Test invalid action req.all_data = {"action": "unknown"} self.assertRaises(Exception, TiqrTokenClass.api_endpoint, req, g) # test enrollment with invalid session req.all_data = {"action": "enrollment", "serial": serial, "session": "123", "secret": KEY20} self.assertRaises(ParameterError, TiqrTokenClass.api_endpoint, req, g) # test enrollment with valid session req.all_data = {"action": "enrollment", "serial": serial, "session": session, "secret": KEY20} r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "text") self.assertEqual(r[1], "OK") # test authentication endpoint # create a challenge by issuing validate/check with user and pin session = "" challenge = "" with self.app.test_request_context('/validate/check', method='GET', query_string=urlencode({ "user": "******", "realm": self.realm1, "pass": pin})): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data).get("result") detail = json.loads(res.data).get("detail") self.assertTrue(result.get("status") is True, result) self.assertTrue(result.get("value") is False, result) transaction_id = detail.get("transaction_id") image_url = detail.get("attributes").get("value") self.assertTrue(image_url.startswith("tiqrauth")) # u'tiqrauth://[email protected] # /12335970131032896263/e0fac7bb2e3ea4219ead' # session = 12335970131032896263 # challenge = e0fac7bb2e3ea4219ead r = image_url.split("/") session = r[3] challenge = r[4] ocrasuite = token.get_tokeninfo("ocrasuite") ocra_object = OCRA(ocrasuite, key=binascii.unhexlify(KEY20)) # Calculate Response with the challenge. response = ocra_object.get_response(challenge) # First, send a wrong response req.all_data = {"response": "12345", "userId": "cornelius_%s" % self.realm1, "sessionKey": session, "operation": "login"} r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "text") self.assertEqual(r[1], "INVALID_RESPONSE") # Send the correct response req.all_data = {"response": response, "userId": "cornelius_%s" % self.realm1, "sessionKey": session, "operation": "login"} r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "text") self.assertEqual(r[1], "OK") # Send the same response a second time would not work # since the Challenge is marked as answered req.all_data = {"response": response, "userId": "cornelius_%s" % self.realm1, "sessionKey": session, "operation": "login"} r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "text") self.assertEqual(r[1], "INVALID_CHALLENGE") # Finally we check the OTP status: r = token.check_challenge_response(options={"transaction_id": transaction_id}) self.assertTrue(r > 0, r) # Check the same challenge again. It will fail, since the # challenge was deleted from the database r = token.check_challenge_response(options={"transaction_id": transaction_id}) self.assertTrue(r < 0, r)
def test_05_api_endpoint_with_multiple_tokens(self): # We test the behavior of the TiQR token with other CR tokens (ie. an email token) present smtpmock.setdata(response={"*****@*****.**": (200, 'OK')}) other_token = init_token( { "type": "email", "email": "*****@*****.**", "pin": "somepin" }, User('selfservice', self.realm1)) pin = "tiqr" token = init_token({ "type": "tiqr", "pin": pin }, User('selfservice', self.realm1)) idetail = token.get_init_detail() value = idetail.get("tiqrenroll").get("value") # 'tiqrenroll://None?action=metadata&session=b81ecdf74118dcf6fa1cd41d3d4b2fec56c9107f&serial=TiQR000163CB # get the serial and the session m = re.search('&serial=(.*)$', value) serial = m.group(1) m = re.search('&session=(.*)&', value) session = m.group(1) # test meta data builder = EnvironBuilder(method='POST', data={}, 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 = { "action": "metadata", "session": session, "serial": serial } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "json") self.assertTrue("identity" in r[1], r[1]) self.assertTrue("service" in r[1], r[1]) # Test invalid action req.all_data = {"action": "unknown"} self.assertRaises(Exception, TiqrTokenClass.api_endpoint, req, g) # test enrollment with invalid session req.all_data = { "action": "enrollment", "serial": serial, "session": "123", "secret": KEY20 } self.assertRaises(ParameterError, TiqrTokenClass.api_endpoint, req, g) # test enrollment with valid session req.all_data = { "action": "enrollment", "serial": serial, "session": session, "secret": KEY20 } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "plain") self.assertEqual(r[1], "OK") # test authentication endpoint # create a challenge by issuing validate/triggerchallenge with self.app.test_request_context('/validate/triggerchallenge', method='POST', data={ "user": "******", "realm": self.realm1 }, headers={"Authorization": self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = res.json.get("result") detail = res.json.get("detail") self.assertTrue(result.get("status") is True, result) transaction_id = detail.get("transaction_id") # we've got two challenges with the same transaction ID self.assertEqual(len(detail["multi_challenge"]), 2) email_challenge = [ challenge for challenge in detail["multi_challenge"] if challenge["type"] == "email" ][0] self.assertEqual(email_challenge["transaction_id"], transaction_id) tiqr_challenge = [ challenge for challenge in detail["multi_challenge"] if challenge["type"] == "tiqr" ][0] self.assertEqual(tiqr_challenge["transaction_id"], transaction_id) image_url = tiqr_challenge.get("attributes").get("value") self.assertTrue(image_url.startswith("tiqrauth")) # u'tiqrauth://[email protected] # /12335970131032896263/e0fac7bb2e3ea4219ead' # session = 12335970131032896263 # challenge = e0fac7bb2e3ea4219ead r = image_url.split("/") session = r[3] challenge = r[4] # check the URL parsed_url = urlparse(image_url) self.assertEqual(parsed_url.netloc, "*****@*****.**") ocrasuite = token.get_tokeninfo("ocrasuite") ocra_object = OCRA(ocrasuite, key=binascii.unhexlify(KEY20)) # Calculate Response with the challenge. response = ocra_object.get_response(challenge) encoded_user_id = u"{!s}_{!s}".format("selfservice", self.realm1).encode('utf-8') # First, send a wrong response req.all_data = { "response": "12345", "userId": encoded_user_id, "sessionKey": session, "operation": "login" } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "plain") self.assertRegexpMatches(r[1], r"INVALID_RESPONSE:[0-9]+") # Check that the OTP status is still incorrect r = token.check_challenge_response( options={"transaction_id": transaction_id}) self.assertEqual(r, -1) # Send the correct response req.all_data = { "response": response, "userId": encoded_user_id, "sessionKey": session, "operation": "login" } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "plain") self.assertEqual(r[1], "OK") # Send the same response a second time would not work # since the Challenge is marked as answered req.all_data = { "response": response, "userId": encoded_user_id, "sessionKey": session, "operation": "login" } r = TiqrTokenClass.api_endpoint(req, g) self.assertEqual(r[0], "plain") self.assertEqual(r[1], "INVALID_CHALLENGE") # Finally we check the OTP status: r = token.check_challenge_response( options={"transaction_id": transaction_id}) self.assertTrue(r > 0, r) # Check the same challenge again. It will fail, since the # challenge was deleted from the database r = token.check_challenge_response( options={"transaction_id": transaction_id}) self.assertTrue(r < 0, r)