Exemple #1
0
def find_attendance_messages(server, mail, password):
    mailbox = MailBox(server)
    mailbox.login(mail, password, initial_folder='inbox')
    f = open('attendance_messages.txt.', 'w')
    counter = 0
    for message in mailbox.fetch(Q(text='Attendance', date=date.today())):
        f.write(message.text)
        counter += 1
        f.write(
            '=====================================================================================\n'
        )
    f.write(f'\n{counter} URLS were generated.')
    f.close()
    mailbox.logout()
Exemple #2
0
def parse_email(imap, u, pw):
    # get list of email subjects from INBOX folder - equivalent verbose version
    mailbox = MailBox(imap)
    mailbox.login(
        u, pw, initial_folder='INBOX')  # or mailbox.folder.set instead 3d arg

    # for debugging, you can set mark_seen=False
    # texts = [msg.html for msg in mailbox.fetch(AND(all=True),mark_seen=False)]
    # sometimes html, sometimes text
    h = [msg.html for msg in mailbox.fetch(AND(all=True), mark_seen=False)]
    h += [msg.text for msg in mailbox.fetch(AND(all=True), mark_seen=False)]
    #print(h) # debugging
    mailbox.logout()
    return h
Exemple #3
0
def test_mailbox_conn(email_addr: str, password: str) -> bool:
    try:
        logger.info("Connecting to mailbox..")
        mail_provider = get_imap_svr(email_addr)
        mailbox = MailBox(mail_provider)
        mailbox.login(email_addr, password)
        conn_status = True
        logger.info("Connection successful")
        mailbox.logout()
    except imaplib.IMAP4.error:
        conn_status = False
        logger.error("IMAP4 Error: Connection failed!")
    except gaierror:
        conn_status = False
        logger.error("GAIError: Connection failed")
    return conn_status
Exemple #4
0
def CheckMail():
  config = LoadConfig()
  ConfirmArchive(config)
  mailbox = MailBox(config['imap_ssl_host'], config['imap_ssl_port'])
  try:
    mailbox.login(config['email_address'], config['email_password'], initial_folder='Inbox')
  except:
    i=0
    while i < config['max_retries']:
      print("Failed to log in to mailbox to retrieve mail. Retrying...")
      print("Retry %d of max %d" % (i, config['max_retries']))
      sleep(1)
      try:
        mailbox.login(config['email_address'], config['email_password'], initial_folder='Inbox')
        break
      except:
        i=i+1
  
  for message in mailbox.fetch(Q(seen=False)):
    if config['allowed_senders']:
      sender = message.from_
      if sender not in config['allowed_senders']:
        continue
    subject = message.subject
    body = message.text
    video_url = body.strip()
    try:
      with youtube_dl.YoutubeDL(config['youtube-dl_options']) as ydl:
        ydl.download([video_url])
    except Exception as e:
      print("Reporting error to user via email.")
      ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
      error = ansi_escape.sub('', str(e))
      s= smtplib.SMTP(host=config['smtp_host'], port=config['smtp_port'])
      s.starttls()
      s.login(config['email_address'], config['email_password'])

      msg = MIMEMultipart()
      msg['From']=config['email_address']
      msg['To']=sender
      msg['Subject']="Re: %s" % subject
      msg.attach(MIMEText(error, 'plain'))
      s.send_message(msg)
      del msg
      s.quit()

  mailbox.logout()
Exemple #5
0
    def fetchBox(self, folder=None, Query=None):
        '''Get list of emails from Mailbox server
        Folder-> Specific folder to extract emails
        Query-> Filter Emails from a Query
        :return List of mail objects'''
        if folder is None:
            folder = 'INBOX'
        if Query is None:
            Query = Q(all=True)
        mailbox = MailBox(self.imap_server, self.imap_port)
        mailbox.login(self.username, self.password, initial_folder=folder)

        message_list = []
        for mail in mailbox.fetch(Query):
            message_list.append(mail)
        mailbox.logout()
        return message_list
Exemple #6
0
class EmailServer:
    def __init__(self,
                 host: str,
                 account: str,
                 password: str,
                 folder: str = '/'):
        """
        :param folder: name of folder prepended with /, ie. '/foobar'
        """
        assert '/' in folder
        print(f"Connecting to {account} at {host}...")
        self.server = MailBox(host)
        self.server.login(account, password, initial_folder='INBOX' + folder)

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.logout()

    def logout(self):
        self.server.logout()

    def fetch_emails_headers(self) -> List[Email]:
        """
        :return: all emails headers on server
        """
        results: List[Email] = []
        for msg in self.server.fetch(criteria='ALL', headers_only=True):
            email = Email(int(msg.uid), msg)
            results.append(email)
        return results

    def fetch_emails_bodies(self, email_uids: List[EmailID]) -> List[Email]:
        """
        :return: full emails from the email_uids list
        """
        if len(email_uids) == 0:
            return []
        results: List[Email] = []
        uids = 'UID ' + ",".join(map(str, email_uids))

        for msg in self.server.fetch(criteria=uids):
            email = Email(int(msg.uid), msg)
            results.append(email)
        return results
 def test_connection(self):
     for test_mailbox_name in test_mailbox_name_set:
         config = get_test_mailbox_config(test_mailbox_name)
         mailbox = MailBox(config['host'])
         self.assertIs(type(mailbox), MailBox)
         login_result = mailbox.login(config['email'], config['password'])
         self.assertEqual(login_result[0], 'OK')
         logout_result = mailbox.logout()
         self.assertEqual(logout_result[0], 'BYE')
Exemple #8
0
def fetch_mails():
    mailbox = MailBox(settings.inbox_url)
    mailbox.login(settings.inbox, settings.inbox_pass)
    msgs = mailbox.fetch(AND(seen=False))
    feeds = []
    for msg in msgs:
        feed = {
            'title': msg.subject,
            "description": msg.html,
            'author': msg.from_,
            'pub_date': msg.date,
            'guid': msg.uid,
            'to': msg.headers['envelope-to'][0]
        }
        feeds.append(feed)
        logger.info(f"New message retrieved for {msg.headers['envelope-to']}")
    if len(feeds) == 0:
        logger.info("No new messages.")
    mailbox.logout()
    return feeds
Exemple #9
0
    def fetchBox(self, folder=None, Query=None):

        if folder is None:
            folder = 'INBOX'

        if Query is None:
            Query = Q(all=True)

        server = 'imap.' + self.username.split("@")[1]
        mailbox = MailBox(server)
        mailbox.login(
            self.username, self.password,
            initial_folder=folder)  # or mailbox.folder.set instead 3d arg

        message_list = []
        for mail in mailbox.fetch(Query):
            message_list.append(mail)

        return message_list

        mailbox.logout()
 def get_new_emails(self):
     ''' Checks for new email. If there is new email, it will return the tuple (sender, subject)'''
     # I suppose one email will have been received, otherwise just pick the last email received
     try:
         mailbox = MailBox(self._email_server)
         mailbox.login(self._email_address,
                       self._email_password,
                       initial_folder='INBOX')
         received_emails = False
         subject = None
         sender = None
         for msg in mailbox.fetch(Q(seen=False)):
             received_emails = True
             subject = msg.subject.lower()
             sender = msg.from_
             #print(subject)
         mailbox.logout()
     except Exception:
         print("Some error occured while checking for new emails...")
         return (None, None)
     if received_emails:
         return (sender, subject)
     else:
         return (None, None)
Exemple #11
0
 def test_connection(self):
     # simple
     for test_mailbox_name in TEST_MAILBOX_NAME_SET:
         config = get_test_mailbox_config(test_mailbox_name)
         mailbox = MailBox(config['host'])
         self.assertIs(type(mailbox), MailBox)
         login_result = mailbox.login(config['email'], config['password'])
         self.assertEqual(login_result.login_result[0], 'OK')
         logout_result = mailbox.logout()
         self.assertEqual(logout_result[0], 'BYE')
     # with
     for test_mailbox_name in TEST_MAILBOX_NAME_SET:
         config = get_test_mailbox_config(test_mailbox_name)
         with MailBox(config['host']).login(config['email'], config['password']) as mailbox:
             self.assertIs(type(mailbox), MailBox)
             self.assertEqual(mailbox.login_result[0], 'OK')
Exemple #12
0
mailbox = MailBox("imap.gmail.com", 993)
mailbox.login(EMAIL_ADDRESS, EMAIL_PASSWORD, initial_folder="INBOX")

# limit : 최대 메일 갯수
# reverse : True 일 경우 최근 메일부터, False 일 경우 과거 메일부터
for msg in mailbox.fetch(limit=1, reverse=True):
    print("제목", msg.subject)
    print("발신자", msg.from_)
    print("수신자", msg.to)
    #print("참조자", msg.cc)
    #print("비밀참조자", msg.bcc)
    print("날짜", msg.date)
    print("본문", msg.text)
    print("HTML 메시지", msg.html)
    print("=" * 100)
    # 첨부 파일 없으면 list len[] 0 값
    print(msg.attachments)
    # 첨부 파일
    for att in msg.attachments:
        print("첨부파일 이름", att.filename)
        print("타입", att.content_type)
        print("크기", att.size)

        # 파일 다운로드
        with open("download_" + att.filename, "wb") as f:
            f.write(att.payload)
            print("첨부 파일 {} 다운로드 완료".format(att.filename))

mailbox.logout()
Exemple #13
0
usuario = '*****@*****.**'
senha = '   123'

meu_email = MailBox('imap.gmail.com').login(usuario, senha)

#Pegar email que foram enviados por um remetente especifico

listaEmails = meu_email.fetch(AND(from_='*****@*****.**'))

print(f'Existe quantos e-mails com esse remetente ? {len(list(listaEmails))}')

#Pegar e-mail sobre o assunto ...
listaEmails2 = meu_email.fetch(AND(subject='Alerta'))

for email in listaEmails2:
    print(email.subject)
    print(email.text)

#Pegando anexo
listaEmails3 = meu_email.fetch(AND(from_='*****@*****.**'))
for email in listaEmails3:
    if len(email.attachments) > 0:
        for anexo in email.attachments:
            if 'Relatorio.pdf' in anexo.filename:
                informacoes_anexo = anexo.payload
                with open('CriandoArquivo', 'wb') as arquivo:
                    arquivo.write(informacoes_anexo)

meu_email.logout()
Exemple #14
0
async def updatemails(ctx):
    """Check for new staff applications and ban appeals"""
    if "Staff" not in str(ctx.author.roles):
        await ctx.respond(":warning: Insufficient permission.", ephemeral=True)
        return

    channel = bot.get_channel(564783779474833431)

    # Connect to imap
    mailbox = MailBox(config.IMAP_HOST).login(config.IMAP_NAME,
                                              config.IMAP_PASS, "INBOX")

    # Cycle through inbox
    for mail in mailbox.fetch():

        # Try to split the email into the form's parts
        try:
            content = mail.text.split("§§")
        except:
            pass

        # Switch submission types

        # Staff application
        if len(content) == 11:
            embed = discord.Embed(
                title=content[0],
                description=f"{content[1]} years old, {content[2]}")
            embed.add_field(name="Minecraft username",
                            value=f"`{content[3]}`",
                            inline=True)
            embed.add_field(name="Discord#Tag",
                            value=f"`{content[4]}`",
                            inline=True)
            embed.add_field(name="E-mail",
                            value=f"`{content[5]}`",
                            inline=True)
            embed.add_field(name="Do you have experience as staff?",
                            value=content[6],
                            inline=False)
            embed.add_field(name="Why do you want to be staff?",
                            value=content[7],
                            inline=False)
            embed.add_field(
                name="Why should you be chosen instead of someone else?",
                value=content[8],
                inline=False)
            embed.add_field(
                name="Do you have any issues with the current staff team?",
                value=content[9],
                inline=False)
            embed.add_field(name="How many hours per week can you contribute?",
                            value=content[10],
                            inline=False)
            content_length = len(content[6].split()) + len(
                content[7].split()) + len(content[8].split())
            embed.set_footer(text=f"{content_length} words")
            if content_length > 50:
                msg = await channel.send(
                    content="**STAFF APPLICATION** @staff", embed=embed)
            else:
                msg = await channel.send(content="**STAFF APPLICATION**",
                                         embed=embed)
            await msg.add_reaction("<:vote_yes:601899059417972737>")
            await msg.add_reaction("<:vote_no:601898704231989259>")
            await msg.create_thread(name=f"{content[0]}\'s Staff Application")

        # Ban appeal
        elif len(content) == 4:
            embed = discord.Embed(title="Ban Appeal")
            embed.add_field(name="Minecraft username",
                            value=f"`{content[0]}`",
                            inline=True)
            embed.add_field(name="Contact",
                            value=f"`{content[1]}`",
                            inline=True)
            embed.add_field(name="More about your ban",
                            value=content[2],
                            inline=False)
            embed.add_field(name="Why should you be unbanned?",
                            value=content[3],
                            inline=False)
            content_length = len(content[2].split()) + len(content[3].split())
            embed.set_footer(text="{} words".format(content_length))
            if content_length > 50:
                msg = await channel.send(content="@staff", embed=embed)
            else:
                msg = await channel.send(embed=embed)
            await msg.add_reaction("<:vote_yes:601899059417972737>")
            await msg.add_reaction("<:vote_no:601898704231989259>")
            await msg.create_thread(name=f"{content[0]}\'s Ban Appeal")

        # Unknown
        else:
            embed = discord.Embed(
                title="Unknown email",
                description=
                f"I've received an email that doesn't match the layout of any form:\n\n{mail.text}"
            )
            await channel.send(embed=embed)

        # Delete the email and log out
        mailbox.delete(mail.uid)
    mailbox.logout()
Exemple #15
0
def check_phish(mid):
    phishing_mails = []

    # Retrieves the email address instance
    logger.info("Click-to-check entered..")

    owner_id = get_owner_id_from_email_id(mid)
    if current_user.is_anonymous or not owner_id == current_user.get_id():
        logger.warning("Anonymous or unauthorized user attempting"\
        " phish check of address ID {}!".format(mid))
        return redirect(url_for('index'))

    mailaddr = get_email_address_by_email_id(mid)

    # Redirects back to page if selected email is inactive
    if mailaddr.get_active_status() == False:
        logger.warning("Redirecting.. User selected inactive email address %s"\
        , mailaddr.get_email_address())
        flash("Email is inactive!", 'error')
        return redirect(url_for('dash_email'))

    logger.info("Mailbox selected is %s", mailaddr.get_email_address())

    try:
        # Logs in to mailbox by retrieving the corresponding IMAP server
        imap_svr = get_imap_svr(mailaddr.get_email_address())
        logger.info("Retrieving IMAP server: %s", imap_svr)
        mailbox = MailBox(imap_svr)
        logger.info("Attempting connection..")
        mailbox.login(mailaddr.get_email_address()\
        , mailaddr.get_decrypted_email_password())
        logger.info("Connected to mailbox %s", mailaddr.get_email_address())
    except ConnectionRefusedError:
        logger.error("Unable to connect to mailbox for %s",
                     mailaddr.get_email_address())
        flash("Unable to connect to mailbox, please update your password!",
              'error')
        return redirect(url_for('dash_email'))

    # Retrieves date last updated
    # if new email address is added column is empty
    # sets last_updated to today - 1 day so that mails in the last 24 hours
    # are checked
    last_updated = mailaddr.get_last_updated() \
    if mailaddr.get_last_updated() else datetime.today() - timedelta(days=1)

    # Selects mailbox to Inbox only
    mailbox.folder.set("INBOX")
    logger.info("Fetching mails..")

    # Sets a check criteria so that
    # only mails newer than last_updated and unread mails are checked
    check_criteria = AND(date_gte=last_updated.date(), seen=False)
    """
    FOR DEMO USE
    """
    # Test code to intentionally pull retrieve backdated emails for demo purposes
    # last_updated = datetime(2020, 12,17, 0, 0, 0)
    # check_criteria = AND(date_gte=[date(2020, 12, 17)], seen=False)

    # Fetch mails from mailbox based on criteria, does not "read" the mail
    # and retrieves in bulk for faster performance at higher computing cost
    all_mails = mailbox.fetch(check_criteria,
                              reverse=True,
                              mark_seen=False,
                              bulk=True)

    logger.info("Mails fetched..")

    # Iterates through the mails that are not sent from the sender's address
    # Creates a EmailData instance for each mail to generate features based on
    # preprocessing logic, passes it into the model - if predict returns 1 it is a detected phish
    # appends the detected mail into a list of Mail (phishing_mails)
    # The purpose of Mail class is for easier display - the values are pulled from the
    # imap_tool's Mail item instead of our EmailData.
    # Inserts all phishing mails to the database
    data = {
        'total_count': 0,
        'detection_count': 0,
        'check_time': datetime.now().strftime('%d-%m-%Y, %H:%M')
    }

    mail_check_count = 0

    for msg in all_mails:
        try:
            sender = msg.from_
        except HeaderParseError:
            # Exception happens when a msg.from_ is malformed resulting in
            # unparseable values. Automatically assume phishing email and add to record.
            # Denote Sender as 'INVALID_SENDER'
            logger.error("HeaderParseError, unparseable msg.from_. \
            Setting sender as INVALID_SENDER")
            sender = 'INVALID_SENDER'
        if (check_valid_time(last_updated, msg.date)) \
        and check_valid_sender(sender, mailaddr.get_email_address()):
            data['total_count'] += 1
            mail_check_count += 1
            mail_item = EmailData(msg.subject, sender, msg.attachments\
            , (msg.text + msg.html), msg.headers)
            mail_item.generate_features()
            result = model.predict(mail_item.repr_in_arr())
            logger.info("Checking mail: %s -- Result: %s"\
            , mail_item.get_subject(), result)
            if result == 1:
                logger.info("Phishing mail detected, subject: %s", msg.subject)

                mail_exist = check_p_mail_exist(mailaddr.get_email_id()\
                , msg.subject, mail_item.get_content())

                if not mail_exist:
                    phishing_mails.append(Mail(sender, \
                    msg.date.astimezone(timezone('Asia/Singapore')), msg.subject))
                    data['detection_count'] += 1
                    detected_mail = PhishingEmail( \
                    sender_address = sender, \
                    subject = msg.subject, \
                    content = mail_item.get_content(), \
                    created_at = datetime.now(), \
                    receiver_id = mailaddr.get_email_id()
                    )
                    db.session.add(detected_mail)

    # Updates last updated to current time
    mailaddr.set_last_updated(datetime.now())
    logger.info("Updating mailbox last updated from %s to %s",\
    last_updated.strftime("%d-%m-%Y, %H:%M:%S"), datetime.now())

    mailaddr.set_phishing_mail_detected(data['detection_count'])
    mailaddr.set_total_mails_checked(mail_check_count)
    db.session.commit()
    logger.info("Finished checking mails.. logging out")
    mailbox.logout()
    send_phish_check_notice(mailaddr.get_email_address(), phishing_mails)

    mailaddr = get_email_address_by_email_id(mid)
    mail_address = mailaddr.get_email_address()

    # return redirect(url_for('dashboard'))
    return render_template('dashboard/detection_results.html', \
    phishing_mails = phishing_mails, data=data, mail_address = mail_address)
Exemple #16
0
def check_all_mailboxes() -> None:
    logger.info("Routine task: checking all active mailboxes..")

    all_active_mailboxes = db.session.query(EmailAddress)\
    .filter(EmailAddress.active == True)\
    .all()

    if all_active_mailboxes:
        logger.info("Checking through all active mailboxes")
        for mailaddr in all_active_mailboxes:
            try:
                imap_svr = get_imap_svr(mailaddr.get_email_address())

                logger.info("Email: %s -- IMAP: %s"\
                , mailaddr.get_email_address(), imap_svr)

                mailbox = MailBox(imap_svr)
                mailbox.login(mailaddr.get_email_address()\
                , mailaddr.get_decrypted_email_password())

                logger.info("Successfully logged in via IMAP")
            except ConnectionRefusedError:
                logger.error("Unable to connect to mailbox for %s"\
                , mailaddr.get_email_address())
                continue

            last_updated = mailaddr.get_last_updated() \
            if mailaddr.get_last_updated() else datetime.today() - timedelta(days=1)

            mailbox.folder.set("INBOX")
            logger.info("Fetching mails..")

            check_criteria = AND(date_gte=last_updated.date(), seen=False)
            all_mails = mailbox.fetch(check_criteria, reverse=True\
            , mark_seen=False, bulk=True)

            logger.info("Mails fetched..")

            detection_count = 0
            mail_check_count = 0
            phishing_mails_detected = []

            for mail in all_mails:
                try:
                    sender = mail.from_
                except HeaderParseError:
                    logger.error("HeaderParseError, unparseable msg.from_."\
                    " Setting sender as INVALID_SENDER")
                    sender = 'INVALID_SENDER'

                if (check_valid_time(last_updated, mail.date))\
                and check_valid_sender(sender, mailaddr.get_email_address()):

                    mail_check_count += 1

                    mail_item = EmailData(mail.subject, sender, mail.attachments\
                    , (mail.text + mail.html), mail.headers)
                    mail_item.generate_features()

                    result = model.predict(mail_item.repr_in_arr())
                    logger.info("Checking mail: %s -- Result: %s"\
                    , mail_item.get_subject(), result)

                    if result == 1:
                        logger.info("Phishing mail detected, subject: %s"\
                        , mail.subject)

                        mail_exist = check_p_mail_exist(mailaddr.get_email_id()\
                        , mail.subject, mail_item.get_content())

                        if not mail_exist:
                            phishing_mails_detected.append(Mail(sender, \
                            mail.date.astimezone(timezone('Asia/Singapore')), mail.subject))
                            detection_count += 1
                            detected_mail = PhishingEmail( \
                            sender_address = sender, \
                            subject = mail.subject, \
                            content = mail_item.get_content(), \
                            created_at = datetime.now(), \
                            receiver_id = mailaddr.get_email_id()
                            )
                            db.session.add(detected_mail)

            logger.info("Updating mailbox last updated from %s to %s",\
             last_updated.strftime("%d-%m-%Y %H:%M:%S"), datetime.now())
            mailaddr.set_last_updated(datetime.now())
            mailaddr.set_phishing_mail_detected(detection_count)
            mailaddr.set_total_mails_checked(mail_check_count)
            logger.info("Finished checking mails.. logging out")
            mailbox.logout()
            db.session.commit()
            if phishing_mails_detected:
                logger.info(
                    "Phishing emails detected in automated scan, sending mail!"
                )
                send_phish_check_notice_context(mailaddr.get_email_address()\
                , phishing_mails_detected, app)
            else:
                logger.info(
                    "No phishing emails detected in automated scan, moving to next.."
                )