Exemple #1
0
    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)
Exemple #2
0
    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)
Exemple #3
0
    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()
Exemple #5
0
 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)
Exemple #6
0
    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")
Exemple #7
0
 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)
Exemple #8
0
 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)
Exemple #10
0
    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)
Exemple #14
0
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")
Exemple #16
0
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)
Exemple #19
0
    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, "")
Exemple #20
0
    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"])
Exemple #21
0
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)
Exemple #26
0
 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)
Exemple #27
0
    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")
Exemple #28
0
    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")
Exemple #29
0
    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)
Exemple #31
0
    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")
Exemple #32
0
    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")
Exemple #33
0
    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())
Exemple #34
0
    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")
Exemple #36
0
    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)
Exemple #37
0
    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")
Exemple #39
0
    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
            })
Exemple #40
0
    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)
Exemple #42
0
    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)
Exemple #44
0
    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
        }
Exemple #45
0
    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)
Exemple #46
0
    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)
Exemple #47
0
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()))
Exemple #48
0
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)
Exemple #49
0
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)
Exemple #50
0
 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)
Exemple #52
0
    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)