def setUp_user_realm2(self): # create user realm rid = save_resolver({"resolver": self.resolvername1, "type": "passwdresolver", "fileName": PWFILE}) self.assertTrue(rid > 0, rid) (added, failed) = set_realm(self.realm2, [self.resolvername1]) self.assertTrue(len(failed) == 0) self.assertTrue(len(added) == 1) user = User(login="******", realm=self.realm2, resolver=self.resolvername1) user_str = "{0!s}".format(user) self.assertTrue(user_str == "<root.resolver1@realm2>", user_str) self.assertFalse(user.is_empty()) self.assertTrue(User().is_empty()) user_repr = "{0!r}".format(user) expected = "User(login='******', realm='realm2', resolver='resolver1')" self.assertTrue(user_repr == expected, user_repr)
def test_14_create_delete_user(self): realm = "sqlrealm" resolver = "SQL1" parameters = self.parameters parameters["resolver"] = resolver parameters["type"] = "sqlresolver" rid = save_resolver(parameters) self.assertTrue(rid > 0, rid) (added, failed) = set_realm(realm, [resolver]) self.assertEqual(len(failed), 0) self.assertEqual(len(added), 1) # Create the user uid = create_user(resolver, {"username": "******", "givenname": "achmed"}, password="******") self.assertTrue(uid > 6) user = User("achmed3", realm=realm) r = user.check_password("secret") # delete user r = user.delete() self.assertTrue(r)
def test_13_update_user(self): realm = "sqlrealm" resolver = "SQL1" parameters = self.parameters parameters["resolver"] = resolver parameters["type"] = "sqlresolver" rid = save_resolver(parameters) self.assertTrue(rid > 0, rid) (added, failed) = set_realm(realm, [resolver]) self.assertEqual(len(failed), 0) self.assertEqual(len(added), 1) user = User(login="******", realm=realm) uinfo = user.info self.assertEqual(uinfo.get("givenname", ""), "") user.update_user_info({"givenname": "wordy", "username": "******"}) uinfo = user.info self.assertEqual(uinfo.get("givenname"), "wordy") self.assertEqual(user.login, "WordpressUser") user.update_user_info({"givenname": "", "username": "******"})
def test_09_invalidate_edit_user(self): # Validate that editing users actually invalidates the cache. For that, we first need an editable resolver self._create_sql_realm() # The cache is initially empty self.assertEquals(UserCache.query.count(), 0) # The following adds an entry to the cache user = User(login="******", realm=self.sql_realm) self.assertEquals(UserCache.query.count(), 1) uinfo = user.info self.assertEqual(uinfo.get("givenname", ""), "") user.update_user_info({"givenname": "wordy"}) uinfo = user.info self.assertEqual(uinfo.get("givenname"), "wordy") # This should have removed the entry from the cache self.assertEqual(UserCache.query.count(), 0) # But now it gets added again user2 = User(login="******", realm=self.sql_realm) self.assertEqual(UserCache.query.count(), 1) # Change it back for the other tests user.update_user_info({"givenname": ""}) uinfo = user.info self.assertEqual(uinfo.get("givenname", ""), "") self.assertEqual(UserCache.query.count(), 0) self._delete_sql_realm()
def test_00_create_user(self): rid = save_resolver({"resolver": self.resolvername1, "type": "passwdresolver", "fileName": PWFILE}) self.assertTrue(rid > 0, rid) (added, failed) = set_realm(self.realm1, [self.resolvername1]) self.assertTrue(len(failed) == 0) self.assertTrue(len(added) == 1) user = User(login="******", realm=self.realm1, resolver=self.resolvername1) user_str = "{0!s}".format(user) self.assertTrue(user_str == "<root.resolver1@realm1>", user_str) # check proper unicode() and str() handling self.assertIsInstance(str(user), bytes) self.assertIsInstance(unicode(user), unicode) self.assertFalse(user.is_empty()) self.assertTrue(User().is_empty()) user_repr = "{0!r}".format(user) expected = "User(login='******', realm='realm1', resolver='resolver1')" self.assertTrue(user_repr == expected, user_repr)
def test_16_ordered_resolver(self): rid = save_resolver({"resolver": "resolver2", "type": "passwdresolver", "fileName": PWFILE}) rid = save_resolver({"resolver": "reso4", "type": "passwdresolver", "fileName": PWFILE}) (added, failed) = set_realm("sort_realm", ["resolver1", "resolver2", "reso3", "reso4"], priority={"resolver1": 30, "resolver2": 10, "reso3": 27, "reso4": 5}) self.assertTrue(len(failed) == 0) self.assertTrue(len(added) == 4) root = User("root", "sort_realm") r = root.get_ordererd_resolvers() self.assertEqual(r[0], "reso4") self.assertEqual(r[1], "resolver2") self.assertEqual(r[2], "reso3") self.assertEqual(r[3], "resolver1") delete_realm("sort_realm")
def test_02_get_user_identifiers(self): user = User(login="******", realm=self.realm1) (uid, rtype, resolvername) = user.get_user_identifiers() self.assertTrue(uid == "0", uid) self.assertTrue(rtype == "passwdresolver", rtype) self.assertTrue(resolvername == self.resolvername1, resolvername)
def test_11_get_search_fields(self): user = User(login="******", realm=self.realm1) sF = user.get_search_fields() self.assertTrue(self.resolvername1 in sF, sF) resolver_sF = sF.get(self.resolvername1) self.assertTrue("username" in resolver_sF, resolver_sF) self.assertTrue("userid" in resolver_sF, resolver_sF)
def auth_otppin(wrapped_function, *args, **kwds): """ Decorator to decorate the tokenclass.check_pin function. Depending on the ACTION.OTPPIN it * either simply accepts an empty pin * checks the pin against the userstore * or passes the request to the wrapped_function :param wrapped_function: In this case the wrapped function should be tokenclass.check_ping :param *args: args[1] is the pin :param **kwds: kwds["options"] contains the flask g :return: True or False """ # if tokenclass.check_pin is called in any other way, options may be None # or it might have no element "g". options = kwds.get("options") or {} g = options.get("g") if g: token = args[0] pin = args[1] clientip = options.get("clientip") user_object = kwds.get("user") if not user_object: # No user in the parameters, so we need to determine the owner of # the token user_object = token.user realms = token.get_realms() if not user_object and len(realms): # if the token has not owner, we take a realm. user_object = User("", realm=realms[0]) if not user_object: # If we still have no user and no tokenrealm, we create an empty # user object. user_object=User("", realm="") # get the policy policy_object = g.policy_object otppin_dict = policy_object.get_action_values(ACTION.OTPPIN, scope=SCOPE.AUTH, realm=user_object.realm, resolver=user_object.resolver, user=user_object.login, client=clientip, unique=True, audit_data=g.audit_object.audit_data) if otppin_dict: if list(otppin_dict)[0] == ACTIONVALUE.NONE: if pin == "": # No PIN checking, we expect an empty PIN! return True else: return False if list(otppin_dict)[0] == ACTIONVALUE.USERSTORE: rv = user_object.check_password(pin) return rv is not None # call and return the original check_pin function return wrapped_function(*args, **kwds)
def test_01_resolvers_of_user(self): user = User(login="******", realm=self.realm1) resolvers = user.get_resolvers() self.assertTrue(self.resolvername1 in resolvers, resolvers) self.assertFalse(self.resolvername2 in resolvers, resolvers) user2 = User(login="******", realm=self.realm1, resolver=self.resolvername1) resolvers = user2.get_resolvers() self.assertTrue(self.resolvername1 in resolvers, resolvers) self.assertFalse(self.resolvername2 in resolvers, resolvers)
def test_10_invalidate_delete_user(self): # Validate that deleting users actually invalidates the cache. For that, we first need an editable resolver self._create_sql_realm() # The cache is initially empty self.assertEquals(UserCache.query.count(), 0) # The following adds an entry to the cache user = User(login="******", realm=self.sql_realm) self.assertEquals(UserCache.query.count(), 1) uinfo = user.info user.delete() # This should have removed the entry from the cache self.assertEqual(UserCache.query.count(), 0) # We add the user again for the other tests create_user(self.sql_resolver, uinfo) self.assertEqual(UserCache.query.count(), 0) self._delete_sql_realm()
def test_03_get_identifiers(self): # create realm self._create_realm() # delete user_cache r = delete_user_cache() self.assertTrue(r >= 0) # The username is not in the cache. It is fetched from the resolver # At the same time the cache is filled. Implicitly we test the # _get_resolvers! user = User(self.username, self.realm1, self.resolvername1) uids = user.get_user_identifiers() self.assertEqual(user.login, self.username) self.assertEqual(user.uid, self.uid) # Now, the cache should have exactly one entry entry = UserCache.query.one() self.assertEqual(entry.user_id, self.uid) self.assertEqual(entry.username, self.username) self.assertEqual(entry.resolver, self.resolvername1) # delete the resolver, which also purges the cache self._delete_realm() # manually re-add the entry from above UserCache(entry.username, entry.resolver, entry.user_id, entry.timestamp).save() # the username is fetched from the cache u_name = get_username(self.uid, self.resolvername1) self.assertEqual(u_name, self.username) # The `User` class also fetches the UID from the cache user2 = User(self.username, self.realm1, self.resolvername1) self.assertEqual(user2.uid, self.uid) # delete the cache r = delete_user_cache() # try to fetch the username. It is not in the cache and the # resolver does not exist anymore. u_name = get_username(self.uid, self.resolvername1) self.assertEqual(u_name, "") # similar case for the `User` class # The `User` class also tries to fetch the UID from the cache with self.assertRaises(UserError): user3 = User(self.username, self.realm1, self.resolvername1)
def test_00_create_user_realm(self): rid = save_resolver({"resolver": self.resolvername1, "type": "passwdresolver", "fileName": PWFILE}) self.assertTrue(rid > 0, rid) (added, failed) = set_realm(self.realm1, [self.resolvername1]) self.assertTrue(len(failed) == 0) self.assertTrue(len(added) == 1) user = User(login="******", realm=self.realm1, resolver=self.resolvername1) user_str = "%s" % user self.assertTrue(user_str == "<root.resolver1@realm1>", user_str) self.assertFalse(user.is_empty()) self.assertTrue(User().is_empty()) user_repr = "%r" % user expected = "User(login='******', realm='realm1', resolver='resolver1')" self.assertTrue(user_repr == expected, user_repr)
def update_user(): """ Edit a user in the user store. The resolver must have the flag editable, so that the user can be deleted. Only administrators are allowed to edit users. **Example request**: .. sourcecode:: http PUT /user user=existing_user resolver=<resolvername> surname=... givenname=... email=... mobile=... phone=... password=... description=... Host: example.com Accept: application/json .. note:: Also a user can call this function to e.g. change his password. But in this case the parameter "user" and "resolver" get overwritten by the values of the authenticated user, even if he specifies another username. """ attributes = _get_attributes_from_param(request.all_data) username = getParam(request.all_data, "user", optional=False) resolvername = getParam(request.all_data, "resolver", optional=False) user_obj = User(login=username, resolver=resolvername) # Remove the password from the attributes, so that we can hide it in the # logs password = attributes.get("password") if password: del attributes["password"] r = user_obj.update_user_info(attributes, password=password) g.audit_object.log({"success": True, "info": u"{0!s}: {1!s}/{2!s}".format(r, username, resolvername)}) return send_result(r)
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 delete_user(resolvername=None, username=None): """ Delete a User in the user store. The resolver must have the flag editable, so that the user can be deleted. Only administrators are allowed to delete users. Delete a user object in a user store by calling **Example request**: .. sourcecode:: http DELETE /user/<resolvername>/<username> Host: example.com Accept: application/json """ user_obj = User(login=username, resolver=resolvername) res = user_obj.delete() g.audit_object.log({"success": res, "info": u"{0!s}".format(user_obj)}) return send_result(res)
def test_02_set_user(self): db_token = Token.query.filter_by(serial=self.serial1).first() token = HotpTokenClass(db_token) self.assertTrue(token.token.tokentype == "hotp", token.token.tokentype) self.assertTrue(token.type == "hotp", token.type) token.set_user(User(login="******", realm=self.realm1)) self.assertTrue(token.token.resolver_type == "passwdresolver", token.token.resolver_type) self.assertTrue(token.token.resolver == self.resolvername1, token.token.resolver) self.assertTrue(token.token.user_id == "1000", token.token.user_id) user_object = token.user self.assertTrue(user_object.login == "cornelius", user_object) self.assertTrue(user_object.resolver == self.resolvername1, user_object) token.set_user_identifiers(2000, self.resolvername1, "passwdresolver") self.assertTrue(int(token.token.user_id) == 2000, token.token.user_id)
def test_02_sendmail(self): # setup realms self.setUp_user_realms() r = add_smtpserver(identifier="myserver", server="1.2.3.4", tls=False) 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": {"emailconfig": "myserver"}} un_handler = UserNotificationEventHandler() res = un_handler.do("sendmail", options=options) self.assertTrue(res)
def test_02_get_resolvers(self): # enable user cache set_privacyidea_config(EXPIRATION_SECONDS, 600) # create realm self._create_realm() # delete user_cache r = delete_user_cache() self.assertTrue(r >= 0) # The username is not in the cache. It is fetched from the resolver # At the same time the cache is filled. user = User(self.username, self.realm1) self.assertEqual(user.login, self.username) # The user ID is fetched from the resolver self.assertEqual(user.uid, self.uid) # Now, the cache should have exactly one entry entry = UserCache.query.one() self.assertEqual(entry.user_id, self.uid) self.assertEqual(entry.username, self.username) self.assertEqual(entry.resolver, self.resolvername1) ts = entry.timestamp # delete the resolver, which also purges the cache self._delete_realm() # manually re-add the entry from above UserCache(self.username, self.username, self.resolvername1, self.uid, ts).save() # the username is fetched from the cache u_name = get_username(self.uid, self.resolvername1) self.assertEqual(u_name, self.username) # delete the cache r = delete_user_cache() # try to fetch the username. It is not in the cache and the # resolver does not exist anymore. u_name = get_username(self.uid, self.resolvername1) self.assertEqual(u_name, "")
def test_03a_api_authenticate_fail(self): # This tests the failed to communicate to the firebase service self.setUp_user_realms() # get enrolled push token toks = get_tokens(tokentype="push") self.assertEqual(len(toks), 1) tokenobj = toks[0] # 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.ServiceAccountCredentials') as mySA: # alternative: side_effect instead of return_value mySA.from_json_keyfile_name.return_value = myCredentials(myAccessTokenInfo("my_bearer_token")) # add responses, to simulate the failing communication (status 500) responses.add(responses.POST, 'https://fcm.googleapis.com/v1/projects/test-123456/messages:send', body="""{}""", status=500, content_type="application/json") # Send the first authentication request to trigger the challenge 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.") # Our ServiceAccountCredentials mock has been called once, because no access token has been fetched before self.assertEqual(len(mySA.from_json_keyfile_name.mock_calls), 1) self.assertIn(FIREBASE_FILE, get_app_local_store()["firebase_token"])
def remove_user_tokens(username, realm): user_obj = User(login=username, realm=realm) # get the token which was enrolled during the triggering /token/init active = True if ONLY_ACTIVE is True else None tokentype = None if REMOVE_TYPE == "all" else REMOVE_TYPE.lower() # remove tokens if any for tok in get_tokens(user=user_obj, tokentype=tokentype, active=active, tokeninfo=TOKENINFO or None): if tok.token.serial: remove_token(serial=tok.token.serial) log.debug("- Remove token with serial {0!s}".format( tok.token.serial)) # check remaining tokens remaining_tokens = get_tokens(user=user_obj) log.debug("User {0!s}@{1!s} has {2!s} remaining tokens." "".format(username, realm, len(remaining_tokens))) for tok in remaining_tokens: log.debug("~ a {0!s} token with serial {1!s}".format( tok.type.upper(), tok.token.serial))
def modify_token(username, realm, ttype): app = create_app(config_name="production", config_file="/etc/privacyidea/pi.cfg", silent=True) with app.app_context(): user_obj = User(username, realm) if user_obj: # Get all active tokens of this types from this user toks = get_tokens(user=user_obj, tokentype=ttype, active=True) # Delete all SMS tokens. for tok_obj in toks: serial = tok_obj.token.serial if ACTION == "delete": tok_obj.delete_token() else: enable_token(serial, False) with open(LOGFILE, "a") as f: f.write(u"{0!s}, {1!s}, {2!s}, {3!s}, {4!s}\n".format( datetime.datetime.now().strftime("%Y-%m-%dT%H:%M"), args.username, args.realm, ACTION, serial))
def test_15_reset_all_failcounters(self): self.setUp_user_realms() set_policy("reset_all", scope=SCOPE.AUTH, action=ACTION.RESETALLTOKENS) user = User(login="******", realm=self.realm1) pin1 = "pin1" pin2 = "pin2" token1 = init_token({"serial": pin1, "pin": pin1, "type": "spass"}, user=user) token2 = init_token({"serial": pin2, "pin": pin2, "type": "spass"}, user=user) token1.inc_failcount() token2.inc_failcount() token2.inc_failcount() self.assertEqual(token1.token.failcount, 1) self.assertEqual(token2.token.failcount, 2) g.policy_object = PolicyClass() g.audit_object = FakeAudit() g.client_ip = None g.serial = None options = {"g": g} r = reset_all_user_tokens(self.fake_check_token_list, [token1, token2], "pw", None, options=options, allow_reset_all_tokens=True, result=True) self.assertTrue(r) self.assertEqual(token1.token.failcount, 0) self.assertEqual(token2.token.failcount, 0) # Clean up remove_token(pin1) remove_token(pin2)
def test_03_otppin_for_serial(self): # now create a policy with userstore PW set_policy(name="pol1", scope=SCOPE.AUTH, action="{0!s}={1!s}".format(ACTION.OTPPIN, ACTIONVALUE.USERSTORE)) g = FakeFlaskG() P = PolicyClass() g.policy_object = P g.audit_object = FakeAudit() options = {"g": g, "serial": "T001"} # create a token and assign to user cornelius token = init_token({ "serial": "T001", "type": "hotp", "genkey": 1 }, user=User("cornelius", realm="r1")) self.assertTrue(token) # Wrong password # Not identified by the user but by the token owner r = auth_otppin(self.fake_check_otp, token, "WrongPW", options=options, user=None) self.assertFalse(r) # Correct password from userstore: "test" # Not identified by the user but by the token owner r = auth_otppin(self.fake_check_otp, token, "test", options=options, user=None) self.assertTrue(r) delete_policy("pol1") remove_token("T001")
def test_08_config_lost_token_policy(self): def func1(serial, validity=10, contents="Ccns", pw_len=16, options=None): self.assertEqual(validity, 10) self.assertEqual(contents, "Ccns") self.assertEqual(pw_len, 16) def func2(serial, validity=10, contents="Ccns", pw_len=16, options=None): self.assertEqual(validity, 5) self.assertEqual(contents, "C") self.assertEqual(pw_len, 3) init_token({"serial": "LOST001", "type": "hotp", "genkey": 1}, user=User("cornelius", realm="r1")) g = FakeFlaskG() P = PolicyClass() g.policy_object = P g.audit_object = FakeAudit() options = {"g": g} # No policy, the function is called with default values config_lost_token(func1, "LOST001", options=options) set_policy(name="lost_pol2", scope=SCOPE.ENROLL, action="%s=%s, %s=%s," "%s=%s" % (ACTION.LOSTTOKENPWCONTENTS, "C", ACTION.LOSTTOKENVALID, 5, ACTION.LOSTTOKENPWLEN, 3)) g = FakeFlaskG() P = PolicyClass() g.policy_object = P g.audit_object = FakeAudit() options = {"g": g} # Policy is set, the function is called with check_otp=True config_lost_token(func2, "LOST001", options=options)
def test_07_get_user_realms(self): user = User(login="******", realm=self.realm1) realms = user.get_user_realms() self.assertTrue(len(realms) == 1, realms) self.assertTrue(self.realm1 in realms, realms) # test for default realm user = User(login="******") realms = user.get_user_realms() self.assertTrue(len(realms) == 1, realms) # test for user with only a resolver user = User(login="******", resolver=self.resolvername1) realms = user.get_user_realms() self.assertTrue(len(realms) == 1, realms) self.assertTrue(self.realm1 in realms, realms)
def test_01_failcounter_max_hotp(self): # Check if we can not authenticate with a token that has the maximum # failcounter user = User(login="******", realm=self.realm1) token = init_token( { "serial": "test47", "pin": "test47", "type": "hotp", "otpkey": OTPKEY }, user=user) """ Truncated Count Hexadecimal Decimal HOTP 0 4c93cf18 1284755224 755224 1 41397eea 1094287082 287082 2 82fef30 137359152 359152 3 66ef7655 1726969429 969429 4 61c5938a 1640338314 338314 5 33c083d4 868254676 254676 6 7256c032 1918287922 287922 7 4e5b397 82162583 162583 8 2823443f 673399871 399871 9 2679dc69 645520489 520489 10 403154 11 481090 12 868912 13 736127 """ res, reply = check_user_pass(user, "test47287082") self.assertTrue(res) # Set the failcounter to maximum failcount token.set_failcount(10) # Authentication must fail, since the failcounter is reached res, reply = check_user_pass(user, "test47359152") self.assertFalse(res) self.assertEqual(reply.get("message"), "matching 1 tokens, " "Failcounter exceeded") remove_token("test47")
def test_16_autoresync_hotp(self): serial = "autosync1" token = init_token( { "serial": serial, "otpkey": self.otpkey, "pin": "async" }, User("cornelius", self.realm2)) set_privacyidea_config("AutoResync", True) token.set_sync_window(10) token.set_count_window(5) # counter = 8, is out of sync with self.app.test_request_context('/validate/check', method='POST', data={ "user": "******" + self.realm2, "pass": "******" }): res = self.app.full_dispatch_request() self.assertEqual(res.status_code, 200) result = json.loads(res.data).get("result") self.assertEqual(result.get("value"), False) # counter = 9, will be autosynced. # Authentication is successful with self.app.test_request_context('/validate/check', method='POST', data={ "user": "******" + self.realm2, "pass": "******" }): res = self.app.full_dispatch_request() self.assertEqual(res.status_code, 200) result = json.loads(res.data).get("result") self.assertEqual(result.get("value"), True) delete_privacyidea_config("AutoResync")
def test_04_user_does_not_exist(self): user = User("MisterX", realm="NoRealm") passw = "wrongPW" options = {} # A non-existing user will fail to authenticate without a policy self.assertRaises(UserError, auth_user_does_not_exist, check_user_pass, user, passw, options) # Now we set a policy, that a non existing user will authenticate set_policy(name="pol1", scope=SCOPE.AUTH, action=ACTION.PASSNOUSER) g = FakeFlaskG() g.policy_object = PolicyClass() options = {"g": g} rv = auth_user_does_not_exist(check_user_pass, user, passw, options=options) self.assertTrue(rv[0]) self.assertEqual(rv[1].get("message"), u"user does not exist, accepted due " u"to 'pol1'") delete_policy("pol1")
def test_06_check_conditions_realm(self): uhandler = UserNotificationEventHandler() # check a locked token with maxfail = failcount builder = EnvironBuilder(method='POST', data={'user': "******"}, headers={}) env = builder.get_environ() req = Request(env) req.all_data = {"user": "******"} req.User = User("cornelius", "realm1") resp = Response() resp.data = """{"result": {"value": false}}""" r = uhandler.check_condition( {"g": {}, "handler_def": {"conditions": {"realm": "realm2"}}, "request": req, "response": resp } ) # wrong realm self.assertEqual(r, False)
def test_33_lost_token(self): # create a token with a user serial1 = "losttoken" tobject1 = init_token({"serial": serial1, "genkey": 1}) r = assign_token(serial1, User(login="******", realm=self.realm1)) self.assertTrue(r, r) # call the losttoken self.assertRaises(TokenAdminError, lost_token, "doesnotexist") r = lost_token(serial1) """ r = {'end_date': '16/12/14 23:59', 'pin': True, 'valid_to': 'xxxx', 'init': True, 'disable': 1, 'user': True, 'serial': 'lostlosttoken', 'password': '******'} """ self.assertTrue(r.get("pin") == True, r) self.assertTrue(r.get("init") == True, r) self.assertTrue(r.get("user") == True, r) self.assertTrue(r.get("serial") == "lost%s" % serial1, r) remove_token("losttoken") remove_token("lostlosttoken")
def test_06_passthru(self): user = User("cornelius", realm="r1") passw = "test" options = {} # A user with no tokens will fail to authenticate self.assertEqual(get_tokens(user=user, count=True), 0) rv = auth_user_passthru(check_user_pass, user, passw, options) self.assertFalse(rv[0]) self.assertEqual(rv[1].get("message"), "The user has no tokens assigned") # Now we set a PASSTHRU policy, so that the user may authenticate # against his userstore set_policy(name="pol1", scope=SCOPE.AUTH, action=ACTION.PASSTHRU) g = FakeFlaskG() g.policy_object = PolicyClass() options = {"g": g} rv = auth_user_passthru(check_user_pass, user, passw, options=options) self.assertTrue(rv[0]) self.assertEqual( rv[1].get("message"), u"The user authenticated against his userstore " u"according to policy 'pol1'.") # Now assign a token to the user. If the user has a token and the # passthru policy is set, the user must not be able to authenticate # with his userstore password. init_token({ "serial": "PTHRU", "type": "spass", "pin": "Hallo" }, user=user) rv = auth_user_passthru(check_user_pass, user, passw, options=options) self.assertFalse(rv[0]) self.assertEqual(rv[1].get("message"), "wrong otp pin") remove_token("PTHRU") delete_policy("pol1")
def test_18_challenges(self): db_token = Token.query.filter_by(serial=self.serial1).first() token = TokenClass(db_token) transaction_id = "123456789" db_token.set_pin("test") # No challenge request, since we have the wrong pin req = token.is_challenge_request( "testX", User(login="******", realm=self.realm1)) self.assertFalse(req, req) # A challenge request, since we have the correct pin req = token.is_challenge_request( "test", User(login="******", realm=self.realm1)) self.assertTrue(req, req) resp = token.is_challenge_response( User(login="******", realm=self.realm1), "test123456") self.assertFalse(resp, resp) # A the token has not DB entry in the challenges table, basically # "is_cahllenge_response" resp = token.is_challenge_response( User(login="******", realm=self.realm1), "test123456", options={"transaction_id": transaction_id}) self.assertTrue(resp) # ... but is does not "has_db_challenge_response" resp = token.has_db_challenge_response( User(login="******", realm=self.realm1), "test123456", options={"transaction_id": transaction_id}) self.assertFalse(resp) # Create a challenge C = Challenge(serial=self.serial1, transaction_id=transaction_id, challenge="12") C.save() resp = token.is_challenge_response( User(login="******", realm=self.realm1), "test123456", options={"transaction_id": transaction_id}) self.assertTrue(resp) # test if challenge is valid self.assertTrue(C.is_valid())
def challenge_response_wrapper(*args, **kwds): options = kwds.get("options", {}) g = options.get("g") token = args[0] passw = args[1] clientip = options.get("clientip") user_object = kwds.get("user") or User() if g: policy_object = g.policy_object allowed_tokentypes_dict = policy_object.get_action_values( action=ACTION.CHALLENGERESPONSE, scope=SCOPE.AUTH, realm=user_object.realm, resolver=user_object.resolver, user=user_object.login, client=clientip) log.debug("Found these allowed tokentypes: {0!s}".format( list(allowed_tokentypes_dict))) # allowed_tokentypes_dict.keys() is a list of actions from several policies. I # could look like this: # ["tiqr hotp totp", "tiqr motp"] chal_resp_found = False for toks in allowed_tokentypes_dict: if token.get_tokentype().upper() in [ x.upper() for x in toks.split(" ") ]: # This token is allowed to to chal resp chal_resp_found = True g.audit_object.add_policy( allowed_tokentypes_dict.get(toks)) if not chal_resp_found: # No policy to allow this token to do challenge response return False f_result = func(*args, **kwds) return f_result
def test_10_auth_lastauth(self): serial = "SPASSLASTAUTH" pin = "secretpin" def fake_auth_missing_serial(user, pin, options=None): return True, {} def fake_auth(user, pin, options): return True, {"serial": serial} user = User("cornelius", realm="r1") init_token({"type": "spass", "pin": pin, "serial": serial}, user=user) # set time limit policy set_policy(name="pol_lastauth", scope=SCOPE.AUTHZ, action="{0!s}=1d".format(ACTION.LASTAUTH)) g = FakeFlaskG() g.policy_object = PolicyClass() g.audit_object = FakeAudit() options = {"g": g} rv = auth_lastauth(fake_auth, user, pin, options) self.assertEqual(rv[0], True) token = get_tokens(serial=serial)[0] # Set a very old last_auth token.add_tokeninfo(ACTION.LASTAUTH, datetime.datetime.utcnow()-datetime.timedelta(days=2)) rv = auth_lastauth(fake_auth, user, pin, options) self.assertEqual(rv[0], False) self.assertTrue("The last successful authentication was" in rv[1].get("message"), rv[1]) remove_token(serial) delete_policy("pol_lastauth")
def test_03_inc_failcounter_of_all_tokens(self): # If a user has more than one token and authenticates with wrong OTP # PIN, the failcounter on all tokens should be increased user = User(login="******", realm=self.realm1) pin1 = "pin1" pin2 = "pin2" token1 = init_token( { "serial": pin1, "pin": pin1, "type": "hotp", "genkey": 1 }, user=user) token2 = init_token( { "serial": pin2, "pin": pin2, "type": "hotp", "genkey": 1 }, user=user) # Authenticate with pin1 will increase first failcounter res, reply = check_user_pass(user, pin1 + "000000") self.assertEqual(res, False) self.assertEqual(reply.get("message"), "wrong otp value") self.assertEqual(token1.token.failcount, 1) self.assertEqual(token2.token.failcount, 0) # Authenticate with a wrong PIN will increase all failcounters res, reply = check_user_pass(user, "XXX" + "000000") self.assertEqual(res, False) self.assertEqual(reply.get("message"), "wrong otp pin") self.assertEqual(token1.token.failcount, 2) self.assertEqual(token2.token.failcount, 1)
def test_17_auth_timelimit_success(self): user = User("timelimituser", realm=self.realm2) pin = "spass" # create a token token = init_token({"type": "spass", "pin": pin}, user=user) # set policy for timelimit set_policy(name="pol_time1", scope=SCOPE.AUTHZ, action="%s=2/20s" % ACTION.AUTHMAXSUCCESS) for i in [1, 2]: with self.app.test_request_context('/validate/check', method='POST', data={ "user": "******", "realm": self.realm2, "pass": pin }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data).get("result") self.assertEqual(result.get("value"), True) with self.app.test_request_context('/validate/check', method='POST', data={ "user": "******", "realm": self.realm2, "pass": pin }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data).get("result") self.assertEqual(result.get("value"), False) delete_policy("pol_time1") remove_token(token.token.serial)
def test_02_get_auth_item(self): serial = "UBOM12345" # create realm self.setUp_user_realms() user = User("cornelius", realm=self.realm1) # create ssh token init_token({ "serial": serial, "type": "totp", "otpkey": OTPKEY }, user=user) auth_item = LUKSApplication.get_authentication_item("totp", serial) self.assertEqual(len(auth_item.get("challenge")), 64) self.assertEqual(len(auth_item.get("response")), 40) auth_item = LUKSApplication.get_authentication_item("totp", serial, challenge="123456") self.assertEqual(auth_item.get("challenge"), "123456") self.assertEqual(auth_item.get("response"), "76d624a5fdf8d84f3d19e781f0313e48c1e69165")
def test_08_missing_attestation(self): self.init_params['nonce'] = webauthn_b64_decode( NONE_ATTESTATION_REGISTRATION_CHALLENGE) self.user = User(login=NONE_ATTESTATION_USER_NAME) self.token.get_init_detail(self.init_params, self.user) with self.assertRaises(RegistrationRejectedException): self.token.update({ 'type': 'webauthn', 'serial': self.token.token.serial, 'regdata': NONE_ATTESTATION_REGISTRATION_RESPONSE_TMPL['attObj'], 'clientdata': NONE_ATTESTATION_REGISTRATION_RESPONSE_TMPL['clientData'], WEBAUTHNACTION.RELYING_PARTY_ID: RP_ID, WEBAUTHNACTION.AUTHENTICATOR_ATTESTATION_LEVEL: ATTESTATION_LEVEL.UNTRUSTED, 'HTTP_ORIGIN': ORIGIN })
def test_04a_user_does_not_exist_without_resolver(self): user = User("MisterX", realm=self.realm1) passw = "somePW" # Now we set a policy, that a non existing user will authenticate set_policy(name="pol1", scope=SCOPE.AUTH, action="{0}, {1}, {2}, {3}=none".format( ACTION.RESETALLTOKENS, ACTION.PASSNOUSER, ACTION.PASSNOTOKEN, ACTION.OTPPIN), realm=self.realm1) g = FakeFlaskG() g.policy_object = PolicyClass() options = {"g": g} rv = auth_user_does_not_exist(check_user_pass, user, passw, options=options) self.assertTrue(rv[0]) self.assertEqual(rv[1].get("message"), u"user does not exist, accepted due " u"to 'pol1'") delete_policy("pol1")
def test_02_get_auth_item(self): serial = "OATH1" # create realm self.setUp_user_realms() user = User("cornelius", realm=self.realm1) # create ssh token init_token({ "serial": serial, "type": "hotp", "otpkey": OTPKEY }, user=user) auth_item = OfflineApplication.get_authentication_item("hotp", serial) self.assertTrue(passlib.hash.\ pbkdf2_sha512.verify("755224", auth_item.get("response").get(0))) self.assertTrue(passlib.hash.\ pbkdf2_sha512.verify("254676", auth_item.get("response").get(5))) # After calling auth_item the token counter should be increased tok = get_tokens(serial=serial)[0] self.assertEqual(tok.token.count, 101)
def test_16_init_detail(self): db_token = Token.query.filter_by(serial=self.serial1).first() token = TotpTokenClass(db_token) token.add_init_details("otpkey", "11223344556677889900") detail = token.get_init_detail() self.assertTrue("otpkey" in detail, detail) # but the otpkey must not be written to token.token.info (DB) # As this only writes the OTPkey to the internal init_details dict self.assertTrue("otpkey" not in token.token.get_info(), token.token.get_info()) # Now get the Google Authenticator URL, which we only # get, if a user is specified. detail = token.get_init_detail(user=User("cornelius", self.realm1)) self.assertTrue("otpkey" in detail, detail) otpkey = detail.get("otpkey") self.assertTrue("img" in otpkey, otpkey) self.assertTrue("googleurl" in detail, detail) # some other stuff. self.assertRaises(Exception, token.set_init_details, "invalid value") token.set_init_details({"detail1": "value1"}) self.assertTrue("detail1" in token.get_init_details(), token.get_init_details())
def test_08_check_conditions_serial(self): uhandler = UserNotificationEventHandler() # check a serial with regexp builder = EnvironBuilder(method='POST', data={'user': "******"}, headers={}) env = builder.get_environ() req = Request(env) req.all_data = {"user": "******", "serial": "OATH123456"} req.User = User("cornelius", "realm1") resp = Response() resp.data = """{"result": {"value": true}}""" r = uhandler.check_condition( {"g": {}, "handler_def": {"conditions": {"serial": "^OATH.*"}}, "request": req, "response": resp } ) # Serial matches the regexp self.assertEqual(r, True)
def setUp(self): self.token = init_token({ 'type': 'webauthn', 'pin': '1234' }) self.init_params = { WEBAUTHNACTION.RELYING_PARTY_ID: RP_ID, WEBAUTHNACTION.RELYING_PARTY_NAME: RP_NAME, WEBAUTHNACTION.TIMEOUT: TIMEOUT, WEBAUTHNACTION.AUTHENTICATOR_ATTESTATION_FORM: DEFAULT_AUTHENTICATOR_ATTESTATION_FORM, WEBAUTHNACTION.USER_VERIFICATION_REQUIREMENT: DEFAULT_USER_VERIFICATION_REQUIREMENT, WEBAUTHNACTION.PUBLIC_KEY_CREDENTIAL_ALGORITHM_PREFERENCE: PUBLIC_KEY_CREDENTIAL_ALGORITHM_PREFERENCE } self.user = User(login=USER_NAME) self.challenge_options = { "user": self.user, WEBAUTHNACTION.ALLOWED_TRANSPORTS: ALLOWED_TRANSPORTS, WEBAUTHNACTION.USER_VERIFICATION_REQUIREMENT: DEFAULT_USER_VERIFICATION_REQUIREMENT, WEBAUTHNACTION.TIMEOUT: TIMEOUT }
def test_02_get_user_identifiers(self): # create user by login user = User(login="******", realm=self.realm1) (uid, rtype, resolvername) = user.get_user_identifiers() self.assertEqual("0", uid) self.assertEqual("passwdresolver", rtype) self.assertEqual(self.resolvername1, resolvername) self.assertEqual(user.realm_id, 1) # create user by uid. fail, since the resolver is missing self.assertRaises(UserError, User, realm=self.realm1, uid="0") # create user by uid. user2 = User(realm=self.realm1, resolver=self.resolvername1, uid="0") (uid, rtype, resolvername) = user2.get_user_identifiers() self.assertEqual("root", user2.login) self.assertEqual("passwdresolver", rtype) self.assertEqual(self.resolvername1, resolvername) self.assertEqual(user.realm_id, 1)
def test_02_failcounter_max_totp(self): # Check if we can not authenticate with a token that has the maximum # failcounter user = User(login="******", realm=self.realm1) pin = "testTOTP" token = init_token( { "serial": pin, "pin": pin, "type": "totp", "otpkey": OTPKEY }, user=user) """ 47251644 942826 47251645 063321 47251646 306773 47251647 722053 47251648 032819 47251649 705493 47251650 589836 """ res, reply = check_user_pass(user, pin + "942826", options={"initTime": 47251644 * 30}) self.assertTrue(res) # Set the failcounter to maximum failcount token.set_failcount(10) # Authentication must fail, since the failcounter is reached res, reply = check_user_pass(user, pin + "032819", options={"initTime": 47251648 * 30}) self.assertFalse(res) self.assertEqual(reply.get("message"), "matching 1 tokens, " "Failcounter exceeded") remove_token(pin)
def before_request(): """ This is executed before the request """ ensure_no_config_object() request.all_data = get_all_params(request.values, request.data) privacyidea_server = current_app.config.get("PI_AUDIT_SERVERNAME") or \ request.host g.policy_object = PolicyClass() g.audit_object = getAudit(current_app.config) g.event_config = EventConfiguration() # access_route contains the ip adresses of all clients, hops and proxies. g.client_ip = get_client_ip(request, get_from_config(SYSCONF.OVERRIDECLIENT)) g.serial = getParam(request.all_data, "serial", default=None) g.audit_object.log({"success": False, "client": g.client_ip, "client_user_agent": request.user_agent.browser, "privacyidea_server": privacyidea_server, "action": "{0!s} {1!s}".format(request.method, request.url_rule), "action_detail": "", "info": ""}) username = getParam(request.all_data, "username") if username: # We only fill request.User, if we really have a username. # On endpoints like /auth/rights, this is not available loginname, realm = split_user(username) # overwrite the split realm if we have a realm parameter. Default back to default_realm realm = getParam(request.all_data, "realm", default=realm) or realm or get_default_realm() # Prefill the request.User. This is used by some pre-event handlers try: request.User = User(loginname, realm) except Exception as e: request.User = None log.warning(u"Problem resolving user {0!s} in realm {1!s}: {2!s}.".format(loginname, realm, e)) log.debug(u"{0!s}".format(traceback.format_exc()))
def register_post(): """ Register a new user in the realm/userresolver. To do so, the user resolver must be writeable like an SQLResolver. Registering a user in fact creates a new user and also creates the first token for the user. The following values are needed to register the user: * username (mandatory) * givenname (mandatory) * surname (mandatory) * email address (mandatory) * password (mandatory) * mobile phone (optional) * telephone (optional) The user receives a registration token via email to be able to login with his self chosen password and the registration token. :jsonparam username: The login name of the new user. Check if it already exists :jsonparam givenname: The givenname of the new user :jsonparam surname: The surname of the new user :jsonparam email: The email address of the new user :jsonparam password: The password of the new user. This is the resolver password of the new user. :jsonparam mobile: The mobile phone number :jsonparam phone: The phone number (land line) of the new user :return: a json result with a boolean "result": true """ username = getParam(request.all_data, "username", required) surname = getParam(request.all_data, "surname", required) givenname = getParam(request.all_data, "givenname", required) email = getParam(request.all_data, "email", required) password = getParam(request.all_data, "password", required) mobile = getParam(request.all_data, "mobile") phone = getParam(request.all_data, "phone") options = {"g": g, "clientip": request.remote_addr} g.audit_object.log({"info": username}) # Add all params to the options for key, value in request.all_data.items(): if value and key not in ["g", "clientip"]: options[key] = value # 1. determine, in which resolver/realm the user should be created realm = g.policy_object.get_action_values(ACTION.REALM, scope=SCOPE.REGISTER, unique=True) if not realm: # No policy for realm, so we use the default realm realm = get_default_realm else: # we use the first realm in the list realm = realm[0] resolvername = g.policy_object.get_action_values(ACTION.RESOLVER, scope=SCOPE.REGISTER, unique=True) if not resolvername: raise RegistrationError("No resolver specified to register in!") resolvername = resolvername[0] # Check if the user exists user = User(username, realm=realm, resolver=resolvername) if user.exist(): raise RegistrationError("The username is already registered!") # Create user uid = create_user(resolvername, {"username": username, "email": email, "phone": phone, "mobile": mobile, "surname": surname, "givenname": givenname, "password": password}) # 3. create a registration token for this user user = User(username, realm=realm, resolver=resolvername) token = init_token({"type": "registration"}, user=user) # 4. send the registration token to the users email registration_key = token.init_details.get("otpkey") smtpconfig = g.policy_object.get_action_values(ACTION.EMAILCONFIG, scope=SCOPE.REGISTER, unique=True) if not smtpconfig: raise RegistrationError("No SMTP server configuration specified!") smtpconfig = smtpconfig[0] # Send the registration key via email r = send_email_identifier(smtpconfig, email, "Your privacyIDEA registration", "Your registration token is %s" % registration_key) log.debug("Registration email sent to %s" % email) g.audit_object.log({"success": r}) return send_result(r)
def get_auth_token(): """ This call verifies the credentials of the user and issues an authentication token, that is used for the later API calls. The authentication token has a validity, that is usually 1 hour. :jsonparam username: The username of the user who wants to authenticate to the API. :jsonparam password: The password/credentials of the user who wants to authenticate to the API. :return: A json response with an authentication token, that needs to be used in any further request. :status 200: in case of success :status 401: if authentication fails **Example Authentication Request**: .. sourcecode:: http POST /auth HTTP/1.1 Host: example.com Accept: application/json username=admin password=topsecret **Example Authentication Response**: .. sourcecode:: http HTTP/1.0 200 OK Content-Length: 354 Content-Type: application/json { "id": 1, "jsonrpc": "2.0", "result": { "status": true, "value": { "token": "eyJhbGciOiJIUz....jdpn9kIjuGRnGejmbFbM" } }, "version": "privacyIDEA unknown" } **Response for failed authentication**: .. sourcecode:: http HTTP/1.1 401 UNAUTHORIZED Content-Type: application/json Content-Length: 203 { "id": 1, "jsonrpc": "2.0", "result": { "error": { "code": -401, "message": "missing Authorization header" }, "status": false }, "version": "privacyIDEA unknown", "config": { "logout_time": 30 } } """ validity = timedelta(hours=1) username = request.all_data.get("username") password = request.all_data.get("password") realm = request.all_data.get("realm") details = {} if realm: username = username + "@" + realm g.audit_object.log({"user": username}) secret = current_app.secret_key superuser_realms = current_app.config.get("SUPERUSER_REALM", []) # This is the default role for the logged in user. # The role privileges may be risen to "admin" role = ROLE.USER # The way the user authenticated. This could be # "password" = The admin user DB or the user store # "pi" = The admin or the user is authenticated against privacyIDEA # "remote_user" = authenticated by webserver authtype = "password" if username is None: raise AuthError("Authentication failure", "missing Username", status=401) # Verify the password admin_auth = False user_auth = False loginname, realm = split_user(username) realm = realm or get_default_realm() # Check if the remote user is allowed if (request.remote_user == username) and is_remote_user_allowed(request): # Authenticated by the Web Server # Check if the username exists # 1. in local admins # 2. in a realm # 2a. is an admin realm authtype = "remote_user " if db_admin_exist(username): role = ROLE.ADMIN admin_auth = True g.audit_object.log({"success": True, "user": "", "administrator": username, "info": "internal admin"}) else: # check, if the user exists user_obj = User(loginname, realm) if user_obj.exist(): user_auth = True if user_obj.realm in superuser_realms: role = ROLE.ADMIN admin_auth = True elif verify_db_admin(username, password): role = ROLE.ADMIN admin_auth = True # This admin is not in the default realm! realm = "" g.audit_object.log({"success": True, "user": "", "administrator": username, "info": "internal admin"}) else: # The user could not be identified against the admin database, # so we do the rest of the check options = {"g": g, "clientip": g.client_ip} for key, value in request.all_data.items(): if value and key not in ["g", "clientip"]: options[key] = value user_obj = User(loginname, realm) user_auth, role, details = check_webui_user(user_obj, password, options=options, superuser_realms= superuser_realms) if role == ROLE.ADMIN: g.audit_object.log({"user": "", "administrator": username}) if not admin_auth and not user_auth: raise AuthError("Authentication failure", "Wrong credentials", status=401, details=details or {}) else: g.audit_object.log({"success": True}) # If the HSM is not ready, we need to create the nonce in another way! hsm = init_hsm() if hsm.is_ready: nonce = geturandom(hex=True) # Add the role to the JWT, so that we can verify it internally # Add the authtype to the JWT, so that we could use it for access # definitions rights = g.policy_object.ui_get_rights(role, realm, loginname, g.client_ip) else: import os import binascii nonce = binascii.hexlify(os.urandom(20)) rights = [] # What is the log level? log_level = current_app.config.get("PI_LOGLEVEL", 30) token = jwt.encode({"username": loginname, "realm": realm, "nonce": nonce, "role": role, "authtype": authtype, "exp": datetime.utcnow() + validity, "rights": rights}, secret) # Add the role to the response, so that the WebUI can make decisions # based on this (only show selfservice, not the admin part) return send_result({"token": token, "role": role, "username": loginname, "realm": realm, "log_level": log_level, "rights": rights}, details=details)
def test_15_user_exist(self): root = User("root", resolver=self.resolvername1, realm=self.realm1) self.assertTrue(root.exist())
def auth_otppin(wrapped_function, *args, **kwds): """ Decorator to decorate the tokenclass.check_pin function. Depending on the ACTION.OTPPIN it * either simply accepts an empty pin * checks the pin against the userstore * or passes the request to the wrapped_function :param wrapped_function: In this case the wrapped function should be tokenclass.check_ping :param *args: args[1] is the pin :param **kwds: kwds["options"] contains the flask g :return: True or False """ ERROR = "There are contradicting policies for the action %s!" % \ ACTION.OTPPIN # if tokenclass.check_pin is called in any other way, options may be None # or it might have no element "g". options = kwds.get("options") or {} g = options.get("g") if g: token = args[0] pin = args[1] clientip = options.get("clientip") user_object = kwds.get("user") if not user_object: # No user in the parameters, so we need to determine the owner of # the token user_object = token.get_user() realms = token.get_realms() if not user_object and len(realms): # if the token has not owner, we take a realm. user_object = User("", realm=realms[0]) if not user_object: # If we still have no user and no tokenrealm, we create an empty # user object. user_object=User("", realm="") # get the policy policy_object = g.policy_object otppin_list = policy_object.get_action_values(ACTION.OTPPIN, scope=SCOPE.AUTH, realm=user_object.realm, user=user_object.login, client=clientip) if len(otppin_list) > 0: # There is an otppin policy # reduce the list: otppin_list = list(set(otppin_list)) if len(otppin_list) > 1: # We can not decide how to handle the request, so we raise an # exception raise PolicyError(ERROR) if otppin_list[0] == ACTIONVALUE.NONE: if pin == "": # No PIN checking, we expect an empty PIN! return True else: return False if otppin_list[0] == ACTIONVALUE.USERSTORE: rv = user_object.check_password(pin) return rv is not None # call and return the original check_pin function return wrapped_function(*args, **kwds)
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)