def test_10_delete_realm(self): delete_realm(self.realm1) delete_realm("realm2") delete_resolver(self.resolvername1) delete_resolver(self.resolvername2) realms = get_realms() self.assertTrue(len(realms) == 0, realms)
def test_02_failing_resolver(self): ldap3mock.setLDAPDirectory([]) # define, that we want to get an exception ldap3mock.set_exception() # Create an LDAP Realm as default realm params = { 'LDAPURI': 'ldap://localhost', 'LDAPBASE': 'o=test', 'BINDDN': 'cn=manager,ou=example,o=test', 'BINDPW': 'ldaptest', 'LOGINNAMEATTRIBUTE': 'cn', 'LDAPSEARCHFILTER': '(cn=*)', 'USERINFO': '{ "username": "******",' '"phone" : "telephoneNumber", ' '"mobile" : "mobile"' ', "email" : "mail", ' '"surname" : "sn", ' '"givenname" : "givenName" }', 'UIDTYPE': 'DN', "resolver": "ldap1", "type": "ldapresolver" } save_resolver(params) set_realm("ldap1", ["ldap1"]) set_default_realm("ldap1") # Try to login as internal admin with a failing LDAP resolver with mock.patch("logging.Logger.warning") as mock_log: with self.app.test_request_context('/auth', method='POST', data={ "username": "******", "password": "******" }): res = self.app.full_dispatch_request() self.assertEqual(200, res.status_code, res) result = res.json.get("result") self.assertTrue(result.get("status"), result) self.assertIn('token', result.get("value"), result) # role should be 'admin' self.assertEqual('admin', result['value']['role'], result) mock_log.assert_called_once_with( "Problem resolving user testadmin in realm ldap1: LDAP request failed." ) delete_realm("ldap1") delete_resolver("ldap1") ldap3mock.set_exception(False)
def test_12_multiple_resolvers(self): # one realm, two SQL resolvers parameters_a = self.sql_parameters.copy() # first resolver only contains users with phone numbers parameters_a['Where'] = 'phone LIKE %' parameters_a['resolver'] = 'reso_a' rid_a = save_resolver(parameters_a) self.assertTrue(rid_a > 0, rid_a) # second resolver contains all users parameters_b = self.sql_parameters.copy() parameters_b['resolver'] = 'reso_b' rid_b = save_resolver(parameters_b) self.assertTrue(rid_b > 0, rid_b) # First ask reso_a, then reso_b (added, failed) = set_realm(self.sql_realm, ['reso_a', 'reso_b'], { 'reso_a': 1, 'reso_b': 2 }) self.assertEqual(len(failed), 0) self.assertEqual(len(added), 2) # Now, query the user and populate the cache self.assertEqual(UserCache.query.count(), 0) user1 = User('wordpressuser', self.sql_realm) self.assertEqual(user1.uid, '6') # Assert it was found in reso_b (as it does not have a phone number)! self.assertEqual(user1.resolver, 'reso_b') self.assertEqual( UserCache.query.filter(UserCache.username == 'wordpressuser', UserCache.user_id == 6).one().resolver, 'reso_b') # Add a phone number. We do not use the User API to do that to simulate that the change is performed # out of privacyIDEA's control. Using `update_user_info` would invalidate the cache, which would be unrealistic. info = user1.info new_info = info.copy() new_info['phone'] = '123456' get_resolver_object('reso_a').update_user(user1.uid, new_info) # Ensure that the user's association with reso_b is still cached. self.assertEqual( UserCache.query.filter(UserCache.username == 'wordpressuser', UserCache.user_id == 6).one().resolver, 'reso_b') # Now, it should be located in reso_a! user2 = User('wordpressuser', self.sql_realm) self.assertEqual(user2.uid, '6') self.assertEqual(user2.resolver, 'reso_a') # ... but the cache still contains entries for both! resolver_query = UserCache.query.filter( UserCache.username == 'wordpressuser', UserCache.user_id == 6).order_by(UserCache.timestamp.desc()) cached_resolvers = [entry.resolver for entry in resolver_query.all()] self.assertEqual(cached_resolvers, ['reso_a', 'reso_b']) # Remove the phone number. get_resolver_object('reso_a').update_user(user1.uid, {'phone': None}) delete_realm(self.sql_realm) delete_resolver('reso_a') delete_resolver('reso_b')
def test_12_multiple_resolvers(self): # one realm, two SQL resolvers parameters_a = self.sql_parameters.copy() # first resolver only contains users with phone numbers parameters_a['Where'] = 'phone LIKE %' parameters_a['resolver'] = 'reso_a' rid_a = save_resolver(parameters_a) self.assertTrue(rid_a > 0, rid_a) # second resolver contains all users parameters_b = self.sql_parameters.copy() parameters_b['resolver'] = 'reso_b' rid_b = save_resolver(parameters_b) self.assertTrue(rid_b > 0, rid_b) # First ask reso_a, then reso_b (added, failed) = set_realm(self.sql_realm, ['reso_a', 'reso_b'], { 'reso_a': 1, 'reso_b': 2 }) self.assertEqual(len(failed), 0) self.assertEqual(len(added), 2) # Now, query the user and populate the cache self.assertEqual(UserCache.query.count(), 0) user1 = User('wordpressuser', self.sql_realm) self.assertEqual(user1.uid, 6) # Assert it was found in reso_b (as it does not have a phone number)! self.assertEqual(user1.resolver, 'reso_b') self.assertEqual(UserCache.query.filter(UserCache.username == 'wordpressuser', UserCache.user_id == 6).one().resolver, 'reso_b') # Add a phone number. We do not use the User API to do that to simulate that the change is performed # out of privacyIDEA's control. Using `update_user_info` would invalidate the cache, which would be unrealistic. info = user1.info new_info = info.copy() new_info['phone'] = '123456' get_resolver_object('reso_a').update_user(user1.uid, new_info) # Ensure that the user's association with reso_b is still cached. self.assertEqual(UserCache.query.filter(UserCache.username == 'wordpressuser', UserCache.user_id == 6).one().resolver, 'reso_b') # Now, it should be located in reso_a! user2 = User('wordpressuser', self.sql_realm) self.assertEqual(user2.uid, 6) self.assertEqual(user2.resolver, 'reso_a') # ... but the cache still contains entries for both! resolver_query = UserCache.query.filter(UserCache.username == 'wordpressuser', UserCache.user_id == 6).order_by(UserCache.timestamp.desc()) cached_resolvers = [entry.resolver for entry in resolver_query.all()] self.assertEqual(cached_resolvers, ['reso_a', 'reso_b']) # Remove the phone number. get_resolver_object('reso_a').update_user(user1.uid, {'phone': None}) delete_realm(self.sql_realm) delete_resolver('reso_a') delete_resolver('reso_b')
def test_37_is_orphaned(self): resolver = "orphreso" realm = "orphrealm" rid = save_resolver({"resolver": resolver, "type": "passwdresolver", "fileName": PWFILE}) self.assertTrue(rid > 0, rid) (added, failed) = set_realm(realm, [resolver]) self.assertTrue(len(failed) == 0) self.assertTrue(len(added) == 1) # Assign token to user "cornelius" "realm1", "resolver1" "uid=1000 db_token = Token("orphaned", tokentype="spass", userid=1000, resolver=resolver, realm=realm) db_token.save() token_obj = TokenClass(db_token) orph = token_obj.is_orphaned() self.assertFalse(orph) # clean up token token_obj.delete_token() # Assign a token to a user in a resolver. user_id does not exist db_token = Token("orphaned", tokentype="spass", userid=872812, resolver=resolver, realm=realm) db_token.save() token_obj = TokenClass(db_token) orph = token_obj.is_orphaned() self.assertTrue(orph) # clean up token token_obj.delete_token() # A token, which a resolver name, that does not exist anymore db_token = Token("orphaned", tokentype="spass", userid=1000, resolver=resolver, realm=realm) db_token.save() # delete the realm delete_realm(realm) # token is orphaned token_obj = TokenClass(db_token) orph = token_obj.is_orphaned() self.assertTrue(orph) # delete the resolver delete_resolver(resolver) # token is orphaned token_obj = TokenClass(db_token) orph = token_obj.is_orphaned() self.assertTrue(orph) # clean up token token_obj.delete_token()
def test_11_otppin_with_resolvers(self): # This tests, if the otppin policy differentiates between users in # the same realm but in different resolvers. r = save_resolver({"resolver": "reso001", "type": "passwdresolver", "fileName": "tests/testdata/passwords"}) # user "cornelius" is in resolver reso001 self.assertTrue(r > 0) r = save_resolver({"resolver": "reso002", "type": "passwdresolver", "fileName": "tests/testdata/pw-2nd-resolver"}) # user "userresolver2" is in resolver reso002 self.assertTrue(r > 0) (added, failed) = set_realm("myrealm", ["reso001", "reso002"]) self.assertEqual(len(added), 2) self.assertEqual(len(failed), 0) my_user_1 = User("cornelius", realm="myrealm") my_user_2 = User("userresolver2", realm="myrealm") # We set a policy only for resolver reso002 set_policy(name="pol1", scope=SCOPE.AUTH, realm="myrealm", resolver="reso002", action="{0!s}={1!s}".format(ACTION.OTPPIN, ACTIONVALUE.NONE)) g = FakeFlaskG() P = PolicyClass() g.policy_object = P g.audit_object = FakeAudit() options = {"g": g} # user in reso001 fails with empty PIN, since the policy does not # match for him r = auth_otppin(self.fake_check_otp, None, "", options=options, user=my_user_1) self.assertFalse(r) # user in reso002 succeeds with empty PIN, since policy pol1 matches # for him r = auth_otppin(self.fake_check_otp, None, "", options=options, user=my_user_2) self.assertTrue(r) # user in reso002 fails with any PIN, since policy pol1 matches # for him r = auth_otppin(self.fake_check_otp, None, "anyPIN", options=options, user=my_user_2) self.assertFalse(r) delete_policy("pol1") delete_realm("myrealm") delete_resolver("reso001") delete_resolver("reso002")
def test_18_user_with_several_phones(self): ldap3mock.setLDAPDirectory(LDAPDirectory_small) params = ({ 'LDAPURI': 'ldap://localhost', 'LDAPBASE': 'o=test', 'BINDDN': 'cn=manager,ou=example,o=test', 'BINDPW': 'ldaptest', 'LOGINNAMEATTRIBUTE': 'cn', 'LDAPSEARCHFILTER': '(|(cn=*))', # we use this weird search filter to get a unique resolver ID 'USERINFO': '{ "username": "******",' '"phone" : "telephoneNumber", ' '"mobile" : "mobile"' ', "email" : "mail", ' '"surname" : "sn", ' '"givenname" : "givenName" }', 'UIDTYPE': 'objectGUID', 'NOREFERRALS': True, 'CACHE_TIMEOUT': 0 }) params["resolver"] = "ldapresolver" params["type"] = "ldapresolver" rid = save_resolver(params) self.assertTrue(rid > 0) (added, failed) = set_realm("ldap", ["ldapresolver"]) self.assertEqual(len(added), 1) self.assertEqual(len(failed), 0) u = User("salesman", "ldap") # get the complete list r = u.get_user_phone("mobile") self.assertEqual(r, ["1234", "3456"]) # get the first entry r = u.get_user_phone("mobile", index=0) self.assertEqual(r, "1234") # Index out of range r = u.get_user_phone("mobile", index=2) self.assertEqual(r, "") delete_realm("ldap") delete_resolver("ldapresolver")
def test_10_delete_resolver(self): # get the list of the resolvers reso_list = get_resolver_list() self.assertTrue(self.resolvername1 in reso_list, reso_list) self.assertTrue(self.resolvername2 in reso_list, reso_list) # delete the resolvers delete_resolver(self.resolvername1) delete_resolver(self.resolvername2) # check list empty reso_list = get_resolver_list() self.assertTrue(self.resolvername1 not in reso_list, reso_list) self.assertTrue(self.resolvername2 not in reso_list, reso_list) self.assertTrue(len(reso_list) == 0, reso_list)
def test_17b_ui_rights_users_in_different_resolvers(self): # Create a realm with two resolvers rid = save_resolver({ "resolver": "passwd", "type": "passwdresolver", "fileName": FILE_PASSWD }) self.assertTrue(rid > 0, rid) rid = save_resolver({ "resolver": "passwords", "type": "passwdresolver", "fileName": FILE_PASSWORDS }) self.assertTrue(rid > 0, rid) # create user realm (added, failed) = set_realm("realm4", ["passwd", "passwords"]) self.assertTrue(len(failed) == 0) self.assertTrue(len(added) == 2) # A user may do something else... set_policy(name="userpol41", scope=SCOPE.USER, action="enable", realm="realm4", resolver="passwd") set_policy(name="userpol42", scope=SCOPE.USER, action="remove", realm="realm4", resolver="passwords") P = PolicyClass() # The two users are in different resolvers and get different rights rights = P.ui_get_rights(SCOPE.USER, "realm4", "postfix") self.assertEqual(set(rights), {"enable", "disable"}) rights = P.ui_get_rights(SCOPE.USER, "realm4", "usernotoken") self.assertEqual(set(rights), {"disable", "remove"}) delete_policy("userpol41") delete_policy("userpol42") delete_realm("realm4") delete_resolver("passwords") delete_resolver("passwd")
def test_18_user_with_several_phones(self): ldap3mock.setLDAPDirectory(LDAPDirectory_small) params = ({'LDAPURI': 'ldap://localhost', 'LDAPBASE': 'o=test', 'BINDDN': 'cn=manager,ou=example,o=test', 'BINDPW': 'ldaptest', 'LOGINNAMEATTRIBUTE': 'cn', 'LDAPSEARCHFILTER': '(|(cn=*))', # we use this weird search filter to get a unique resolver ID 'USERINFO': '{ "username": "******",' '"phone" : "telephoneNumber", ' '"mobile" : "mobile"' ', "email" : "mail", ' '"surname" : "sn", ' '"givenname" : "givenName" }', 'UIDTYPE': 'objectGUID', 'NOREFERRALS': True, 'CACHE_TIMEOUT': 0 }) params["resolver"] = "ldapresolver" params["type"] = "ldapresolver" rid = save_resolver(params) self.assertTrue(rid > 0) (added, failed) = set_realm("ldap", ["ldapresolver"]) self.assertEqual(len(added), 1) self.assertEqual(len(failed), 0) u = User("salesman", "ldap") # get the complete list r = u.get_user_phone("mobile") self.assertEqual(r, ["1234", "3456"]) # get the first entry r = u.get_user_phone("mobile", index=0) self.assertEqual(r, "1234") # Index out of range r = u.get_user_phone("mobile", index=2) self.assertEqual(r, "") delete_realm("ldap") delete_resolver("ldapresolver")
def test_08_no_ldap_password(self): params = {'LDAPURI': 'ldap://localhost', 'LDAPBASE': 'o=test', 'BINDDN': 'cn=manager,ou=example,o=test', 'BINDPW': 'ldaptest', 'LOGINNAMEATTRIBUTE': 'cn', 'LDAPSEARCHFILTER': '(cn=*)', 'USERINFO': '{ "username": "******", "phone": "telephoneNumber", ' '"mobile" : "mobile", "email": "mail", ' '"surname" : "sn", "givenname": "givenName" }', 'UIDTYPE': 'DN', 'type': 'ldapresolver', 'resolver': 'testL'} r = save_resolver(params) self.assertTrue(r) with self.app.test_request_context('/resolver/testL', method='GET', headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')).get("result") self.assertTrue(result["status"] is True, result) data = result["value"]["testL"]["data"] self.assertEqual(data.get("BINDPW"), CENSORED) with self.app.test_request_context('/resolver/', method='GET', headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data.decode('utf8')).get("result") self.assertTrue(result["status"] is True, result) data = result["value"]["testL"]["data"] self.assertEqual(data.get("BINDPW"), CENSORED) r = delete_resolver(params.get("resolver")) self.assertTrue(r)
def _delete_realm(self): delete_realm(self.realm1) delete_resolver(self.resolvername1)
def _delete_ldap_realm(self): delete_realm(self.ldap_realm) delete_resolver(self.ldap_resolver)
def test_15_unassign_missing_user(self): """ Unassign a token from a user that does not exist anymore. There is a token which is owned by a user, who was deleted fromt he userstore. An Event Handler, to notifiy the user via email on unassign is defined. This testcase must NOT throw an exception. Well, the user can not be notified anymore, since the email also does not exist in the userstore anymore. """ # Create our realm and resolver parameters = { 'resolver': "notify_resolver", "type": "sqlresolver", 'Driver': 'sqlite', 'Server': '/tests/testdata/', 'Database': "testuser.sqlite", 'Table': 'users', 'Encoding': 'utf8', 'Editable': True, 'Map': '{ "username": "******", \ "userid" : "id", \ "email" : "email", \ "surname" : "name", \ "givenname" : "givenname", \ "password" : "password", \ "phone": "phone", \ "mobile": "mobile"}' } r = save_resolver(parameters) self.assertTrue(r) success, fail = set_realm("notify_realm", ["notify_resolver"]) self.assertEqual(len(success), 1) self.assertEqual(len(fail), 0) # Create a user ## First delete it, in case the user exist User("notify_user", "notify_realm").delete() uid = create_user("notify_resolver", {"username": "******"}) self.assertTrue(uid) user = User("notify_user", "notify_realm") self.assertEqual(user.login, "notify_user") self.assertEqual(user.realm, "notify_realm") # Create a token for this user r = init_token({"type": "spass", "serial": "SPNOTIFY"}, user=user) self.assertTrue(r) # create notification handler eid = set_event("token_unassign", "UserNotification", "sendmail") self.assertTrue(eid) # delete the user r = user.delete() self.assertTrue(r) # unassign the token from the non-existing user # call the notification handler implicitly with self.app.test_request_context('/token/unassign', method='POST', data={"serial": "SPNOTIFY"}, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data).get("result") self.assertTrue(result.get("value") is True, result) # Cleanup delete_event(eid) delete_realm("notify_realm") delete_resolver("notify_resolver") remove_token("SPNOTIFY")
def _delete_sql_realm(self): delete_realm(self.sql_realm) delete_resolver(self.sql_resolver)
def test_12_authcache(self): password = "******" username = "******" realm = "myrealm" resolver = "reso001" pw_hash = binascii.hexlify(hashlib.sha256(password).digest()) r = save_resolver({"resolver": "reso001", "type": "passwdresolver", "fileName": "tests/testdata/passwords"}) (added, failed) = set_realm("myrealm", ["reso001"]) def fake_check_user_pass(user, passw, options=None): return True, {"message": "Fake Authentication"} set_policy(name="pol1", scope=SCOPE.AUTH, realm=realm, resolver=resolver, action="{0!s}={1!s}".format(ACTION.AUTH_CACHE, "4h/5m")) g = FakeFlaskG() P = PolicyClass() g.policy_object = P g.audit_object = FakeAudit() options = {"g": g} # This successfully authenticates against the authcache # We have an authentication, that is within the policy timeout AuthCache(username, realm, resolver, pw_hash, first_auth=datetime.datetime.utcnow() - timedelta(hours=3), last_auth=datetime.datetime.utcnow() - timedelta(minutes=1)).save() r = auth_cache(fake_check_user_pass, User("cornelius", "myrealm"), password, options=options) self.assertTrue(r[0]) self.assertEqual(r[1].get("message"), "Authenticated by AuthCache." ) # We have an authentication, that is not read from the authcache, # since the authcache first_auth is too old. delete_from_cache(username, realm, resolver, pw_hash) AuthCache(username, realm, resolver, pw_hash, first_auth=datetime.datetime.utcnow() - timedelta(hours=5), last_auth=datetime.datetime.utcnow() - timedelta( minutes=1)).save() r = auth_cache(fake_check_user_pass, User("cornelius", "myrealm"), password, options=options) self.assertTrue(r[0]) self.assertEqual(r[1].get("message"), "Fake Authentication") # We have an authentication, that is not read from authcache, since # the last_auth is too old = 10 minutes. delete_from_cache(username, realm, resolver, pw_hash) AuthCache(username, realm, resolver, pw_hash, first_auth=datetime.datetime.utcnow() - timedelta(hours=1), last_auth=datetime.datetime.utcnow() - timedelta( minutes=10)).save() r = auth_cache(fake_check_user_pass, User("cornelius", "myrealm"), password, options=options) self.assertTrue(r[0]) self.assertEqual(r[1].get("message"), "Fake Authentication") # We have a policy, with no special last_auth delete_policy("pol1") set_policy(name="pol1", scope=SCOPE.AUTH, realm=realm, resolver=resolver, action="{0!s}={1!s}".format(ACTION.AUTH_CACHE, "4h")) g = FakeFlaskG() P = PolicyClass() g.policy_object = P g.audit_object = FakeAudit() options = {"g": g} delete_from_cache(username, realm, resolver, pw_hash) AuthCache(username, realm, resolver, pw_hash, first_auth=datetime.datetime.utcnow() - timedelta(hours=2), last_auth=datetime.datetime.utcnow() - timedelta( hours=1)).save() r = auth_cache(fake_check_user_pass, User("cornelius", "myrealm"), password, options=options) self.assertTrue(r[0]) self.assertEqual(r[1].get("message"), "Authenticated by AuthCache.") # Clean up delete_policy("pol1") delete_realm("myrealm") delete_resolver("reso001")
def test_21_check_all_resolver(self): # check_all_resolver allows to find a policy for a secondary user # resolver. # We create one realm "realm1" with the resolvers # reso1 (prio 1) # reso2 (prio 2) # reso3 (prio 3) # A user user@realm1 will be identified as user.reso1@realm1. # But we will also match policies for reso2. # no realm and resolver r = get_realms() self.assertEqual(r, {}) r = get_resolver_list() self.assertEqual(r, {}) # create user realm for reso in ["reso1", "resoX", "resoA"]: rid = save_resolver({ "resolver": reso, "type": "passwdresolver", "fileName": PWFILE }) self.assertTrue(rid > 0, rid) # create a realm with reso1 being the resolver with the highest priority (added, failed) = set_realm("realm1", ["reso1", "resoX", "resoA"], priority={ "reso1": 1, "resoX": 2, "resoA": 3 }) self.assertTrue(len(failed) == 0) self.assertTrue(len(added) == 3) user = User(login="******", realm="realm1") # The user, that is created, is cornelius.reso1@realm1 user_str = "{0!s}".format(user) self.assertEqual(user_str, "<cornelius.reso1@realm1>") # But the user "cornelius" is also contained in other resolves in # this realm r = user.get_ordererd_resolvers() self.assertEqual(r, ["reso1", "resoX", "resoA"]) self.assertFalse(user.is_empty()) self.assertTrue(User().is_empty()) # define a policy with the wrong resolver p = set_policy(name="checkAll", scope=SCOPE.AUTHZ, realm="realm1", resolver="resoX", action="{0}=totp".format(ACTION.TOKENTYPE)) self.assertTrue(p > 0) p = set_policy(name="catchAll", scope=SCOPE.AUTHZ, realm="realm1", action="{0}=totp".format(ACTION.TOKENTYPE)) self.assertTrue(p > 0) P = PolicyClass() pols = P.get_policies(scope=SCOPE.AUTHZ, realm=user.realm, resolver=user.resolver, user=user.login) self.assertEqual(len(pols), 1) # Now we change the policy, so that it uses check_all_resolver, i.e. p = set_policy(name="checkAll", scope=SCOPE.AUTHZ, realm="realm1", resolver="resoX", check_all_resolvers=True, action="{0}=totp".format(ACTION.TOKENTYPE)) self.assertTrue(p > 0) P = PolicyClass() pols = P.get_policies(scope=SCOPE.AUTHZ, realm=user.realm, resolver=user.resolver, user=user.login) self.assertEqual(len(pols), 2) # delete policy delete_policy("checkAll") delete_policy("catchAll") # delete resolvers and realm delete_realm("realm1") for reso in ["reso1", "resoX", "resoA"]: rid = delete_resolver(reso) self.assertTrue(rid > 0, rid)
def test_12_passwdresolver(self): # Create a resolver with an empty filename # will use the filename /etc/passwd rid = save_resolver({ "resolver": self.resolvername1, "type": "passwdresolver", "fileName": "", "type.fileName": "string", "desc.fileName": "The name of the file" }) self.assertTrue(rid > 0, rid) y = get_resolver_object(self.resolvername1) y.loadFile() delete_resolver(self.resolvername1) # Load a file with an empty line rid = save_resolver({ "resolver": self.resolvername1, "type": "passwdresolver", "fileName": PWFILE, "type.fileName": "string", "desc.fileName": "The name of the file" }) self.assertTrue(rid > 0, rid) y = get_resolver_object(self.resolvername1) y.loadFile() ulist = y.getUserList({"username": "******"}) self.assertTrue(len(ulist) > 1, ulist) self.assertTrue(y.checkPass("1000", "test")) self.assertFalse(y.checkPass("1000", "wrong password")) self.assertRaises(NotImplementedError, y.checkPass, "1001", "secret") self.assertFalse(y.checkPass("1002", "no pw at all")) self.assertTrue( y.getUsername("1000") == "cornelius", y.getUsername("1000")) self.assertTrue( y.getUserId(u"cornelius") == "1000", y.getUserId("cornelius")) self.assertTrue(y.getUserId("user does not exist") == "") sF = y.getSearchFields({"username": "******"}) self.assertTrue(sF.get("username") == "text", sF) # unknown search fields. We get an empty userlist r = y.getUserList({"blabla": "something"}) self.assertTrue(r == [], r) # list exactly one user r = y.getUserList({"userid": "=1000"}) self.assertTrue(len(r) == 1, r) r = y.getUserList({"userid": "<1001"}) self.assertTrue(len(r) == 1, r) r = y.getUserList({"userid": ">1000"}) self.assertTrue(len(r) > 1, r) r = y.getUserList({"userid": "between 1000, 1001"}) self.assertTrue(len(r) == 2, r) r = y.getUserList({"userid": "between 1001, 1000"}) self.assertTrue(len(r) == 2, r) r = y.getUserList({"userid": "<=1000"}) self.assertTrue(len(r) == 1, "%s" % r) r = y.getUserList({"userid": ">=1000"}) self.assertTrue(len(r) > 1, r) r = y.getUserList({"description": "field1"}) self.assertTrue(len(r) == 0, r) r = y.getUserList({"email": "field1"}) self.assertTrue(len(r) == 0, r) rid = y.getResolverId() self.assertTrue(rid == PWFILE, rid) rtype = y.getResolverType() self.assertTrue(rtype == "passwdresolver", rtype) rdesc = y.getResolverDescriptor() self.assertTrue("config" in rdesc.get("passwdresolver"), rdesc) self.assertTrue("clazz" in rdesc.get("passwdresolver"), rdesc) # internal stringMatch function self.assertTrue(y._stringMatch(u"Hallo", "*lo")) self.assertTrue(y._stringMatch("Hallo", u"Hal*")) self.assertFalse(y._stringMatch("Duda", "Hal*")) self.assertTrue(y._stringMatch("HalloDuda", "*Du*")) self.assertTrue(y._stringMatch("Duda", "Duda"))
def test_12_passwdresolver(self): # Create a resolver with an empty filename # will use the filename /etc/passwd rid = save_resolver( { "resolver": self.resolvername1, "type": "passwdresolver", "fileName": "", "type.fileName": "string", "desc.fileName": "The name of the file", } ) self.assertTrue(rid > 0, rid) y = get_resolver_object(self.resolvername1) y.loadFile() delete_resolver(self.resolvername1) # Load a file with an empty line rid = save_resolver( { "resolver": self.resolvername1, "type": "passwdresolver", "fileName": PWFILE, "type.fileName": "string", "desc.fileName": "The name of the file", } ) self.assertTrue(rid > 0, rid) y = get_resolver_object(self.resolvername1) y.loadFile() ulist = y.getUserList({"username": "******"}) self.assertTrue(len(ulist) > 1, ulist) self.assertTrue(y.checkPass("1000", "test")) self.assertFalse(y.checkPass("1000", "wrong password")) self.assertRaises(NotImplementedError, y.checkPass, "1001", "secret") self.assertFalse(y.checkPass("1002", "no pw at all")) self.assertTrue(y.getUsername("1000") == "cornelius", y.getUsername("1000")) self.assertTrue(y.getUserId(u"cornelius") == "1000", y.getUserId("cornelius")) self.assertTrue(y.getUserId("user does not exist") == "") sF = y.getSearchFields({"username": "******"}) self.assertTrue(sF.get("username") == "text", sF) # unknown search fields. We get an empty userlist r = y.getUserList({"blabla": "something"}) self.assertTrue(r == [], r) # list exactly one user r = y.getUserList({"userid": "=1000"}) self.assertTrue(len(r) == 1, r) r = y.getUserList({"userid": "<1001"}) self.assertTrue(len(r) == 1, r) r = y.getUserList({"userid": ">1000"}) self.assertTrue(len(r) > 1, r) r = y.getUserList({"userid": "between 1000, 1001"}) self.assertTrue(len(r) == 2, r) r = y.getUserList({"userid": "between 1001, 1000"}) self.assertTrue(len(r) == 2, r) r = y.getUserList({"userid": "<=1000"}) self.assertTrue(len(r) == 1, "%s" % r) r = y.getUserList({"userid": ">=1000"}) self.assertTrue(len(r) > 1, r) r = y.getUserList({"description": "field1"}) self.assertTrue(len(r) == 0, r) r = y.getUserList({"email": "field1"}) self.assertTrue(len(r) == 0, r) rid = y.getResolverId() self.assertTrue(rid == PWFILE, rid) rtype = y.getResolverType() self.assertTrue(rtype == "passwdresolver", rtype) rdesc = y.getResolverDescriptor() self.assertTrue("config" in rdesc.get("passwdresolver"), rdesc) self.assertTrue("clazz" in rdesc.get("passwdresolver"), rdesc) # internal stringMatch function self.assertTrue(y._stringMatch(u"Hallo", "*lo")) self.assertTrue(y._stringMatch("Hallo", u"Hal*")) self.assertFalse(y._stringMatch("Duda", "Hal*")) self.assertTrue(y._stringMatch("HalloDuda", "*Du*")) self.assertTrue(y._stringMatch("Duda", "Duda"))
def test_12_authcache(self): password = "******" username = "******" realm = "myrealm" resolver = "reso001" r = save_resolver({"resolver": "reso001", "type": "passwdresolver", "fileName": "tests/testdata/passwords"}) (added, failed) = set_realm("myrealm", ["reso001"]) def fake_check_user_pass(user, passw, options=None): return True, {"message": "Fake Authentication"} set_policy(name="pol1", scope=SCOPE.AUTH, realm=realm, resolver=resolver, action="{0!s}={1!s}".format(ACTION.AUTH_CACHE, "4h/5m")) g = FakeFlaskG() P = PolicyClass() g.policy_object = P g.audit_object = FakeAudit() options = {"g": g} # This successfully authenticates against the authcache # We have an authentication, that is within the policy timeout AuthCache(username, realm, resolver, _hash_password(password), first_auth=datetime.datetime.utcnow() - timedelta(hours=3), last_auth=datetime.datetime.utcnow() - timedelta(minutes=1)).save() r = auth_cache(fake_check_user_pass, User("cornelius", "myrealm"), password, options=options) self.assertTrue(r[0]) self.assertEqual(r[1].get("message"), "Authenticated by AuthCache." ) # We have an authentication, that is not read from the authcache, # since the authcache first_auth is too old. delete_from_cache(username, realm, resolver, password) AuthCache(username, realm, resolver, _hash_password(password), first_auth=datetime.datetime.utcnow() - timedelta(hours=5), last_auth=datetime.datetime.utcnow() - timedelta( minutes=1)).save() r = auth_cache(fake_check_user_pass, User("cornelius", "myrealm"), password, options=options) self.assertTrue(r[0]) self.assertEqual(r[1].get("message"), "Fake Authentication") # We have an authentication, that is not read from authcache, since # the last_auth is too old = 10 minutes. delete_from_cache(username, realm, resolver, password) AuthCache(username, realm, resolver, _hash_password(password), first_auth=datetime.datetime.utcnow() - timedelta(hours=1), last_auth=datetime.datetime.utcnow() - timedelta( minutes=10)).save() r = auth_cache(fake_check_user_pass, User("cornelius", "myrealm"), password, options=options) self.assertTrue(r[0]) self.assertEqual(r[1].get("message"), "Fake Authentication") # We have a policy, with no special last_auth delete_policy("pol1") set_policy(name="pol1", scope=SCOPE.AUTH, realm=realm, resolver=resolver, action="{0!s}={1!s}".format(ACTION.AUTH_CACHE, "4h")) g = FakeFlaskG() P = PolicyClass() g.policy_object = P g.audit_object = FakeAudit() options = {"g": g} delete_from_cache(username, realm, resolver, password) AuthCache(username, realm, resolver, _hash_password(password), first_auth=datetime.datetime.utcnow() - timedelta(hours=2), last_auth=datetime.datetime.utcnow() - timedelta( hours=1)).save() r = auth_cache(fake_check_user_pass, User("cornelius", "myrealm"), password, options=options) self.assertTrue(r[0]) self.assertEqual(r[1].get("message"), "Authenticated by AuthCache.") # Clean up delete_policy("pol1") delete_realm("myrealm") delete_resolver("reso001")
def test_21_check_all_resolver(self): # check_all_resolver allows to find a policy for a secondary user # resolver. # We create one realm "realm1" with the resolvers # reso1 (prio 1) # reso2 (prio 2) # reso3 (prio 3) # A user user@realm1 will be identified as user.reso1@realm1. # But we will also match policies for reso2. # no realm and resolver r = get_realms() self.assertEqual(r, {}) r = get_resolver_list() self.assertEqual(r, {}) # create user realm for reso in ["reso1", "resoX", "resoA"]: rid = save_resolver({"resolver": reso, "type": "passwdresolver", "fileName": PWFILE}) self.assertTrue(rid > 0, rid) # create a realm with reso1 being the resolver with the highest priority (added, failed) = set_realm("realm1", ["reso1", "resoX", "resoA"], priority={"reso1": 1, "resoX": 2, "resoA": 3}) self.assertTrue(len(failed) == 0) self.assertTrue(len(added) == 3) user = User(login="******", realm="realm1") # The user, that is created, is cornelius.reso1@realm1 user_str = "{0!s}".format(user) self.assertEqual(user_str, "<cornelius.reso1@realm1>") # But the user "cornelius" is also contained in other resolves in # this realm r = user.get_ordererd_resolvers() self.assertEqual(r, ["reso1", "resoX", "resoA"]) self.assertFalse(user.is_empty()) self.assertTrue(User().is_empty()) # define a policy with the wrong resolver p = set_policy(name="checkAll", scope=SCOPE.AUTHZ, realm="realm1", resolver="resoX", action="{0}=totp".format(ACTION.TOKENTYPE)) self.assertTrue(p > 0) p = set_policy(name="catchAll", scope=SCOPE.AUTHZ, realm="realm1", action="{0}=totp".format(ACTION.TOKENTYPE)) self.assertTrue(p > 0) P = PolicyClass() pols = P.get_policies(scope=SCOPE.AUTHZ, realm=user.realm, resolver=user.resolver, user=user.login) self.assertEqual(len(pols), 1) # Now we change the policy, so that it uses check_all_resolver, i.e. p = set_policy(name="checkAll", scope=SCOPE.AUTHZ, realm="realm1", resolver="resoX", check_all_resolvers=True, action="{0}=totp".format(ACTION.TOKENTYPE)) self.assertTrue(p > 0) P = PolicyClass() pols = P.get_policies(scope=SCOPE.AUTHZ, realm=user.realm, resolver=user.resolver, user=user.login) self.assertEqual(len(pols), 2) # delete policy delete_policy("checkAll") delete_policy("catchAll") # delete resolvers and realm delete_realm("realm1") for reso in ["reso1", "resoX", "resoA"]: rid = delete_resolver(reso) self.assertTrue(rid > 0, rid)