Example #1
0
    def add_maildir(self, maildir_path):
        """ Load up a maildir add compute hash for each mail their contain. """
        maildir = Maildir(maildir_path, factory=None, create=False)
        # Collate folders by hash.
        logger.info(
            "Processing {} mails in {}".format(len(maildir), maildir._path))
        for mail_id, message in maildir.items():
            mail_file = os.path.join(maildir._path, maildir._lookup(mail_id))
            try:
                mail_hash, header_text = self.compute_hash(
                    mail_file, message, self.use_message_id)
            except InsufficientHeadersError as e:
                logger.warning(
                    "Ignoring problematic {}: {}".format(mail_file, e.args[0]))
            else:
                if self.mail_count > 0 and self.mail_count % 100 == 0:
                    logger.info(".")
                logger.debug(
                    "Hash is {} for mail {!r}.".format(mail_hash, mail_id))
                if mail_hash not in self.mails:
                    self.mails[mail_hash] = []

                self.mails[mail_hash].append((mail_file, message))
                self.mail_count += 1
Example #2
0
def test_email_works(tmpdir):
    """
    This is a basic test of the email server working OK.

    """

    email_server, maildir = generate_email_server(tmpdir)
    email_server.start()
    time.sleep(3.0)

    # send a test email
    email_sent = actions.send_email(
        "*****@*****.**",
        "Hello",
        "this is a test",
        ["*****@*****.**"],
        "127.0.0.1",
        None,
        None,
        "salt",
        port=9487,
    )

    assert email_sent is True

    # check if it was received
    mailbox = Maildir(maildir)

    for _, message in mailbox.items():

        if message["Subject"] == "Hello":
            assert message["From"] == "*****@*****.**"
            assert message["To"] == "*****@*****.**"
            assert "this is a test" in message.as_string()

    email_server.stop()
Example #3
0
def test_create_user_with_email(tmpdir):
    """
    This creates a user and tries to send a verification code to their email.

    """

    test_authdb_url = get_test_authdb(tmpdir)
    get_public_suffix_list()

    # 0. start the email server
    email_server, maildir = generate_email_server(tmpdir)
    email_server.start()
    time.sleep(3.0)

    # 1a. create a new session
    session_payload = {
        "user_id": 2,
        "user_agent": "Mozzarella Killerwhale",
        "expires": datetime.utcnow() + timedelta(hours=1),
        "ip_address": "1.1.1.1",
        "extra_info_json": {"pref_datasets_always_private": True},
        "pii_salt": "super-secret-salt",
        "reqid": 1,
    }
    session_token_info = actions.auth_session_new(
        session_payload, raiseonfail=True, override_authdb_path=test_authdb_url
    )

    # 1b. create a new user
    payload = {
        "full_name": "Test User",
        "email": "*****@*****.**",
        "password": "******",
        "reqid": 1,
        "pii_salt": "super-secret-salt",
    }
    user_created = actions.create_new_user(
        payload, raiseonfail=True, override_authdb_path=test_authdb_url
    )
    assert user_created["success"] is True
    assert user_created["user_email"] == "*****@*****.**"
    assert user_created["user_id"] == 4
    assert user_created["send_verification"] is True
    assert (
        "User account created. Please verify your email address to log in."
        in user_created["messages"]
    )

    token_key = Fernet.generate_key()

    # 2. generate a verification token and send them an email
    verify_token = tokens.generate_email_token(
        session_payload["ip_address"],
        session_payload["user_agent"],
        "*****@*****.**",
        session_token_info["session_token"],
        token_key,
    )

    # this uses the payload method of sending SMTP settings to the backend
    # function
    verification_email_info = actions.send_signup_verification_email(
        {
            "email_address": "*****@*****.**",
            "session_token": session_token_info["session_token"],
            "created_info": user_created,
            "server_name": "Authnzerver",
            "server_baseurl": "https://localhost/auth",
            "account_verify_url": "/users/verify",
            "verification_token": verify_token,
            "verification_expiry": 900,
            "emailuser": None,
            "emailpass": None,
            "emailserver": "localhost",
            "emailport": 9487,
            "emailsender": "Authnzerver <*****@*****.**>",
            "reqid": 1337,
            "pii_salt": "super-secret-salt",
        },
        raiseonfail=True,
        override_authdb_path=test_authdb_url,
    )
    assert verification_email_info["success"] is True
    assert verification_email_info["email_address"] == "*****@*****.**"

    # 3. check the mailbox to see if the email was received
    mailbox = Maildir(maildir)

    email_found = False

    for _, message in mailbox.items():

        if "Please verify your account sign up request" in message["Subject"]:

            email_found = True
            assert message["From"] == "Authnzerver <*****@*****.**>"
            assert message["To"] == "*****@*****.**"
            assert (
                "\n".join(textwrap.wrap(verify_token.decode()))
                in message.as_string()
            )
            break

    assert email_found is True

    # now verify that the token from the email contains the same info we
    # provided
    received_token_base64 = re.findall(
        r"enter this code:([\S\n]+)into the account verification",
        message.as_string(),
    )
    received_token_base64 = received_token_base64[0]
    received_token_base64 = received_token_base64.replace("\n", "")
    received_token_valid = tokens.verify_email_token(
        received_token_base64,
        session_payload["ip_address"],
        session_payload["user_agent"],
        session_token_info["session_token"],
        "*****@*****.**",
        token_key,
        match_returned_items=("ipa", "usa", "stk", "ema"),
    )
    assert received_token_valid is True

    # 4. set the user's email address as verified
    email_verified_info = actions.set_user_emailaddr_verified(
        {
            "email": "*****@*****.**",
            "reqid": 123,
            "pii_salt": "super-secret-salt",
        },
        raiseonfail=True,
        override_authdb_path=test_authdb_url,
    )

    assert email_verified_info["success"] is True
    assert email_verified_info["user_id"] == 4
    assert email_verified_info["is_active"] is True
    assert email_verified_info["user_role"] == "authenticated"

    # 5. send a password forgot email to the user

    # 5a. create a new session for the user first
    session_payload = {
        "user_id": 4,
        "user_agent": "Mozzarella Killerwhale",
        "expires": datetime.utcnow() + timedelta(hours=1),
        "ip_address": "1.1.1.1",
        "extra_info_json": {"pref_datasets_always_private": True},
        "pii_salt": "super-secret-salt",
        "reqid": 1,
    }
    session_token_info = actions.auth_session_new(
        session_payload, raiseonfail=True, override_authdb_path=test_authdb_url
    )

    # 5b. now send a forgot-password email
    forgotpass_token = tokens.generate_email_token(
        session_payload["ip_address"],
        session_payload["user_agent"],
        "*****@*****.**",
        session_token_info["session_token"],
        token_key,
    )

    # this uses the config object method of sending SMTP settings to the backend
    # function
    config_obj = SimpleNamespace()
    config_obj.emailuser = None
    config_obj.emailpass = None
    config_obj.emailserver = "localhost"
    config_obj.emailport = 9487
    config_obj.emailsender = "Authnzerver <*****@*****.**>"

    forgotpass_email_info = actions.send_forgotpass_verification_email(
        {
            "email_address": "*****@*****.**",
            "session_token": session_token_info["session_token"],
            "server_name": "Authnzerver",
            "server_baseurl": "https://localhost/auth",
            "password_forgot_url": "/password/reset-step1",
            "verification_token": forgotpass_token,
            "verification_expiry": 900,
            "reqid": 1337,
            "pii_salt": "super-secret-salt",
        },
        raiseonfail=True,
        override_authdb_path=test_authdb_url,
        config=config_obj,
    )
    assert forgotpass_email_info["success"] is True
    assert forgotpass_email_info["email_address"] == "*****@*****.**"

    # 6. check the mailbox to see if the forgot password email was received
    mailbox = Maildir(maildir)

    email_found = False

    for _, message in mailbox.items():

        if "Please verify your password reset request" in message["Subject"]:

            email_found = True
            assert message["From"] == "Authnzerver <*****@*****.**>"
            assert message["To"] == "*****@*****.**"
            assert (
                "\n".join(textwrap.wrap(forgotpass_token.decode()))
                in message.as_string()
            )
            break

    assert email_found is True

    # now verify that the token from the email contains the same info we
    # provided
    received_token_base64 = re.findall(
        r"enter this code:([\S\n]+)into the password reset",
        message.as_string(),
    )
    received_token_base64 = received_token_base64[0]
    received_token_base64 = received_token_base64.replace("\n", "")
    received_token_valid = tokens.verify_email_token(
        received_token_base64,
        session_payload["ip_address"],
        session_payload["user_agent"],
        session_token_info["session_token"],
        "*****@*****.**",
        token_key,
        match_returned_items=("ipa", "usa", "stk", "ema"),
    )
    assert received_token_valid is True

    #
    # clean up
    #

    email_server.stop()