def _enroll_token_set_pin(self): """ Enroll token and set PIN 'mypin' :return: Dictionary with token information """ token = { "key": "3132333435363738393031323334353637383930", "type": "hmac", "serial": None, "otplen": 6, "otps": deque( ["755224", "287082", "359152", "969429", "338314", "254676", "287922", "162583", "399871", "520489"] ), } # enroll token params = {"otpkey": token["key"], "type": token["type"], "otplen": token["otplen"]} response = self.make_admin_request("init", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertTrue(content["result"]["value"]) token["serial"] = content["detail"]["serial"] self.token_for_deletion.add(token["serial"]) # set PIN params = {"serial": token["serial"], "pin": "mypin"} response = self.make_admin_request("set", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertTrue(content["result"]["value"]) return token
def test_duplicate_otp(self): """ If the OTP value matches for several token autoassignment fails """ token_list = deepcopy(self.token_list[0:1]) # Enroll new token with duplicate first OTP token = { "key": "0f51c51a55a3c2736ecd0c022913d541b25734b5", "type": "hmac", "serial": None, "otplen": 6, "otps": ["755224", "657344", "672823"], } params = {"otpkey": token["key"], "type": token["type"], "otplen": token["otplen"]} response = self.make_admin_request("init", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertTrue(content["result"]["value"]) token["serial"] = content["detail"]["serial"] self.token_for_deletion.add(token["serial"]) token_list.append(token) # (user, password) pairs from myDefRealm users = [(u"molière", u"molière"), (u"shakespeare", u"shakespeare1")] self._create_autoassignment_policy("my_autoassign_policy", "mydefrealm") self._set_token_realm(token_list, "mydefrealm") # autoassign token_list[0] to users[0] -> should fail because the OTP # value is valid for several token and therefore it can't be # determined which one to use user_name, user_pwd = users[0] token = token_list[0] self._validate(user_name, user_pwd + token["otps"][0], expected="value-false") # This only happens if several unassigned token have a common OTP # value. To verify this we assign one of the token, then the other # one can be assigned with autoassigment. # Assign token_list[0] to users[0] user_name, user_pwd = users[0] token = token_list[0] params = {"user": user_name.encode("utf-8"), "serial": token["serial"]} response = self.make_admin_request("assign", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertEqual(1, content["result"]["value"]) # No PIN was set self._validate(user_name, token["otps"][0]) # autoassign token_list[1] to users[1] user_name, user_pwd = users[1] token = token_list[1] self._validate(user_name, user_pwd + token["otps"][0])
def _set_pin_in_selfservice(self, user, pwd, serial, pin): """ Log into selfservice and set PIN :param user: username or username@realm :param pwd: User password :param serial: Token serial :param pin: The PIN to be set """ params = { 'serial': serial, 'userpin': pin, } login = user.encode('utf-8') password = pwd.encode('utf-8') response = self.make_userservice_request('setpin', params, auth_user=(login, password)) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) expected = { "set userpin": 1 } self.assertDictEqual(expected, content['result']['value']) return
def _validate(self, user, pwd, expected='success', err_msg=None): """ Makes a validate/check requests and verifies the response is as 'expected' :param user: Username or username@realm :param pwd: Password (e.g. PIN+OTP) :param expected: One of 'success', 'value-false', 'status-false' or 'both-false' :param err_msg: An error message to display if assert fails :return: The content (JSON object) """ params = { 'user': user.encode('utf-8'), 'pass': pwd.encode('utf-8') } response = self.make_validate_request('check', params=params) content = TestController.get_json_body(response) if not err_msg: err_msg = "validate/check failed for %r. Response: %r" % (user, content) if expected == 'success': self.assertTrue(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'value-false': self.assertTrue(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) elif expected == 'status-false': self.assertFalse(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'both-false': self.assertFalse(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) else: self.fail("Unknown 'expected' %s" % expected) return content
def _set_token_realm(self, serial, realm): """ Set the token realm 'realm' for token defined by 'serial' """ params = {"serial": serial, "realms": realm} response = self.make_admin_request("tokenrealm", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertTrue(content["result"]["value"])
def _enroll_token_set_pin(self): """ Enroll token and set PIN 'mypin' :return: Dictionary with token information """ token = { 'key': '3132333435363738393031323334353637383930', 'type': 'hmac', 'serial': None, 'otplen': 6, 'otps': deque([ '755224', '287082', '359152', '969429', '338314', '254676', '287922', '162583', '399871', '520489' ]), } # enroll token params = { "otpkey": token['key'], "type": token['type'], "otplen": token['otplen'], } response = self.make_admin_request('init', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) token['serial'] = content['detail']['serial'] self.token_for_deletion.add(token['serial']) # set PIN params = { 'serial': token['serial'], 'pin': 'mypin', } response = self.make_admin_request('set', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) return token
def test_cant_autoassign_assigned_token(self): """ It is not possible to autoassign a token that has already been assigned. """ # Only one token required for this test token_list = deepcopy(self.token_list[0:1]) # Put all token in the same realm self._create_autoassignment_policy('my_autoassign_policy', 'mydefrealm') self._set_token_realm(token_list, 'mydefrealm') # (user, password) pairs from myDefRealm users = [ (u'molière', u'molière'), (u'shakespeare', u'shakespeare1'), ] # Assign token[0] to users[0] user_name, user_pwd = users[0] token = token_list[0] params = { 'user': user_name.encode('utf-8'), 'serial': token['serial'], } response = self.make_admin_request('assign', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(1, content['result']['value']) # Try to autoassign token[0] to users[1] -> should fail because it is # already assigned to users[0] user_name, user_pwd = users[1] token = token_list[0] self._validate( user_name, user_pwd + token['otps'][0], expected='value-false', ) # molière can authenticate... user_name, user_pwd = users[0] token = token_list[0] # No PIN was set self._validate( user_name, token['otps'][1], ) # ... and shakespeare can't user_name, user_pwd = users[1] token = token_list[0] self._validate( user_name, user_pwd + token['otps'][2], expected='value-false', )
def test_cant_autoassign_assigned_token(self): """ It is not possible to autoassign a token that has already been assigned. """ # Only one token required for this test token_list = deepcopy(self.token_list[0:1]) # Put all token in the same realm self._create_autoassignment_policy('my_autoassign_policy', 'mydefrealm') self._set_token_realm(token_list, 'mydefrealm') # (user, password) pairs from myDefRealm users = [ (u'molière', u'molière'), (u'shakespeare', u'shakespeare1'), ] # Assign token[0] to users[0] user_name, user_pwd = users[0] token = token_list[0] params = { 'user': user_name.encode('utf-8'), 'serial': token['serial'], } response = self.make_admin_request('assign', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(1, content['result']['value']) # Try to autoassign token[0] to users[1] -> should fail because it is # already assigned to users[0] user_name, user_pwd = users[1] token = token_list[0] self._validate( user_name, user_pwd + token['otps'][0], expected='value-false', ) # molière can authenticate... user_name, user_pwd = users[0] token = token_list[0] # No PIN was set self._validate( user_name, token['otps'][1], ) # ... and shakespeare can't user_name, user_pwd = users[1] token = token_list[0] self._validate( user_name, user_pwd + token['otps'][2], expected='value-false', )
def test_only_autoassign_with_no_other_token(self): """ A user can only autoassign himself a token if he has no token. """ self._create_autoassignment_policy('my_autoassign_policy', 'mydefrealm') # Only two token required for this test token_list = deepcopy(self.token_list[0:2]) # Put all token in the same realm self._set_token_realm(token_list, 'mydefrealm') # (user, password) pairs from myDefRealm users = [ (u'molière', u'molière'), ] # Assign token[0] to users[0] user_name, user_pwd = users[0] token = token_list[0] params = { 'user': user_name.encode('utf-8'), 'serial': token['serial'], } response = self.make_admin_request('assign', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(1, content['result']['value']) # Try to autoassign token[1] to users[0] -> should fail because the # user already has a token user_name, user_pwd = users[0] token = token_list[1] self._validate( user_name, user_pwd + token['otps'][0], expected='value-false', ) # molière can only authenticate with token_list[0] ... user_name, user_pwd = users[0] token = token_list[0] # No PIN was set self._validate( user_name, token['otps'][1], ) # ... not token_list[1] user_name, user_pwd = users[0] token = token_list[1] self._validate( user_name, user_pwd + token['otps'][2], expected='value-false', )
def _setup_realms(self): """ Setup 2 realms 'realm_default' and 'realm_no_default' with resolver myDefRes. """ for realm in ("realm_default", "realm_no_default"): response = self.create_realm(realm=realm, resolvers=self.resolvers["myDefRes"]) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertTrue(content["result"]["value"]) # Assert 'realm_default' is default response = self.make_system_request("getRealms", {}) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) realms = content["result"]["value"] self.assertEqual(len(realms), 2) self.assertIn("realm_default", realms) self.assertIn("default", realms["realm_default"]) self.assertTrue(realms["realm_default"]["default"])
def _set_token_realm(self, token_list, realm_name): """ Set the token realm 'realm_name' for all token in 'token_list'. """ for token in token_list: self.assertIsNotNone(token["serial"]) params = {"serial": token["serial"], "realms": realm_name} response = self.make_admin_request("tokenrealm", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertEqual(1, content["result"]["value"])
def test_only_autoassign_with_no_other_token(self): """ A user can only autoassign himself a token if he has no token. """ self._create_autoassignment_policy('my_autoassign_policy', 'mydefrealm') # Only two token required for this test token_list = deepcopy(self.token_list[0:2]) # Put all token in the same realm self._set_token_realm(token_list, 'mydefrealm') # (user, password) pairs from myDefRealm users = [ (u'molière', u'molière'), ] # Assign token[0] to users[0] user_name, user_pwd = users[0] token = token_list[0] params = { 'user': user_name.encode('utf-8'), 'serial': token['serial'], } response = self.make_admin_request('assign', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(1, content['result']['value']) # Try to autoassign token[1] to users[0] -> should fail because the # user already has a token user_name, user_pwd = users[0] token = token_list[1] self._validate( user_name, user_pwd + token['otps'][0], expected='value-false', ) # molière can only authenticate with token_list[0] ... user_name, user_pwd = users[0] token = token_list[0] # No PIN was set self._validate( user_name, token['otps'][1], ) # ... not token_list[1] user_name, user_pwd = users[0] token = token_list[1] self._validate( user_name, user_pwd + token['otps'][2], expected='value-false', )
def _delete_realms(self): """ Delete the realms set up in _setup_realms. """ for realm in ("realm_default", "realm_no_default"): params = {"realm": realm} response = self.make_system_request("delRealm", params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) expected_value = {u"delRealm": {u"result": True}} self.assertDictEqual(expected_value, content["result"]["value"])
def _set_token_realm(self, token_list, realm_name): """ Set the token realm 'realm_name' for all token in 'token_list'. """ for token in token_list: self.assertIsNotNone(token['serial']) params = {'serial': token['serial'], 'realms': realm_name} response = self.make_admin_request('tokenrealm', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(1, content['result']['value'])
def _set_token_realm(self, serial, realm): """ Set the token realm 'realm' for token defined by 'serial' """ params = { 'serial': serial, 'realms': realm, } response = self.make_admin_request('tokenrealm', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value'])
def _set_token_realm(self, serial, realm): """ Set the token realm 'realm' for token defined by 'serial' """ params = { 'serial': serial, 'realms': realm, } response = self.make_admin_request('tokenrealm', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value'])
def _set_pin_in_selfservice(self, user, pwd, serial, pin): """ Log into selfservice and set PIN :param user: username or username@realm :param pwd: User password :param serial: Token serial :param pin: The PIN to be set """ params = { 'login': user.encode('utf-8'), 'password': pwd.encode('utf-8'), 'defaultRealm': 'myDefRealm', 'realm': '', 'realmbox': False, } response = self.make_request('account', 'dologin', params=params, method='GET') err_msg = "Unexpected response %r" % response self.assertEqual(302, response.status_int, err_msg) self.assertEqual('/', response.headers['location']) self.assertRegexpMatches( response.headers['Set-Cookie'], r"^linotp_selfservice=.*", err_msg, ) session = self.app.cookies['linotp_selfservice'] session = session.strip('"') self.assertGreater(len(session), 0, err_msg) params = { 'serial': serial, 'session': session, 'userpin': pin, } cookies = { 'linotp_selfservice': '"%s"' % session, } response = self.make_request( 'userservice', 'setpin', params=params, cookies=cookies, method='GET' ) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) expected = { "set userpin": 1 } self.assertDictEqual(expected, content['result']['value']) return
def _delete_realms(self): """ Delete the realms set up in _setup_realms. """ for realm in ('realm_default', 'realm_no_default'): params = { "realm": realm, } response = self.make_system_request('delRealm', params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) expected_value = {u'delRealm': {u'result': True}} self.assertDictEqual(expected_value, content['result']['value'])
def _assign(self, serial, user): """ Assign token defined by 'serial' to 'user' :param serial: Token serial number :param user: User (e.g. username@realm) :return: None """ params = {"serial": serial, "user": user.encode("utf-8")} response = self.make_admin_request("assign", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertTrue(content["result"]["value"])
def _delete_realms(self): """ Delete the realms set up in _setup_realms. """ for realm in ('realm_default', 'realm_no_default'): params = { "realm": realm, } response = self.make_system_request('delRealm', params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) expected_value = {u'delRealm': {u'result': True}} self.assertDictEqual(expected_value, content['result']['value'])
def _set_pin(self, serial, pin): """ Set the token PIN 'pin' for the token identified by 'serial' """ params = { 'serial': serial, 'pin': pin, } response = self.make_admin_request('set', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) return
def _set_pin(self, serial, pin): """ Set the token PIN 'pin' for the token identified by 'serial' """ params = { 'serial': serial, 'pin': pin, } response = self.make_admin_request('set', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) return
def test_autoassign_mixed_token(self): """ Autoassignment with 4 HMAC and 1 Yubikey token to 5 different users 5 Token (4 HMAC + 1 Yubikey) are enrolled and put together in the same token realm. An autoenrollment policy for that realm is created. 5 different users from that realm autoassign themselves one token each by authenticating with their user-store password and an OTP value corresponding to that token. """ token_list = deepcopy(self.token_list) self._create_autoassignment_policy('my_autoassign_policy', 'mydefrealm') self._set_token_realm(token_list, 'mydefrealm') # 5 (user, password) pairs from myDefRealm users = [ (u'molière', u'molière'), (u'shakespeare', u'shakespeare1'), (u'lorca', u'lorca1'), (u'aἰσχύλος', u'Πέρσαι'), (u'beckett', u'beckett1'), ] # autoassign token to users for i in range(5): user_name, user_pwd = users[i] token = token_list[i] self._validate( user_name, user_pwd + token['otps'][0], ) for i in range(5): # Assert the token was assigned to the correct user user_name, user_pwd = users[i] token = token_list[i] response = self.make_admin_request('getTokenOwner', {'serial': token['serial']}) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(user_name, content['result']['value']['username']) # Validate the remaining OTP values for j in range(1, 3): self._validate( user_name, user_pwd + token['otps'][j], )
def _set_token_realm(self, serial, realm): """ Set the token realm 'realm' for the token identified by 'serial' """ assert serial and realm, "Both 'serial' and 'realm' required" params = { 'serial': serial, 'realms': realm, } response = self.make_admin_request('tokenrealm', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(1, content['result']['value']) return
def _setup_realms(self): """ Setup 2 realms 'realm_default' and 'realm_no_default' with resolver myDefRes. """ for realm in ('realm_default', 'realm_no_default'): response = self.create_realm( realm=realm, resolvers=self.resolvers['myDefRes'], ) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) # Assert 'realm_default' is default response = self.make_system_request('getRealms', {}) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) realms = content['result']['value'] self.assertEqual(len(realms), 2) self.assertIn('realm_default', realms) self.assertIn('default', realms['realm_default']) self.assertTrue(realms['realm_default']['default'])
def _set_token_realm(self, token_list, realm_name): """ Set the token realm 'realm_name' for all token in 'token_list'. """ for token in token_list: self.assertIsNotNone(token['serial']) params = { 'serial': token['serial'], 'realms': realm_name } response = self.make_admin_request('tokenrealm', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(1, content['result']['value'])
def _setup_realms(self): """ Setup 2 realms 'realm_default' and 'realm_no_default' with resolver myDefRes. """ for realm in ('realm_default', 'realm_no_default'): response = self.create_realm( realm=realm, resolvers=self.resolvers['myDefRes'], ) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) # Assert 'realm_default' is default response = self.make_system_request('getRealms', {}) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) realms = content['result']['value'] self.assertEqual(len(realms), 2) self.assertIn('realm_default', realms) self.assertIn('default', realms['realm_default']) self.assertTrue(realms['realm_default']['default'])
def _set_token_realm(self, serial, realm): """ Set the token realm 'realm' for the token identified by 'serial' """ assert serial and realm, "Both 'serial' and 'realm' required" params = { 'serial': serial, 'realms': realm, } response = self.make_admin_request('tokenrealm', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(1, content['result']['value']) return
def _enroll_token_set_pin(self): """ Enroll token and set PIN 'mypin' :return: Dictionary with token information """ token = { 'key': '3132333435363738393031323334353637383930', 'type': 'hmac', 'serial': None, 'otplen': 6, 'otps': deque(['755224', '287082', '359152', '969429', '338314', '254676', '287922', '162583', '399871', '520489']), } # enroll token params = { "otpkey": token['key'], "type": token['type'], "otplen": token['otplen'], } response = self.make_admin_request('init', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) token['serial'] = content['detail']['serial'] self.token_for_deletion.add(token['serial']) # set PIN params = { 'serial': token['serial'], 'pin': 'mypin', } response = self.make_admin_request('set', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) return token
def test_autoassign_mixed_token(self): """ Autoassignment with 4 HMAC and 1 Yubikey token to 5 different users 5 Token (4 HMAC + 1 Yubikey) are enrolled and put together in the same token realm. An autoenrollment policy for that realm is created. 5 different users from that realm autoassign themselves one token each by authenticating with their user-store password and an OTP value corresponding to that token. """ token_list = deepcopy(self.token_list) self._create_autoassignment_policy('my_autoassign_policy', 'mydefrealm') self._set_token_realm(token_list, 'mydefrealm') # 5 (user, password) pairs from myDefRealm users = [ (u'molière', u'molière'), (u'shakespeare', u'shakespeare1'), (u'lorca', u'lorca1'), (u'aἰσχύλος', u'Πέρσαι'), (u'beckett', u'beckett1'), ] # autoassign token to users for i in range(5): user_name, user_pwd = users[i] token = token_list[i] self._validate( user_name, user_pwd + token['otps'][0], ) for i in range(5): # Assert the token was assigned to the correct user user_name, user_pwd = users[i] token = token_list[i] response = self.make_admin_request('getTokenOwner', {'serial': token['serial']}) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(user_name, content['result']['value']['username']) # Validate the remaining OTP values for j in range(1, 3): self._validate( user_name, user_pwd + token['otps'][j], )
def _set_pin_in_selfservice(self, user, pwd, serial, pin): """ Log into selfservice and set PIN :param user: username or username@realm :param pwd: User password :param serial: Token serial :param pin: The PIN to be set """ params = { 'login': user.encode('utf-8'), 'password': pwd.encode('utf-8'), 'defaultRealm': 'myDefRealm', 'realm': '', 'realmbox': False, } response = self.make_request('account', 'dologin', params=params) err_msg = "Unexpected response %r" % response self.assertEqual(302, response.status_int, err_msg) self.assertEqual('/', response.headers['location']) self.assertRegexpMatches( response.headers['Set-Cookie'], r"^linotp_selfservice=.*", err_msg, ) session = self.app.cookies['linotp_selfservice'] session = session.strip('"') self.assertGreater(len(session), 0, err_msg) params = { 'serial': serial, 'session': session, 'userpin': pin, } cookies = { 'linotp_selfservice': '"%s"' % session, } response = self.make_request( 'userservice', 'setpin', params=params, cookies=cookies, ) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) expected = {"set userpin": 1} self.assertDictEqual(expected, content['result']['value']) return
def _enroll_token(self, token_list): """ Enroll all token in token_list. Update the list with the serial number returned by LinOTP. Adds the token to self.token_for deletion so it is cleaned up on tearDown. """ for token in token_list: params = {"otpkey": token["key"], "type": token["type"], "otplen": token["otplen"]} response = self.make_admin_request("init", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertTrue(content["result"]["value"]) token["serial"] = content["detail"]["serial"] self.token_for_deletion.add(token["serial"])
def _assign(self, serial, user): """ Assign token defined by 'serial' to 'user' :param serial: Token serial number :param user: User (e.g. username@realm) :return: None """ params = { 'serial': serial, 'user': user.encode('utf-8'), } response = self.make_admin_request('assign', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value'])
def _assign(self, serial, user): """ Assign token defined by 'serial' to 'user' :param serial: Token serial number :param user: User (e.g. username@realm) :return: None """ params = { 'serial': serial, 'user': user.encode('utf-8'), } response = self.make_admin_request('assign', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value'])
def _validate(self, user_or_serial, pwd, expected='success', err_msg=None, action='check'): """ Makes a validate/check request and verifies the response is as 'expected' :param user_or_serial: Username or username@realm or token serial number :param pwd: Password (e.g. PIN+OTP) :param expected: One of 'success', 'value-false', 'status-false' or 'both-false' :param err_msg: An error message to display if assert fails :param action: The validate action (typically check or check_s) :return: The content (JSON object) """ params = {'pass': pwd.encode('utf-8')} if action == 'check': params['user'] = user_or_serial.encode('utf-8') elif action == 'check_s': params['serial'] = user_or_serial else: self.fail("Action %s not implemented" % action) response = self.make_validate_request(action, params=params) content = TestController.get_json_body(response) if not err_msg: err_msg = "validate/%s failed for %r. Response: %r" % ( action, user_or_serial, content, ) if expected == 'success': self.assertTrue(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'value-false': self.assertTrue(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) elif expected == 'status-false': self.assertFalse(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'both-false': self.assertFalse(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) else: self.fail("Unknown 'expected' %s" % expected) return content
def _validate(self, user_or_serial, pwd, expected='success', err_msg=None, action='check'): """ Makes a validate/check request and verifies the response is as 'expected' :param user_or_serial: Username or username@realm or token serial number :param pwd: Password (e.g. PIN+OTP) :param expected: One of 'success', 'value-false', 'status-false' or 'both-false' :param err_msg: An error message to display if assert fails :param action: The validate action (typically check or check_s) :return: The content (JSON object) """ params = { 'pass': pwd.encode('utf-8') } if action == 'check': params['user'] = user_or_serial.encode('utf-8') elif action == 'check_s': params['serial'] = user_or_serial else: self.fail("Action %s not implemented" % action) response = self.make_validate_request(action, params=params) content = TestController.get_json_body(response) if not err_msg: err_msg = "validate/%s failed for %r. Response: %r" % ( action, user_or_serial, content, ) if expected == 'success': self.assertTrue(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'value-false': self.assertTrue(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) elif expected == 'status-false': self.assertFalse(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'both-false': self.assertFalse(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) else: self.fail("Unknown 'expected' %s" % expected) return content
def test_autoassign_mixed_token(self): """ Autoassignment with 4 HMAC and 1 Yubikey token to 5 different users 5 Token (4 HMAC + 1 Yubikey) are enrolled and put together in the same token realm. An autoenrollment policy for that realm is created. 5 different users from that realm autoassign themselves one token each by authenticating with their user-store password and an OTP value corresponding to that token. """ token_list = deepcopy(self.token_list) self._create_autoassignment_policy("my_autoassign_policy", "mydefrealm") self._set_token_realm(token_list, "mydefrealm") # 5 (user, password) pairs from myDefRealm users = [ (u"molière", u"molière"), (u"shakespeare", u"shakespeare1"), (u"lorca", u"lorca1"), (u"aἰσχύλος", u"Πέρσαι"), (u"beckett", u"beckett1"), ] # autoassign token to users for i in range(5): user_name, user_pwd = users[i] token = token_list[i] self._validate(user_name, user_pwd + token["otps"][0]) for i in range(5): # Assert the token was assigned to the correct user user_name, user_pwd = users[i] token = token_list[i] response = self.make_admin_request("getTokenOwner", {"serial": token["serial"]}) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertEqual(user_name, content["result"]["value"]["username"]) # Validate the remaining OTP values for j in range(1, 3): self._validate(user_name, user_pwd + token["otps"][j])
def _enroll_token(self, token_list): """ Enroll all token in token_list. Update the list with the serial number returned by LinOTP. Adds the token to self.token_for deletion so it is cleaned up on tearDown. """ for token in token_list: params = { "otpkey": token['key'], "type": token['type'], "otplen": token['otplen'], } response = self.make_admin_request('init', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) token['serial'] = content['detail']['serial'] self.token_for_deletion.add(token['serial'])
def test_lostToken_policy_hierarchy_1(self): """ The losttoken policy for specific user is prefered over the wildcard policy two policies are definded, one for specific user, one for wildcard user """ serial = '0001' policy_special = { 'name': 'losttoken_valid_hans', 'scope': 'enrollment', 'action': 'lostTokenValid=8', 'realm': '*', 'user': '******', 'time': '', 'client': '', } policy_wildcard = { 'name': 'losttoken_valid_all', 'scope': 'enrollment', 'action': 'lostTokenValid=5', 'realm': '*', 'user': '******', 'time': '', 'client': '', } token = {'serial': serial} self._create_token(serial=serial, user='******') self.create_policy(params=policy_special) self.create_policy(params=policy_wildcard) today = datetime.now() validity_special = (today + timedelta(days=8)).strftime("%d/%m/%y 23:59") losetoken = self.make_authenticated_request(controller='admin', action='losttoken', params=token) resp = TestController.get_json_body(losetoken) values = resp.get('result').get('value') self.assertEqual(values.get('end_date'), validity_special, resp)
def test_only_autoassign_with_no_other_token(self): """ A user can only autoassign himself a token if he has no token. """ self._create_autoassignment_policy("my_autoassign_policy", "mydefrealm") # Only two token required for this test token_list = deepcopy(self.token_list[0:2]) # Put all token in the same realm self._set_token_realm(token_list, "mydefrealm") # (user, password) pairs from myDefRealm users = [(u"molière", u"molière")] # Assign token[0] to users[0] user_name, user_pwd = users[0] token = token_list[0] params = {"user": user_name.encode("utf-8"), "serial": token["serial"]} response = self.make_admin_request("assign", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertEqual(1, content["result"]["value"]) # Try to autoassign token[1] to users[0] -> should fail because the # user already has a token user_name, user_pwd = users[0] token = token_list[1] self._validate(user_name, user_pwd + token["otps"][0], expected="value-false") # molière can only authenticate with token_list[0] ... user_name, user_pwd = users[0] token = token_list[0] # No PIN was set self._validate(user_name, token["otps"][1]) # ... not token_list[1] user_name, user_pwd = users[0] token = token_list[1] self._validate(user_name, user_pwd + token["otps"][2], expected="value-false")
def test_with_ignore_autoassignment_pin(self): """ Test PIN is empty when ignore_autoassignment_pin policy is set """ token_list = deepcopy(self.token_list[0:1]) self._create_autoassignment_policy('my_autoassign_policy', 'mydefrealm') self._set_token_realm(token_list, 'mydefrealm') # (user, password) pairs from myDefRealm users = [ (u'molière', u'molière'), ] self._create_ignore_autoassignment_pin_policy('mydefrealm') # autoassign token to users user_name, user_pwd = users[0] token = token_list[0] self._validate( user_name, user_pwd + token['otps'][0], ) # Assert the token was assigned to the correct user response = self.make_admin_request('getTokenOwner', {'serial': token['serial']}) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(user_name, content['result']['value']['username']) # Validate the remaining OTP values (note PIN is empty) for j in range(1, 3): self._validate( user_name, token['otps'][j], )
def test_cant_autoassign_assigned_token(self): """ It is not possible to autoassign a token that has already been assigned. """ # Only one token required for this test token_list = deepcopy(self.token_list[0:1]) # Put all token in the same realm self._create_autoassignment_policy("my_autoassign_policy", "mydefrealm") self._set_token_realm(token_list, "mydefrealm") # (user, password) pairs from myDefRealm users = [(u"molière", u"molière"), (u"shakespeare", u"shakespeare1")] # Assign token[0] to users[0] user_name, user_pwd = users[0] token = token_list[0] params = {"user": user_name.encode("utf-8"), "serial": token["serial"]} response = self.make_admin_request("assign", params=params) content = TestController.get_json_body(response) self.assertTrue(content["result"]["status"]) self.assertEqual(1, content["result"]["value"]) # Try to autoassign token[0] to users[1] -> should fail because it is # already assigned to users[0] user_name, user_pwd = users[1] token = token_list[0] self._validate(user_name, user_pwd + token["otps"][0], expected="value-false") # molière can authenticate... user_name, user_pwd = users[0] token = token_list[0] # No PIN was set self._validate(user_name, token["otps"][1]) # ... and shakespeare can't user_name, user_pwd = users[1] token = token_list[0] self._validate(user_name, user_pwd + token["otps"][2], expected="value-false")
def test_lostToken_policy_hierarchy_1(self): """ The losttoken policy for specific user is prefered over the wildcard policy two policies are definded, one for specific user, one for wildcard user """ serial = '0001' policy_special = { 'name': 'losttoken_valid_hans', 'scope': 'enrollment', 'action': 'lostTokenValid=8', 'realm': '*', 'user': '******', 'time': '', 'client': '', } policy_wildcard = { 'name': 'losttoken_valid_all', 'scope': 'enrollment', 'action': 'lostTokenValid=5', 'realm': '*', 'user': '******', 'time': '', 'client': '', } token = {'serial': serial} self._create_token(serial=serial, user='******') self.create_policy(params=policy_special) self.create_policy(params=policy_wildcard) today = datetime.now() validity_special = (today + timedelta(days=8)).strftime("%d/%m/%y 23:59") losetoken = self.make_authenticated_request( controller='admin', action='losttoken', params=token) resp = TestController.get_json_body(losetoken) values = resp.get('result').get('value') self.assertEqual(values.get('end_date'), validity_special, resp)
def _validate_base(self, params, action='check', expected='success', err_msg=None): """ Base method for /validate/<action> requests Don't call this method directly but use _validate() or _validate_check_s() instead. :param params: Request parameters :param expected: One of 'success', 'value-false', 'status-false' or 'both-false' :param err_msg: An error message to display if assert fails :return: The content (JSON object) """ response = self.make_validate_request(action, params=params) content = TestController.get_json_body(response) if not err_msg: err_msg = "validate/%s failed for %r. Response: %r" % ( action, params, content ) if expected == 'success': self.assertTrue(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'value-false': self.assertTrue(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) elif expected == 'status-false': self.assertFalse(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'both-false': self.assertFalse(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) else: self.fail("Unknown 'expected' %s" % expected) return content
def _validate_base(self, params, action='check', expected='success', err_msg=None): """ Base method for /validate/<action> requests Don't call this method directly but use _validate() or _validate_check_s() instead. :param params: Request parameters :param expected: One of 'success', 'value-false', 'status-false' or 'both-false' :param err_msg: An error message to display if assert fails :return: The content (JSON object) """ response = self.make_validate_request(action, params=params) content = TestController.get_json_body(response) if not err_msg: err_msg = "validate/%s failed for %r. Response: %r" % ( action, params, content) if expected == 'success': self.assertTrue(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'value-false': self.assertTrue(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) elif expected == 'status-false': self.assertFalse(content['result']['status'], err_msg) self.assertTrue(content['result']['value'], err_msg) elif expected == 'both-false': self.assertFalse(content['result']['status'], err_msg) self.assertFalse(content['result']['value'], err_msg) else: self.fail("Unknown 'expected' %s" % expected) return content
def _set_pin_in_selfservice(self, user, pwd, serial, pin): """ Log into selfservice and set PIN :param user: username or username@realm :param pwd: User password :param serial: Token serial :param pin: The PIN to be set """ params = { 'serial': serial, 'userpin': pin, } login = user.encode('utf-8') password = pwd.encode('utf-8') response = self.make_userservice_request('setpin', params, auth_user=(login, password)) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) expected = {"set userpin": 1} self.assertDictEqual(expected, content['result']['value']) return
def _enroll_token(self, token, user=None): """ Enroll token for 'user'. :param token: A dictionary with token information. This dictionary is augmented with 'serial' after enrolling the token. :param user: The name of the user to assign the token to. If None then the token is not assigned. """ # enroll token params = { "otpkey": token['key'], "type": token['type'], "otplen": token['otplen'], } if user: params['user'] = user.encode('utf-8') response = self.make_admin_request('init', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) token['serial'] = content['detail']['serial'] self.token_for_deletion.add(token['serial']) return
def _enroll_token(self, token, user=None): """ Enroll token for 'user'. :param token: A dictionary with token information. This dictionary is augmented with 'serial' after enrolling the token. :param user: The name of the user to assign the token to. If None then the token is not assigned. """ # enroll token params = { "otpkey": token['key'], "type": token['type'], "otplen": token['otplen'], } if user: params['user'] = user.encode('utf-8') response = self.make_admin_request('init', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) token['serial'] = content['detail']['serial'] self.token_for_deletion.add(token['serial']) return
def test_duplicate_otp(self): """ If the OTP value matches for several token autoassignment fails """ token_list = deepcopy(self.token_list[0:1]) # Enroll new token with duplicate first OTP token = { 'key': '0f51c51a55a3c2736ecd0c022913d541b25734b5', 'type': 'hmac', 'serial': None, 'otplen': 6, 'otps': ['755224', '657344', '672823'], } params = { "otpkey": token['key'], "type": token['type'], "otplen": token['otplen'], } response = self.make_admin_request('init', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertTrue(content['result']['value']) token['serial'] = content['detail']['serial'] self.token_for_deletion.add(token['serial']) token_list.append(token) # (user, password) pairs from myDefRealm users = [ (u'molière', u'molière'), (u'shakespeare', u'shakespeare1'), ] self._create_autoassignment_policy('my_autoassign_policy', 'mydefrealm') self._set_token_realm(token_list, 'mydefrealm') # autoassign token_list[0] to users[0] -> should fail because the OTP # value is valid for several token and therefore it can't be # determined which one to use user_name, user_pwd = users[0] token = token_list[0] self._validate( user_name, user_pwd + token['otps'][0], expected='value-false', ) # This only happens if several unassigned token have a common OTP # value. To verify this we assign one of the token, then the other # one can be assigned with autoassigment. # Assign token_list[0] to users[0] user_name, user_pwd = users[0] token = token_list[0] params = { 'user': user_name.encode('utf-8'), 'serial': token['serial'], } response = self.make_admin_request('assign', params=params) content = TestController.get_json_body(response) self.assertTrue(content['result']['status']) self.assertEqual(1, content['result']['value']) # No PIN was set self._validate( user_name, token['otps'][0], ) # autoassign token_list[1] to users[1] user_name, user_pwd = users[1] token = token_list[1] self._validate( user_name, user_pwd + token['otps'][0], )