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
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()
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()