Exemple #1
0
def main(inargs=None):
    """Find moderatorless groups, make a nice table and send it to drift"""
    try:
        import argparse
    except ImportError:
        from Cerebrum.extlib import argparse
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-r',
                        '--recipient',
                        dest='recipient',
                        default=None,
                        help='Recipient of the report')
    logutils.options.install_subparser(parser)

    argutils.add_commit_args(parser, default=False)
    args = parser.parse_args(inargs)
    logutils.autoconf('cronjob', args)

    logger.info('START %s', parser.prog)
    logger.info('Extracting adminless groups')
    abandoned_manual_groups = get_abandoned_manual_groups()
    logger.info('Creating table')
    table = make_table(abandoned_manual_groups)
    args = parser.parse_args(inargs)
    if args.recipient:
        logger.info('Sending email to %s', args.recipient)
        email.sendmail(args.recipient, '*****@*****.**', get_title(),
                       table)
    else:
        logger.info('No email provided')
    logger.info('DONE %s', parser.prog)
Exemple #2
0
def _send_mail(mail_to, mail_from, subject, body,
               mail_cc=None, debug_enabled=False):
    if debug_enabled:
        logger.debug("Sending mail to %s. Subject: %s", mail_to, subject)
        # logger.debug("Body: %s" % body)
        return True

    try:
        sendmail(
            toaddr=mail_to,
            fromaddr=mail_from,
            subject=subject,
            body=body,
            cc=mail_cc,
            debug=debug_enabled)
    except smtplib.SMTPRecipientsRefused as e:
        failed_recipients = e.recipients
        for mail, condition in failed_recipients.iteritems():
            logger.exception("Failed when notifying %s (%s): %s",
                             mail_to, mail, condition)
        return False
    except Exception as e:
        logger.error("Error when notifying %s: %s" % (mail_to, e))
        return False
    return True
Exemple #3
0
 def mail_warning(self, person, account, reason):
     """Warn a person by sending an e-mail to all its accounts."""
     msg = '\n'.join([
         "Someone has tried to recover the password for your account: %s."
         % account.account_name,
         "This has failed, due to the following reason:", '',
         " %s" % reason, '',
         "If this was not you, please contact your local IT-department as "
         "soon as possible.", '',
         "-- ", "%s" % self.email_signature])
     account2 = Factory.get('Account')(self.db)
     for row in person.get_accounts():
         account2.clear()
         account2.find(row['account_id'])
         try:
             primary = account2.get_primary_mailaddress()
         except Errors.NotFoundError as e:
             logger.error("Couldn't warn user %r, no primary mail: %s",
                          account.account_name, e)
             continue
         logger.debug("Emailing user %r (%r)",
                      account2.account_name, account2.entity_id)
         try:
             sendmail(primary, self.email_from, self.email_subject, msg)
         except Exception as e:
             logger.error("Error for %r from sendmail: %s", primary, e)
 def mail_warning(self, person, account, reason):
     """Warn a person by sending an e-mail to all its accounts."""
     msg = '\n'.join([
         "Someone has tried to recover the password for your account: %s." %
         account.account_name,
         "This has failed, due to the following reason:", '',
         " %s" % reason, '',
         "If this was not you, please contact your local IT-department as "
         "soon as possible.", '', "-- ",
         "%s" % self.email_signature
     ])
     account2 = Factory.get('Account')(self.db)
     for row in person.get_accounts():
         account2.clear()
         account2.find(row['account_id'])
         try:
             primary = account2.get_primary_mailaddress()
         except Errors.NotFoundError as e:
             logger.error("Couldn't warn user %r, no primary mail: %s",
                          account.account_name, e)
             continue
         logger.debug("Emailing user %r (%r)", account2.account_name,
                      account2.entity_id)
         try:
             sendmail(primary, self.email_from, self.email_subject, msg)
         except Exception as e:
             logger.error("Error for %r from sendmail: %s", primary, e)
def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'hsdf:', [
            'help', 'summary', 'detail', 'min=', 'max=', 'mail-to=',
            'mail-from=', 'file='
        ])
    except getopt.GetoptError:
        usage("Argument error!", 1)

    detail = False
    minimum = 1
    maxmum = None
    report_type = 'screen'
    outputstream = sys.stdout
    mail_to = None
    mail_from = None
    persons = 'person_id'

    for opt, val in opts:
        if opt in ('-h', '--help'):
            usage()
        elif opt in ('-s', '--summary'):
            pass
        elif opt in ('-d', '--detail'):
            detail = True
        elif opt in ('--min'):
            minimum = int(val)
            if minimum < 0:
                usage(
                    "Error: the value of parameter --min should be at least 1",
                    2)
        elif opt in ('--max'):
            maxmum = int(val)
            if maxmum < 0:
                usage(
                    "Error: the value of parameter --max should be at least 1",
                    3)
        elif opt in ('-f', '--file'):
            report_type = 'file'
            outputstream = open(val, 'w')
            outputstream.write(
                "==== Results of checking active accounts in Cerebrum ====\n")
            outputstream.write("person_id\tNr_accounts\taccount_names\n")
        elif opt in ('--mail-to'):
            report_type = 'mail'
            mail_to = val
        elif opt in ('--mail-from'):
            mail_from = val
        else:
            usage("Error: Unknown parameter '%s'" % opt, 4)

    persons += checkACaccount(minimum, maxmum, detail, report_type,
                              outputstream)

    if mail_to:
        count = persons.count("\n")
        subject = "Warning: these following %s persons have more than %s active accounts." % (
            count, minimum)
        sendmail(mail_to, mail_from, subject, persons)
def process(output, mail):
    db = Factory.get('Database')()
    co = Factory.get('Constants')(db)
    ac = Factory.get('Account')(db)
    pe = Factory.get('Person')(db)

    logger.info("Invoice stats started")
    logger.debug("Using database: %s", cereconf.CEREBRUM_DATABASE_NAME)
    last_event = None
    try:
        last_event = db.query_1('''
            SELECT tstamp FROM [:table schema=cerebrum name=change_log]
            ORDER BY tstamp DESC
            LIMIT 1''')
    except Errors.NotFoundError:
        pass
    logger.debug("Last event found from db: %s", last_event)

    # Find active persons:
    affs = []
    for a in ('STUDENT', 'ANSATT', 'TILKNYTTET', 'ELEV', 'MANUELL', 'PROJECT'):
        try:
            af = co.PersonAffiliation(a)
            int(af)
            affs.append(af)
        except Errors.NotFoundError:
            pass
    logger.debug("Active affiliations: %s" % ', '.join(text_type(a) for a in
                                                       affs))
    all_affiliated = set(r['person_id'] for r in pe.list_affiliations(
                                affiliation=affs,
                                include_deleted=False))
    logger.debug("Found %d persons with active aff", len(all_affiliated))

    # Find active accounts:
    quars = set(r['entity_id'] for r in
                ac.list_entity_quarantines(only_active=True,
                                           entity_types=co.entity_account))
    logger.debug("Found %d quarantined accounts", len(quars))

    active_accounts = set(r['account_id'] for r in
                          ac.search(owner_type=co.entity_person) if
                          (r['owner_id'] in all_affiliated and r['account_id']
                           not in quars))
    logger.info("Found %d accounts for the active persons",
                len(active_accounts))

    if output:
        csvw = csv.writer(output)
        csvw.writerow((time.strftime('%Y-%m-%d'),
                       cereconf.CEREBRUM_DATABASE_NAME,
                       len(active_accounts),
                       last_event,
                       ))
    if mail:
        body = """Found {} active accounts in {} from {}""".format(
            len(active_accounts), cereconf.CEREBRUM_DATABASE_NAME, last_event)
        sendmail(mail, mail_from, mail_subject, body)
    logger.info("Invoice stats finished")
Exemple #7
0
def process(output, mail):
    db = Factory.get('Database')()
    co = Factory.get('Constants')(db)
    ac = Factory.get('Account')(db)
    pe = Factory.get('Person')(db)

    logger.info("Invoice stats started")
    logger.debug("Using database: %s", cereconf.CEREBRUM_DATABASE_NAME)
    last_event = None
    try:
        last_event = db.query_1('''
            SELECT tstamp FROM [:table schema=cerebrum name=change_log]
            ORDER BY tstamp DESC
            LIMIT 1''')
    except Errors.NotFoundError:
        pass
    logger.debug("Last event found from db: %s", last_event)

    # Find active persons:
    affs = []
    for a in ('STUDENT', 'ANSATT', 'TILKNYTTET', 'ELEV', 'MANUELL', 'PROJECT'):
        try:
            af = co.PersonAffiliation(a)
            int(af)
            affs.append(af)
        except Errors.NotFoundError:
            pass
    logger.debug("Active affiliations: %s" %
                 ', '.join(text_type(a) for a in affs))
    all_affiliated = set(
        r['person_id']
        for r in pe.list_affiliations(affiliation=affs, include_deleted=False))
    logger.debug("Found %d persons with active aff", len(all_affiliated))

    # Find active accounts:
    quars = set(r['entity_id'] for r in ac.list_entity_quarantines(
        only_active=True, entity_types=co.entity_account))
    logger.debug("Found %d quarantined accounts", len(quars))

    active_accounts = set(
        r['account_id'] for r in ac.search(owner_type=co.entity_person)
        if (r['owner_id'] in all_affiliated and r['account_id'] not in quars))
    logger.info("Found %d accounts for the active persons",
                len(active_accounts))

    if output:
        csvw = csv.writer(output)
        csvw.writerow((
            time.strftime('%Y-%m-%d'),
            cereconf.CEREBRUM_DATABASE_NAME,
            len(active_accounts),
            last_event,
        ))
    if mail:
        body = """Found {} active accounts in {} from {}""".format(
            len(active_accounts), cereconf.CEREBRUM_DATABASE_NAME, last_event)
        sendmail(mail, mail_from, mail_subject, body)
    logger.info("Invoice stats finished")
def handle_person(database, source_system, affiliations, send_notifications,
                  email_config, data):
    pe = Factory.get('Person')(database)
    ac = Factory.get('Account')(database)
    et = EmailTarget(database)
    ef = EmailForward(database)
    ed = EmailDomain(database)

    if (data.get('resourceType') == 'persons' and
            'affiliation' in data.get(
                'urn:ietf:params:event:SCIM:modify', {}).get(
                    'attributes', [])):
        ident = int(data.get('sub').split('/')[-1])

        if not pe.list_affiliations(
                person_id=ident,
                source_system=source_system,
                affiliation=affiliations):
            return

        pe.clear()
        pe.find(ident)

        removed_forwards = defaultdict(list)
        for account_id in map(lambda x: x['account_id'],
                              pe.get_accounts(
                                  filter_expired=False)):
            try:
                et.clear()
                et.find_by_target_entity(account_id)
            except Errors.NotFoundError:
                continue
            ef.clear()
            ef.find(et.entity_id)
            for forward in map(lambda x: x['forward_to'],
                               ef.get_forward()):
                try:
                    ed.clear()
                    ed.find_by_domain(forward.split('@')[-1])
                except Errors.NotFoundError:
                    ac.clear()
                    ac.find(account_id)
                    ef.delete_forward(forward)
                    removed_forwards[ac.get_primary_mailaddress()
                                     ].append(forward)
                    logger.info(
                        'Deleted forward {} from {}'.format(
                            forward, ac.account_name))
        if send_notifications:
            for k, v in removed_forwards.items():
                sendmail(
                    toaddr=k,
                    fromaddr=email_config.sender,
                    subject=email_config.subject,
                    body=email_config.body_template.format('\n'.join(v)))
    database.commit()
def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'hsdf:',
                                   ['help', 'summary', 'detail',
                                    'min=', 'max=',
                                    'mail-to=', 'mail-from=',
                                    'file='])
    except getopt.GetoptError:
        usage("Argument error!", 1)

    detail = False
    minimum = 1  
    maxmum = None
    report_type = 'screen'
    outputstream = sys.stdout
    mail_to = None
    mail_from = None
    persons = 'person_id'
    
    for opt, val in opts:
        if opt in ('-h', '--help'):
            usage()
        elif opt in ('-s', '--summary'):
            pass
        elif opt in ('-d', '--detail'):
            detail = True
        elif opt in ('--min'):
            minimum = int(val)
            if minimum < 0:
                usage("Error: the value of parameter --min should be at least 1", 2)
        elif opt in ('--max'):
            maxmum = int(val)
            if maxmum < 0:
                usage("Error: the value of parameter --max should be at least 1", 3)
        elif opt in ('-f', '--file'):
            report_type = 'file'
            outputstream = open(val, 'w')
            outputstream.write("==== Results of checking active accounts in Cerebrum ====\n")
            outputstream.write("person_id\tNr_accounts\taccount_names\n")
        elif opt in ('--mail-to'):
            report_type = 'mail'
            mail_to = val
        elif opt in ('--mail-from'):
            mail_from = val
        else:
            usage("Error: Unknown parameter '%s'" % opt, 4)

    persons += checkACaccount(minimum,maxmum,detail,report_type,outputstream)
          
    if mail_to:
        count = persons.count("\n")
        subject = "Warning: these following %s persons have more than %s active accounts." % (count,minimum)
        sendmail(mail_to, mail_from, subject, persons)
Exemple #10
0
def send_report(report):
    """Send email with import errors."""
    recipient = cereconf.TELEFONIERRORS_RECEIVER
    sender = cereconf.SYSX_EMAIL_NOTFICATION_SENDER
    subject = 'Import telefoni errors from Cerebrum {0}'.format(
        datetime.date.today().strftime('%Y%m%d'))
    sendmail(
        toaddr=recipient,
        fromaddr=sender,
        subject=subject,
        body=report,
    )
Exemple #11
0
def send_notify_email(new_cere_ous, to_email_addrs):
    """
    Sends information about OUs to a set of mail_addresses.

    :type new_cere_ous: dict
    :param new_cere_ous:
        *ou_id* -> *sko* mapping, containing the OUs that has been added to the
        database.

    :type to_email_addrs: list
    :param to_email_addrs:
        List of email addresses that should be notified about the new OUs.
    """

    if len(new_cere_ous) < 1:
        logger.warn('No new OUs to send notification about')
        return

    ous = OU_class(db)

    # Set up email
    sender = '*****@*****.**'
    subject = 'New OUs added to Cerebrum'
    body = '%(num)d OUs added to Cerebrum on %(time)s\n\n' % {
        'num': len(new_cere_ous),
        'time': mx.DateTime.now().strftime(),
    }

    for ou_id in new_cere_ous.keys():
        names = ous.search_name_with_language(entity_id=ou_id,
                                              name_language=co.language_nb,
                                              name_variant=co.ou_name)

        body += '  Entity Id: %d\n' % ou_id
        body += '  Stedkode:  %s\n' % new_cere_ous[ou_id]
        if len(names):
            body += '  Name     : %s\n\n' % names[0]['name']

    for to_email in to_email_addrs:
        try:
            sendmail(to_email, sender, subject, body)

        except SMTPRecipientsRefused as ref:
            for email, cond in ref.recipients.iteritems():
                logger.info("Failed to notify '%s': %s", email, cond)
            continue

        except SMTPException as e:
            logger.warning("Failed to notify '%s': %s", to_email, e)
            continue

        logger.info("OUs added, '%s' notified", to_email)
def email_report(to_address, from_address, report):
    """Send the report by email."""
    import smtplib
    try:
        sendmail(to_address,
                 from_address,
                 'ePhorte role report',
                 report,
                 cc=None)
    except smtplib.SMTPRecipientsRefused, e:
        failed_recipients = e.recipients
        logger.info("Failed to notify <%d> users", len(failed_recipients))
        for email, condition in failed_recipients.iteritems():
            logger.info("Failed to notify: %s", condition)
def handle_person(database, source_system, affiliations, send_notifications,
                  email_config, data):
    pe = Factory.get('Person')(database)
    ac = Factory.get('Account')(database)
    et = EmailTarget(database)
    ef = EmailForward(database)
    ed = EmailDomain(database)

    if (data.get('resourceType') == 'persons' and 'affiliation' in data.get(
            'urn:ietf:params:event:SCIM:modify', {}).get('attributes', [])):
        ident = int(data.get('sub').split('/')[-1])

        if not pe.list_affiliations(person_id=ident,
                                    source_system=source_system,
                                    affiliation=affiliations):
            return

        pe.clear()
        pe.find(ident)

        removed_forwards = defaultdict(list)
        for account_id in map(lambda x: x['account_id'],
                              pe.get_accounts(filter_expired=False)):
            try:
                et.clear()
                et.find_by_target_entity(account_id)
            except Errors.NotFoundError:
                continue
            ef.clear()
            ef.find(et.entity_id)
            for forward in map(lambda x: x['forward_to'], ef.get_forward()):
                try:
                    ed.clear()
                    ed.find_by_domain(forward.split('@')[-1])
                except Errors.NotFoundError:
                    ac.clear()
                    ac.find(account_id)
                    ef.delete_forward(forward)
                    removed_forwards[ac.get_primary_mailaddress()].append(
                        forward)
                    logger.info('Deleted forward {} from {}'.format(
                        forward, ac.account_name))
        if send_notifications:
            for k, v in removed_forwards.items():
                sendmail(toaddr=k,
                         fromaddr=email_config.sender,
                         subject=email_config.subject,
                         body=email_config.body_template.format('\n'.join(v)))
    database.commit()
Exemple #14
0
def send_notify_email(new_cere_ous, to_email_addrs):
    """Sends information about OUs to a set of mail_addresses.

    @type  new_cere_ous:   dict
    @param new_cere_ous:   ou_id -> sko (basestring) mapping, containing the OUs
                           that has been added to the database.

    @type  to_email_addrs: list
    @param to_email_addrs: List of email addresses that should be notified about
                           the new OUs.
    """

    if len(new_cere_ous) < 1:
        logger.warn('No new OUs to send notification about')
        return

    ous = OU_class(db)

    # Set up email
    sender = '*****@*****.**'
    subject = 'New OUs added to Cerebrum'
    body = '%(num)d OUs added to Cerebrum on %(time)s\n\n' % \
           {'num': len(new_cere_ous), \
            'time': DateTime.now().strftime()}

    for ou_id in new_cere_ous.keys():
	names = ous.search_name_with_language(entity_id=ou_id,
                                              name_language=co.language_nb,
                                              name_variant=co.ou_name)

        body += '  Entity Id: %d\n' % ou_id
        body += '  Stedkode:  %s\n' % new_cere_ous[ou_id]
        if len(names):
            body += '  Name     : %s\n\n' % names[0]['name']

    for to_email in to_email_addrs:
        try:
            sendmail(to_email, sender, subject, body)

        except SMTPRecipientsRefused, ref:
            for email, cond in ref.recipients.iteritems():
                logger.info('Failed to notify \'%s\': %s', email, cond)
            continue

        except SMTPException, e:
            logger.warn('Failed to notify \'%s\': %s', to_email, e)
            continue
    def send_email(self, subject, message):
        """ Send an email to the email address associated with the account

        """
        to_addr = self.get_address()
        if not self.trait_allows():
            self.logger.warn("Account flooded, will not mail %r", to_addr)
        elif not self.dryrun:
            try:
                sendmail(to_addr, self.sender, subject, message)
                self.logger.debug("Sent message to %r", to_addr)
            except smtplib.SMTPRecipientsRefused, e:
                error = e.recipients.get(to_addr)
                self.logger.warn("Failed to send message to %s (SMTP %d: %s)",
                                 to_addr, error[0], error[1])
            except smtplib.SMTPException:
                self.logger.exception("Failed to send message to %s", to_addr)
Exemple #16
0
def send_email(requests, dryrun, database):
    """Send 'confirm you are still alive' e-mails.
    """

    logger.debug("%d e-mails to dispatch.", len(requests))
    for account_id in requests:
        attrs = requests[account_id]
        email = attrs.email
        uname = attrs.uname
        account_id = attrs.account_id
        magic_key = attrs.magic_key
        expire_date = attrs.expire_date.strftime("%Y-%m-%d")
        confirm_url = get_config("EXPIRE_CONFIRM_URL") + magic_key

        message = get_config("EXPIRE_MESSAGE_TEMPLATE") % {
            "uname": uname,
            "expire_date": expire_date,
            "url": confirm_url,
        }

        logger.debug("Generated a message for %s/%s (request key: %s). ",
                     uname, email, magic_key)
        if not dryrun:
            try:
                sendmail(email,
                         get_config("EXPIRE_MESSAGE_SENDER"),
                         get_config("EXPIRE_MESSAGE_SUBJECT"),
                         message)
                logger.debug("Message for %s/%s (request key: %s) sent",
                             uname, email, magic_key)
            except smtplib.SMTPRecipientsRefused, e:
                error = e.recipients.get(email)
                logger.warn("Failed to send message to %s/%s (SMTP %d: %s)",
                            uname, email, error[0], error[1])
                if error[0] == 550:
                    continue
                else:
                    cancel_request(attrs, database)
            except smtplib.SMTPException:
                logger.exception(
                    "Failed to send message to %s/%s", uname, email)
                cancel_request(attrs, database)
Exemple #17
0
def send_email(requests, dryrun, database):
    """Send 'confirm you are still alive' e-mails.
    """

    logger.debug("%d e-mails to dispatch.", len(requests))
    for account_id in requests:
        attrs = requests[account_id]
        email = attrs.email
        uname = attrs.uname
        account_id = attrs.account_id
        magic_key = attrs.magic_key
        expire_date = attrs.expire_date.strftime("%Y-%m-%d")
        confirm_url = get_config("EXPIRE_CONFIRM_URL") + magic_key

        message = get_config("EXPIRE_MESSAGE_TEMPLATE") % {
            "uname": uname,
            "expire_date": expire_date,
            "url": confirm_url,
        }

        logger.debug("Generated a message for %s/%s (request key: %s). ",
                     uname, email, magic_key)
        if not dryrun:
            try:
                sendmail(email, get_config("EXPIRE_MESSAGE_SENDER"),
                         get_config("EXPIRE_MESSAGE_SUBJECT"), message)
                logger.debug("Message for %s/%s (request key: %s) sent", uname,
                             email, magic_key)
            except smtplib.SMTPRecipientsRefused, e:
                error = e.recipients.get(email)
                logger.warn("Failed to send message to %s/%s (SMTP %d: %s)",
                            uname, email, error[0], error[1])
                if error[0] == 550:
                    continue
                else:
                    cancel_request(attrs, database)
            except smtplib.SMTPException:
                logger.exception("Failed to send message to %s/%s", uname,
                                 email)
                cancel_request(attrs, database)
Exemple #18
0
def test_sendmail(cereconf):
    from Cerebrum.utils.email import sendmail
    mail = {
        'toaddr': '[email protected],[email protected]',
        'fromaddr': '*****@*****.**',
        'cc': '[email protected],[email protected]',
        'subject': 'Testing',
        'body': 'hello this is dog'
    }
    result = sendmail(**mail)
    assert 'To: ' + mail['toaddr'] in result
    assert 'From: ' + mail['fromaddr'] in result
    assert 'Cc: ' + mail['cc'] in result
    assert 'Subject: ' + mail['subject'] in result
    assert base64.b64encode(mail['body']) in result
Exemple #19
0
def test_sendmail(cereconf):
    from Cerebrum.utils.email import sendmail
    mail = {
        'toaddr': '[email protected],[email protected]',
        'fromaddr': '*****@*****.**',
        'cc': '[email protected],[email protected]',
        'subject': 'Testing',
        'body': 'hello this is dog'
    }
    result = sendmail(**mail)
    assert 'To: ' + mail['toaddr'] in result
    assert 'From: ' + mail['fromaddr'] in result
    assert 'Cc: ' + mail['cc'] in result
    assert 'Subject: ' + mail['subject'] in result
    assert base64.b64encode(mail['body']) in result
def send_mail(mail_to, mail_from, subject, body, mail_cc=None):
    """Function for sending mail to users.

    Will respect dryrun, as that is given and handled by
    Cerebrum.utils.email.sendmail, which is then not sending the e-mail.

    @type mail_to: string
    @param mail_to: The recipient of the Email.

    @type mail_from: string
    @param mail_from: The senders address.

    @type subject: string
    @param subject: The messages subject.

    @type body: string
    @param body: The message body.

    @type mail_cc: string
    @param mail_cc: An optional address that the mail will be CCed to.

    @rtype: bool
    @return: A boolean that tells if the email was sent sucessfully or not.
    """
    try:
        ret = sendmail(mail_to,
                       mail_from,
                       subject,
                       body,
                       cc=mail_cc,
                       debug=dryrun)
        if debug_verbose:
            print("---- Mail: ---- \n" + ret)
    except smtplib.SMTPRecipientsRefused as e:
        failed_recipients = e.recipients
        logger.info("Failed to notify <%d> users", len(failed_recipients))
        for _, condition in failed_recipients.iteritems():
            logger.info("Failed to notify: %s", condition)
    except smtplib.SMTPException as msg:
        logger.warn("Error sending to %s: %s" % (mail_to, msg))
        return False
    return True
def send_mail(mail_to, mail_from, subject, body, mail_cc=None):
    """Function for sending mail to users.

    Will respect dryrun, as that is given and handled by
    Cerebrum.utils.email.sendmail, which is then not sending the e-mail.

    @type mail_to: string
    @param mail_to: The recipient of the Email.

    @type mail_from: string
    @param mail_from: The senders address.

    @type subject: string
    @param subject: The messages subject.

    @type body: string
    @param body: The message body.

    @type mail_cc: string
    @param mail_cc: An optional address that the mail will be CCed to.

    @rtype: bool
    @return: A boolean that tells if the email was sent sucessfully or not.
    """
    try:
        ret = sendmail(mail_to, mail_from, subject, body,
                       cc=mail_cc, debug=dryrun)
        if debug_verbose:
            print("---- Mail: ---- \n" + ret)
    except smtplib.SMTPRecipientsRefused as e:
        failed_recipients = e.recipients
        logger.info("Failed to notify <%d> users", len(failed_recipients))
        for _, condition in failed_recipients.iteritems():
            logger.info("Failed to notify: %s", condition)
    except smtplib.SMTPException as msg:
        logger.warn("Error sending to %s: %s" % (mail_to, msg))
        return False
    return True
def main(inargs=None):
    parser = argparse.ArgumentParser(description=__doc__)

    dryrun_arg = parser.add_argument('-d',
                                     '--dryrun',
                                     dest='dryrun',
                                     action='store_true',
                                     default=False,
                                     help='Dry-run (do not send report email)')

    parser.add_argument('-s',
                        '--start-date',
                        dest='start_date',
                        type=ISO.ParseDate,
                        default=now() + RelativeDateTime(days=-1),
                        help='Start date (YYYY-MM-DD) for events,'
                        ' defaults to %(default)s (1 day ago)')

    parser.add_argument('-c',
                        '--change-program',
                        dest='change_program',
                        help='Only get events for %(metavar)s')

    mail_to_arg = parser.add_argument(
        '-t',
        '--mail-to',
        dest='mail_to',
        metavar='ADDR',
        help="Send an email report to %(metavar)s")
    mail_from_arg = parser.add_argument('-f',
                                        '--mail-from',
                                        dest='mail_from',
                                        metavar='ADDR',
                                        help="Send reports from %(metavar)s")

    Cerebrum.logutils.options.install_subparser(parser)
    args = parser.parse_args(inargs)

    # Require mail_to and mail_from, or neither
    if bool(args.mail_from) ^ bool(args.mail_to):
        apply_to = mail_to_arg if args.mail_to else mail_from_arg
        missing = mail_from_arg if args.mail_to else mail_to_arg
        parser.error(
            argparse.ArgumentError(
                apply_to, "Must set {0} as well".format('/'.join(
                    missing.option_strings))))

    # Require mail_to or dryrun to be set
    if not any((args.mail_to, args.dryrun)):
        parser.error(
            argparse.ArgumentError(
                mail_to_arg, "Must set {0} if not sending mail".format(
                    '/'.join(dryrun_arg.option_strings))))

    Cerebrum.logutils.autoconf('cronjob', args)

    logger.info('Start of script %s', parser.prog)
    logger.debug("args: %r", args)

    db = Factory.get('Database')()
    new_persons = list(
        get_new_persons(db,
                        args.start_date,
                        change_program=args.change_program))

    if args.change_program:
        subject = u'New persons from %s since %s' % (args.change_program,
                                                     args.start_date.date)
    else:
        subject = u'New persons since %s' % (args.start_date.date, )
    message = u'\n'.join(report_new_persons(new_persons))

    if new_persons:
        if args.mail_to and not args.dryrun:
            sendmail(args.mail_to, args.mail_from, subject, message)
            logger.info("Sent report to %s", args.mail_to)
        else:
            print("To: {0}".format(args.mail_to))
            print("From: {0}".format(args.mail_from))
            print("Subject: {0}".format(subject))
            print("")
            print(message)
    else:
        logger.info("Nothing to report")

    logger.info('Done with script %s', parser.prog)
def main(inargs=None):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=__doc__)
    parser.add_argument(
        '-o', '--output',
        metavar='FILE',
        type=argparse.FileType('w'),
        default='-',
        help='output file for report, defaults to stdout')
    parser.add_argument(
        '-e', '--encoding',
        dest='codec',
        default=DEFAULT_ENCODING,
        type=codec_type,
        help="output file encoding, defaults to %(default)s")

    parser.add_argument(
        '--min',
        dest='minimum',
        type=lambda x: abs(int(x)),
        default=1,
        metavar='MIN',
        help='Report persons with more than %(metavar)s users'
             ' (default: %(default)s)')
    parser.add_argument(
        '--max',
        dest='maximum',
        type=lambda x: abs(int(x)),
        default=None,
        metavar='MAX',
        help='Report persons with less than %(metavar)s users'
             ' (default: no limit)')

    source_arg = parser.add_argument(
        '--source_systems',
        default=DEFAULT_SOURCE,
        help="comma separated list of source systems to search through,"
             " defaults to %(default)s")

    mail_to_arg = parser.add_argument(
        '-t', '--mail-to',
        dest='mail_to',
        metavar='ADDR',
        help="Send an email report to %(metavar)s")
    mail_from_arg = parser.add_argument(
        '-f', '--mail-from',
        dest='mail_from',
        metavar='ADDR',
        help="Send reports from %(metavar)s")

    Cerebrum.logutils.options.install_subparser(parser)
    args = parser.parse_args(inargs)
    Cerebrum.logutils.autoconf('cronjob', args)

    # Require mail_to and mail_from, or neither
    if bool(args.mail_from) ^ bool(args.mail_to):
        apply_to = mail_to_arg if args.mail_to else mail_from_arg
        missing = mail_from_arg if args.mail_to else mail_to_arg
        parser.error(argparse.ArgumentError(
            apply_to,
            "Must set {0} as well".format('/'.join(missing.option_strings))))

    db = Factory.get('Database')()
    co = Factory.get('Constants')(db)

    src = [get_constant(db, parser, co.AuthoritativeSystem, code, source_arg)
           for code in args.source_systems.split(',')]

    logger.info('Start of script %s', parser.prog)
    logger.debug("args: %r", args)
    logger.debug("source_systems: %r", src)

    stats = collections.defaultdict(int)
    persons = list(get_persons_by_sko(db, src, args.minimum, args.maximum,
                                      stats))

    write_html_report(args.output, args.codec, persons, stats, args.minimum,
                      args.maximum)

    args.output.flush()
    if args.output is not sys.stdout:
        args.output.close()
    logger.info('Report written to %s', args.output.name)

    if args.mail_to:
        subject = "Report from %s" % parser.prog
        body = make_email_report(persons, args.minimum, args.maximum, stats)
        logger.debug('Sending report to %r (%r)', args.mail_to, subject)
        sendmail(args.mail_to, args.mail_from, subject, body)

    logger.info('Done with script %s', parser.prog)
def main(inargs=None):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-t', '--type',
        dest='config',
        type=eventconf_type,
        required=True,
        help="Sync type (a valid entry in eventconf.CONFIG)")

    parser.add_argument(
        '-f', '--file',
        dest='state',
        required=True,
        help="read and write state to %(metavar)s")

    parser.add_argument(
        '-m', '--mail',
        help="Send reports to %(metavar)s")

    parser.add_argument(
        '-s', '--sender',
        help="Send reports from %(metavar)s")

    parser.add_argument(
        '-r', '--report-file',
        dest='report',
        help="Write the report to %(metavar)s")

    Cerebrum.logutils.options.install_subparser(parser)
    args = parser.parse_args(inargs)

    if bool(args.mail) ^ bool(args.sender):
        raise ValueError("Must give both mail and sender")

    Cerebrum.logutils.autoconf('cronjob', args)

    attr_config = args.config['state_check_conf']
    mb_ou = args.config['mailbox_ou']

    try:
        with open(args.state, 'r') as f:
            state = pickle.load(f)
    except IOError:
        logger.warn('No existing state file %s', args.state)
        state = None

    sc = StateChecker(args.config)
    # Collect group info from Cerebrum and Exchange
    sc.init_ldap()
    mb_info = sc.collect_exchange_mail_info(mb_ou)
    sc.close()

    # Collect mail-data from Cerebrum
    cere_mb_info = sc.collect_cerebrum_mail_info()

    # Compare mailbox state between Cerebrum and Exchange
    new_state, report = sc.compare_mailbox_state(mb_info, cere_mb_info,
                                                 state, attr_config)

    try:
        rep = u'\n'.join(report)
    except UnicodeError as e:
        logger.warn('Bytestring data in report: %r', e)
        tmp = []
        for x in report:
            tmp.append(x.decode('UTF-8'))
        rep = u'\n'.join(tmp)

    # Send a report by mail
    if args.mail and args.sender:
        sendmail(args.mail, args.sender,
                 'Exchange mailbox state report',
                 rep.encode('utf-8'))

    # Write report to file
    if args.report:
        with open(args.report, 'w') as f:
            f.write(rep.encode('utf-8'))

    with open(args.state, 'w') as f:
        pickle.dump(new_state, f)
def main(inargs=None):
    parser = argparse.ArgumentParser(
        description="Change the name of an account", )
    parser.add_argument(
        '-o',
        '--old',
        dest='old_name',
        required=True,
        help='Change account name from %(metavar)s',
        metavar='<name>',
    )
    parser.add_argument(
        '-n',
        '--new',
        dest='new_name',
        required=True,
        help='Change account name to %(metavar)s',
        metavar='<name>',
    )
    parser.add_argument(
        '-N',
        '--no-email',
        dest='notify_user',
        action='store_false',
        default=True,
        help='Do not notify user about change (default: notify)',
    )
    add_commit_args(parser)
    Cerebrum.logutils.options.install_subparser(parser)

    args = parser.parse_args(inargs)
    Cerebrum.logutils.autoconf('tee', args)

    logger.info('Start %s', parser.prog)
    logger.debug('args: %r', args)

    dryrun = not args.commit
    old_name = args.old_name
    new_name = args.new_name
    notify_user = args.notify_user

    db = Factory.get('Database')()
    db.cl_init(change_program='ren_acc')

    worker = Changer(db)

    co = Factory.get('Constants')(db)
    ac = Factory.get('Account')(db)
    pe = Factory.get('Person')(db)

    # Find person full name (old)
    ac.find_by_name(old_name)
    pe.find(ac.owner_id)
    old_person_name = pe.get_name(co.system_cached, co.name_full)
    ac.clear()
    pe.clear()

    print("old_name:%s" % old_name)
    print("new name:%s" % new_name)
    send_user_mail = worker.rename_account(old_name, new_name) and notify_user
    update_legacy(db, old_name, new_name)

    ac.find_by_name(new_name)
    pe.find(ac.owner_id)
    new_person_name = pe.get_name(co.system_cached, co.name_full)

    print("Old name:", new_person_name)
    print("New name:", old_person_name)
    print("Notify user:"******"Are you sure you want to write changes?")
        dryrun = not is_sure

    if dryrun:
        logger.info('Rolling back changes')
        db.rollback()
    else:
        logger.info('Commiting changes')
        db.commit()

    if not dryrun and enable_sut_email:
        logger.info("Not running in dryrun mode, sending SUT notification")
        # Sending email to SUT queue in RT
        account_expired = ''
        if ac.is_expired():
            account_expired = (' Imidlertid er ikke kontoen aktiv, '
                               'men kan reaktiveres når som helst.')

        # TBD : remove comment below when leetah is removed
        recipient = '*****@*****.**'
        sendmail(
            toaddr=recipient,
            fromaddr='*****@*****.**',
            subject=('Brukernavn endret (%s erstattes av %s)' %
                     (old_name, new_name)),
            body=('Brukernavnet %s er endret til %s. Videresend '
                  'e-post, flytt filer, e-post, osv. fra %s til '
                  '%s.%s' %
                  (old_name, new_name, old_name, new_name, account_expired)),
            cc=None,
            charset='iso-8859-1',
            debug=dryrun)
        logger.info("Notified %r", recipient)

    if not dryrun and enable_rt_email:
        logger.info("Not running in dryrun mode, sending RT notification")
        # Sending email to PORTAL queue in RT
        # account_expired = ''
        # if ac.is_expired():
        #     account_expired = (' Imidlertid er ikke kontoen aktiv, '
        #                        'men kan reaktiveres når som helst.')
        recipient = '*****@*****.**'
        sendmail(toaddr=recipient,
                 fromaddr='*****@*****.**',
                 subject=('Brukernavn endret (%s erstattes av %s)' %
                          (old_name, new_name)),
                 body=('Brukernavnet %s er endret til %s.' %
                       (old_name, new_name)),
                 cc=None,
                 charset='iso-8859-1',
                 debug=False)
        logger.info("Notified %r", recipient)

    # Sending email to AD nybrukere if necessary
    mailto_ad = False
    try:
        spreads = ac.get_spread()
        for spread in spreads:
            if spread['spread'] == co.spread_uit_ad_account:
                mailto_ad = True
                break
    except Exception:
        logger.debug('No AD-spread on account')

    if not dryrun and enable_ad_email and mailto_ad:
        logger.info("Not running in dryrun mode, sending AD notification")
        riktig_brukernavn = ' Nytt brukernavn er %s.' % (new_name)

        if ac.is_expired():
            riktig_brukernavn += (' Imidlertid er ikke kontoen aktiv, og '
                                  'vil kun sendes til AD når den blir '
                                  'reaktivert.')
        recipient = '*****@*****.**'
        sendmail(toaddr=recipient,
                 fromaddr='*****@*****.**',
                 subject='Brukernavn endret',
                 body=('Brukernavnet %s er endret i BAS.%s' %
                       (old_name, riktig_brukernavn)),
                 cc=None,
                 charset='iso-8859-1',
                 debug=dryrun)
        logger.info("Notified %r", recipient)

    if not dryrun and enable_user_email and send_user_mail:
        logger.info("Not running in dryrun mode, sending user notification")
        # SEND MAIL TO OLD AND NEW ACCOUNT + "BCC" to bas-admin!
        sender = '*****@*****.**'
        # TBD: remove below comment when leetah is removed
        # recipient = send_user_mail['OLD_MAIL']
        # cc = [send_user_mail['NEW_MAIL']]
        # template = os.path.join(cereconf.TEMPLATE_DIR,
        #                         'rename_account.tmpl')
        # result = mail_template(
        #     recipient=recipient,
        #     template_file=template,
        #     sender=sender,
        #     cc=cc,
        #     substitute=send_user_mail,
        #     charset='utf-8',
        #     debug=dryrun)
        # print("Mail sent to: %s" % (recipient))
        # print("cc to %s" % (cc))

        # if dryrun:
        #     print("\nDRYRUN: mailmsg=\n%s" % result)

        # BCC
        recipient = '*****@*****.**'
        template = os.path.join(cereconf.TEMPLATE_DIR, 'rename_account.tmpl')
        mail_template(recipient=recipient,
                      template_file=template,
                      sender=sender,
                      substitute=send_user_mail,
                      charset='utf-8',
                      debug=dryrun)
        logger.info("BCC sent to %r", recipient)
    logger.info('Done %s', parser.prog)
Exemple #26
0
def main(argv=None):
    """Main processing hub for program."""
    if argv is None:
        argv = sys.argv

    # Default values for command-line options
    options = {
        "vlanfile": None,
        "datafile": None,
        "force": False,
        "status_recipients": None,
        "error_recipients": None,
        "mail-from": None,
        "mail-cc": None
    }

    ######################################################################
    # Option-gathering
    try:
        opts, args = getopt.getopt(argv[1:], "hd:v:fs:e:", [
            "help", "datafile=", "vlanfile=", "force", "status_recipients=",
            "error_recipients=", "mail-from=", "mail-cc="
        ])
    except getopt.GetoptError as error:
        usage(message=error.msg)
        return 1

    for opt, val in opts:
        if opt in (
                '-h',
                '--help',
        ):
            usage()
            return 0
        if opt in (
                '-f',
                '--force',
        ):
            options["force"] = True
        if opt in (
                '-v',
                '--vlanfile',
        ):
            options["vlanfile"] = val
        if opt in (
                '-d',
                '--datafile',
        ):
            options["datafile"] = val
        if opt in (
                '-s',
                '--status_recipients',
        ):
            options["status_recipients"] = val
        if opt in (
                '-e',
                '--error_recipients',
        ):
            options["error_recipients"] = val
        if opt in ('--mail-from', ):
            options["mail-from"] = val
        if opt in ('--mail-cc', ):
            options["mail-cc"] = val

    logger.debug("VLAN-file: '%s'" % options["vlanfile"])
    logger.debug("Datafile: '%s'" % options["datafile"])

    if not options["datafile"]:
        usage("Error: need datafile specified.")
        return 2

    ######################################################################
    # Data-processing
    if options["vlanfile"]:
        subnet_to_vlan = parse_vlan_file(options["vlanfile"])
    else:
        subnet_to_vlan = {}

    subnets_in_file = parse_data_file(options["datafile"], subnet_to_vlan)

    (changes, errors) = compare_file_to_db(subnets_in_file, options["force"])

    ######################################################################
    # Feedback to interested parties
    today = time.strftime("%Y-%m-%d")

    doc_info = ""
    if cereconf.DNS_SUBNETIMPORT_ERRORDOC_URL is not None:
        doc_info = ("For more information concerning this import and any "
                    "errors that are reported, please direct your browser to "
                    "%s\n\n" % cereconf.DNS_SUBNETIMPORT_ERRORDOC_URL)

    if errors:
        mail_to = options["error_recipients"]
        subject = "Errors from subnet-import %s" % today
        mail_body = doc_info
        mail_body += ("The following errors were encountered during the"
                      " import:\n\n")
        mail_body += "\n\n".join(errors)
        if options["force"]:
            mail_body += ("\n\nImport forced - non-erronous "
                          "changes made anyway.")
            mail_body += ("\nThe following changes were made:\n%s\n" %
                          "\n".join(changes))
            logger.info("Force-committing non-erronous changes to database.")
            logger.info("Sending mail to '%s' (CC: '%s')", mail_to,
                        options["mail-cc"])
            sendmail(mail_to,
                     options["mail-from"],
                     subject,
                     mail_body,
                     cc=options["mail-cc"])
            db.commit()
            return 0
        else:
            mail_body += "\n\nImport not completed - no changes made."
            mail_body += "Fix the above problems, then rerun the import.\n"
            logger.error("Errors encountered. No changes made by import.")
            db.rollback()
            logger.info("Sending mail to '%s' (CC: '%s')", mail_to,
                        options["mail-cc"])
            sendmail(mail_to,
                     options["mail-from"],
                     subject,
                     mail_body,
                     cc=options["mail-cc"])
            return 3
    else:
        mail_to = options["status_recipients"]
        subject = "Status from subnet-import %s" % today
        mail_body = doc_info
        mail_body += "Subnet-import completed without problems\n"
        if changes:
            mail_body += ("The following changes were made:\n%s\n" %
                          "\n".join(changes))
            logger.info("Committing all changes to database.")
            db.commit()
        else:
            logger.info("No changes needed to be done during this run. "
                        "No mail sent")
            return 0

        logger.info("Sending mail to '%s' (CC: '%s')", mail_to,
                    options["mail-cc"])
        sendmail(mail_to,
                 options["mail-from"],
                 subject,
                 mail_body,
                 cc=options["mail-cc"])
        return 0
def main(argv=None):
    """Main processing hub for program."""
    if argv is None:
        argv = sys.argv

    # Default values for command-line options
    options = {"vlanfile": None,
               "datafile": None,
               "force": False,
               "status_recipients": None,
               "error_recipients": None,
               "mail-from": None,
               "mail-cc": None}

    ######################################################################
    # Option-gathering
    try:
        opts, args = getopt.getopt(argv[1:],
                                   "hd:v:fs:e:",
                                   ["help", "datafile=",
                                    "vlanfile=", "force",
                                    "status_recipients=", "error_recipients=",
                                    "mail-from=", "mail-cc="])
    except getopt.GetoptError as error:
        usage(message=error.msg)
        return 1

    for opt, val in opts:
        if opt in ('-h', '--help',):
            usage()
            return 0
        if opt in ('-f', '--force',):
            options["force"] = True
        if opt in ('-v', '--vlanfile',):
            options["vlanfile"] = val
        if opt in ('-d', '--datafile',):
            options["datafile"] = val
        if opt in ('-s', '--status_recipients',):
            options["status_recipients"] = val
        if opt in ('-e', '--error_recipients',):
            options["error_recipients"] = val
        if opt in ('--mail-from',):
            options["mail-from"] = val
        if opt in ('--mail-cc',):
            options["mail-cc"] = val

    logger.debug("VLAN-file: '%s'" % options["vlanfile"])
    logger.debug("Datafile: '%s'" % options["datafile"])

    if not options["datafile"]:
        usage("Error: need datafile specified.")
        return 2

    ######################################################################
    # Data-processing
    if options["vlanfile"]:
        subnet_to_vlan = parse_vlan_file(options["vlanfile"])
    else:
        subnet_to_vlan = {}

    subnets_in_file = parse_data_file(options["datafile"], subnet_to_vlan)

    (changes, errors) = compare_file_to_db(subnets_in_file, options["force"])

    ######################################################################
    # Feedback to interested parties
    today = time.strftime("%Y-%m-%d")

    doc_info = ""
    if cereconf.DNS_SUBNETIMPORT_ERRORDOC_URL is not None:
        doc_info = ("For more information concerning this import and any "
                    "errors that are reported, please direct your browser to "
                    "%s\n\n" % cereconf.DNS_SUBNETIMPORT_ERRORDOC_URL)

    if errors:
        mail_to = options["error_recipients"]
        subject = "Errors from subnet-import %s" % today
        mail_body = doc_info
        mail_body += ("The following errors were encountered during the"
                      " import:\n\n")
        mail_body += "\n\n".join(errors)
        if options["force"]:
            mail_body += ("\n\nImport forced - non-erronous "
                          "changes made anyway.")
            mail_body += ("\nThe following changes were made:\n%s\n" %
                          "\n".join(changes))
            logger.info("Force-committing non-erronous changes to database.")
            logger.info("Sending mail to '%s' (CC: '%s')", mail_to,
                        options["mail-cc"])
            sendmail(mail_to, options["mail-from"], subject, mail_body,
                     cc=options["mail-cc"])
            db.commit()
            return 0
        else:
            mail_body += "\n\nImport not completed - no changes made."
            mail_body += "Fix the above problems, then rerun the import.\n"
            logger.error("Errors encountered. No changes made by import.")
            db.rollback()
            logger.info("Sending mail to '%s' (CC: '%s')", mail_to,
                        options["mail-cc"])
            sendmail(mail_to, options["mail-from"], subject, mail_body,
                     cc=options["mail-cc"])
            return 3
    else:
        mail_to = options["status_recipients"]
        subject = "Status from subnet-import %s" % today
        mail_body = doc_info
        mail_body += "Subnet-import completed without problems\n"
        if changes:
            mail_body += ("The following changes were made:\n%s\n" %
                          "\n".join(changes))
            logger.info("Committing all changes to database.")
            db.commit()
        else:
            logger.info("No changes needed to be done during this run. "
                        "No mail sent")
            return 0

        logger.info("Sending mail to '%s' (CC: '%s')", mail_to,
                    options["mail-cc"])
        sendmail(mail_to, options["mail-from"], subject, mail_body,
                 cc=options["mail-cc"])
        return 0
Exemple #28
0
    def send_mail(self, uname, user_info, nr, forward=False):
        """
        Get template file based on user_info and expiring action number to
        create Subject and body of mail.

        Get mail addresses based on type of account and expiring action number.
        If a critical error occurs or sending the actual mail fails return
        False, else return True.
        """
        logger.debug("send_mail(uname=%r, user_info=%r, nr=%r, forward=%r)",
                     uname, user_info, nr, forward)

        ac = Factory.get('Account')(self.db)
        ac.find_by_name(uname)
        # Do not send mail to quarantined accounts
        if ac.get_entity_quarantine():
            logger.info("Account is quarantened - no mail sent: %s", uname)
            return False

        # Assume that there exists template files for the mail texts
        # and that cereconf.py has the dict USER_EXPIRE_MAIL
        lines = email_templates.get_template(nr)
        if not lines:
            return False

        msg = []
        for line in lines:
            if line.strip().startswith('From:'):
                email_from = line.split(':')[1]
            elif line.strip().startswith('Subject:'):
                subject = line.split(':', 1)[1]
                subject = subject.replace('$USER$', uname)
            else:
                msg.append(line)
        body = ''.join(msg)
        body = body.replace('$USER$', uname)
        body = body.replace('$EXPIRE_DATE$',
                            user_info['expire_date'].strftime('%Y-%m-%d'))

        # OK, tenk på hvordan dette skal gjøres pent.
        if user_info['ou']:
            body = body.replace('ved $OU$', 'ved %s' % user_info['ou'])
            body = body.replace('at $OU$', 'at %s' % user_info['ou'])

        email_addrs = self.get_email_addresses(user_info['account_id'], nr,
                                               forward)
        if not email_addrs:
            logger.warning("No email addresses available for user_info=%s",
                           repr(user_info))
            return False

        try:
            logger.info("Sending %d. mail To: %s", nr, ', '.join(email_addrs))
            sendmail(
                toaddr=', '.join(email_addrs),
                fromaddr=email_from,
                subject=subject,
                body=body.encode("iso8859-1"),
                debug=self.dryrun,
            )
            if len(email_addrs) > 2:
                logger.warning("Multiple email addrs for account_id=%r (%r)",
                               user_info['account_id'], email_addrs)
                # TODO: We return False, even though we sent emails?
                return False
            return True
        except Exception:
            logger.error("Could not send mail To: %s",
                         ', '.join(email_addrs),
                         exc_info=True)
            return False
Exemple #29
0
def main(inargs=None):
    parser = argparse.ArgumentParser()
    parser.add_argument('-t',
                        '--type',
                        dest='config',
                        type=eventconf_type,
                        required=True,
                        help="Sync type (a valid entry in eventconf.CONFIG)")

    parser.add_argument('-f',
                        '--file',
                        dest='state',
                        required=True,
                        help="read and write state to %(metavar)s")

    parser.add_argument('-m', '--mail', help="Send reports to %(metavar)s")

    parser.add_argument('-s', '--sender', help="Send reports from %(metavar)s")

    parser.add_argument('-r',
                        '--report-file',
                        dest='report',
                        help="Write the report to %(metavar)s")

    Cerebrum.logutils.options.install_subparser(parser)
    args = parser.parse_args(inargs)

    if bool(args.mail) ^ bool(args.sender):
        raise ValueError("Must give both mail and sender")

    Cerebrum.logutils.autoconf('cronjob', args)

    attr_config = args.config['state_check_conf']
    mb_ou = args.config['mailbox_ou']

    try:
        with open(args.state, 'r') as f:
            state = pickle.load(f)
    except IOError:
        logger.warn('No existing state file %s', args.state)
        state = None

    sc = StateChecker(args.config)
    # Collect group info from Cerebrum and Exchange
    sc.init_ldap()
    mb_info = sc.collect_exchange_mail_info(mb_ou)
    sc.close()

    # Collect mail-data from Cerebrum
    cere_mb_info = sc.collect_cerebrum_mail_info()

    # Compare mailbox state between Cerebrum and Exchange
    new_state, report = sc.compare_mailbox_state(mb_info, cere_mb_info, state,
                                                 attr_config)

    try:
        rep = u'\n'.join(report)
    except UnicodeError as e:
        logger.warn('Bytestring data in report: %r', e)
        tmp = []
        for x in report:
            tmp.append(x.decode('UTF-8'))
        rep = u'\n'.join(tmp)

    # Send a report by mail
    if args.mail and args.sender:
        sendmail(args.mail, args.sender, 'Exchange mailbox state report',
                 rep.encode('utf-8'))

    # Write report to file
    if args.report:
        with open(args.report, 'w') as f:
            f.write(rep.encode('utf-8'))

    with open(args.state, 'w') as f:
        pickle.dump(new_state, f)