def test_delete_account():
    ph = PasswordHistory(db)
    entity_id = None
    for acc in get_next_account():
        entity_id = acc.entity_id
        acc.delete()
        break
    for row in ph.get_history(entity_id):
        assert False, "Got password history for deleted e_id %s" % entity_id
def test_delete_account():
    ph = PasswordHistory(db)
    entity_id = None
    for acc in get_next_account():
        entity_id = acc.entity_id
        acc.delete()
        break
    for row in ph.get_history(entity_id):
        assert False, "Got password history for deleted e_id %s" % entity_id
def print_change_dates(accounts):
    db = Factory.get('Database')()
    ac = Factory.get('Account')(db)
    logger = Factory.get_logger('console')
    ph = PasswordHistory(db)

    for account_name in accounts:
        ac.clear()

        try:
            ac.find_by_name(account_name)
        except Errors.NotFoundError:
            logger.error("No such account {!r}".format(account_name))
            continue

        history = ph.get_history(ac.entity_id)
        if history:
            history = sorted(history, key=lambda x: x['set_at'])
            last = dict(history[-1])
            print "{}\t{}".format(account_name, str(last['set_at']))
        else:
            print "{}\t{}".format(account_name, 'NEVER')
Example #4
0
def main():
    """ Script invocation. """
    try:
        import argparse
    except ImportError:
        import Cerebrum.extlib.argparse as argparse

    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-y', '--years', dest='years',
                        help='Number of years to add to the timedelta')
    parser.add_argument('-m', '--months', dest='months',
                        help='Number of months to add to the timedelta')
    parser.add_argument('-d', '--days', dest='days',
                        help='Number of days to add to the timedelta')
    parser.add_argument('--commit', action='store_true',
                        help='Commit changes to DB')
    parser.add_argument('-l', '--logger-name', dest='logname',
                        default='cronjob',
                        help='Specify logger (default: cronjob)')
    args = parser.parse_args()
    if not args.years and not args.months and not args.days:
        raise SystemExit('At least one of the following arguments must be '
                         'specified: years, months, days.\n'
                         'See %s --help' % sys.argv[0])

    exp_date = get_relative_date(years=args.years,
                                 months=args.months,
                                 days=args.days)

    db = Factory.get('Database')()
    logger = Factory.get_logger(args.logname)
    logger.info('Deleting all entries in password_history before: %s' % exp_date)
    ph = PasswordHistory(db)
    ph.del_exp_history(exp_date)
    if args.commit:
        ph.commit()
Example #5
0
def main():
    """ Script invocation. """
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-y',
                        '--years',
                        dest='years',
                        help='Number of years to add to the timedelta')
    parser.add_argument('-m',
                        '--months',
                        dest='months',
                        help='Number of months to add to the timedelta')
    parser.add_argument('-d',
                        '--days',
                        dest='days',
                        help='Number of days to add to the timedelta')
    parser.add_argument('--commit',
                        action='store_true',
                        default=False,
                        help='Commit changes to DB')
    args = parser.parse_args()

    exp_date = get_relative_date(years=args.years,
                                 months=args.months,
                                 days=args.days)

    logger.info('Deleting all entries in password_history before: %s' %
                exp_date)

    ph = PasswordHistory(Factory.get('Database')())
    ph.del_exp_history(exp_date)
    if args.commit:
        logger.info('Committing changes')
        ph.commit()
    else:
        logger.info('Rolling back changes')
        ph.rollback()
    logger.info('Done')
Example #6
0
def main():
    """ Script invocation. """
    try:
        import argparse
    except ImportError:
        import Cerebrum.extlib.argparse as argparse

    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-y',
                        '--years',
                        dest='years',
                        help='Number of years to add to the timedelta')
    parser.add_argument('-m',
                        '--months',
                        dest='months',
                        help='Number of months to add to the timedelta')
    parser.add_argument('-d',
                        '--days',
                        dest='days',
                        help='Number of days to add to the timedelta')
    parser.add_argument('--commit',
                        action='store_true',
                        help='Commit changes to DB')
    parser.add_argument('-l',
                        '--logger-name',
                        dest='logname',
                        default='cronjob',
                        help='Specify logger (default: cronjob)')
    args = parser.parse_args()
    if not args.years and not args.months and not args.days:
        raise SystemExit('At least one of the following arguments must be '
                         'specified: years, months, days.\n'
                         'See %s --help' % sys.argv[0])

    exp_date = get_relative_date(years=args.years,
                                 months=args.months,
                                 days=args.days)

    db = Factory.get('Database')()
    logger = Factory.get_logger(args.logname)
    logger.info('Deleting all entries in password_history before: %s' %
                exp_date)
    ph = PasswordHistory(db)
    ph.del_exp_history(exp_date)
    if args.commit:
        ph.commit()
def main():
    """ Script invocation. """
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '-y', '--years',
        dest='years',
        help='Number of years to add to the timedelta')
    parser.add_argument(
        '-m', '--months',
        dest='months',
        help='Number of months to add to the timedelta')
    parser.add_argument(
        '-d', '--days',
        dest='days',
        help='Number of days to add to the timedelta')
    parser.add_argument(
        '--commit',
        action='store_true',
        default=False,
        help='Commit changes to DB')
    args = parser.parse_args()

    exp_date = get_relative_date(years=args.years,
                                 months=args.months,
                                 days=args.days)

    logger.info(
        'Deleting all entries in password_history before: %s' % exp_date)

    ph = PasswordHistory(Factory.get('Database')())
    ph.del_exp_history(exp_date)
    if args.commit:
        logger.info('Committing changes')
        ph.commit()
    else:
        logger.info('Rolling back changes')
        ph.rollback()
    logger.info('Done')
def test_assert_history_written():
    ph = PasswordHistory(db)
    for acc in get_next_account():
        for row in ph.get_history(acc.entity_id):
            return
    raise Exception("Did not find password history")
def test_assert_history_written():
    ph = PasswordHistory(db)
    for acc in get_next_account():
        for row in ph.get_history(acc.entity_id):
            return
    raise Exception("Did not find password history")
Example #10
0
    def get_old_account_ids(self):
        """ Returns the ID of candidate accounts with old affiliations.

        :return set:
            A set with Account entity_ids.
        """
        def _with_aff(affiliation=None, max_age=None):
            old = set()
            person = Utils.Factory.get("Person")(self.db)

            aff_or_status = self.constants.human2constant(affiliation)
            if not aff_or_status:
                self.logger.error('Unknown affiliation "%s"', affiliation)
                return old

            lookup = {'status' if '/' in affiliation
                      else 'affiliation': aff_or_status}
            for row in person.list_affiliations(**lookup):
                person_id = row['person_id']
                # if person_id in old_ids:
                #     continue
                person.clear()
                person.find(person_id)
                # account_id = person.get_primary_account()
                for account_row in person.get_accounts():
                    # consider all accounts belonging to this person
                    account_id = account_row['account_id']
                    if account_id:
                        history = [x['set_at'] for x in ph.get_history(
                            account_id)]
                        if history and (self.today - max(history) > max_age):
                            old.add(account_id)
                        else:
                            # The account does not have an expired password
                            # according to the special rules.
                            # Remove it from old_ids if it was put there
                            # by the default rules.
                            try:
                                old_ids.remove(account_id)
                            except KeyError:
                                pass
            self.logger.info(
                'Accounts with affiliation %s with old password: %s',
                str(affiliation), len(old))
            return old

        ph = PasswordHistory(self.db)

        self.logger.info('Fetching accounts with password older than %d days',
                         self.config.max_password_age)
        old_ids = set(
            [int(x['account_id']) for x in ph.find_old_password_accounts((
                self.today - dt.DateTimeDelta(
                    self.config.max_password_age)).strftime(DATE_FORMAT))])
        self.logger.info('Fetching accounts with no password history')
        old_ids.update(
            set([int(x['account_id']) for x in ph.find_no_history_accounts()]))
        # Do we have special rules for certain person affiliations?
        # We want to end with the smallest 'max_password_age'
        aff_mappings = sorted(self.config.affiliation_mappings,
                              key=lambda k: k['max_password_age'],
                              reverse=True)
        for aff_mapping in aff_mappings:
            self.logger.info(
                'Fetching accounts with affiliation %s '
                'with password older than %d days',
                str(aff_mapping['affiliation']),
                aff_mapping['max_password_age'])
            old_ids.update(_with_aff(
                affiliation=aff_mapping['affiliation'],
                max_age=dt.DateTimeDelta(aff_mapping['max_password_age'])))
        self.logger.info('Fetching quarantines')
        # TODO: Select only autopassword quarantines?
        quarantined_ids = QuarantineHandler.get_locked_entities(
            self.db,
            entity_types=self.constants.entity_account,
            entity_ids=old_ids)

        old_ids = old_ids - quarantined_ids
        return old_ids
Example #11
0
    def get_old_account_ids(self):
        """ Returns the ID of candidate accounts with old affiliations.

        :return set:
            A set with Account entity_ids.
        """
        def _with_aff(affiliation=None, max_age=None):
            old = set()
            person = Utils.Factory.get("Person")(self.db)

            aff_or_status = self.constants.human2constant(affiliation)
            if not aff_or_status:
                self.logger.error('Unknown affiliation "%s"', affiliation)
                return old

            lookup = {
                'status' if '/' in affiliation else 'affiliation':
                aff_or_status
            }
            for row in person.list_affiliations(**lookup):
                person_id = row['person_id']
                # if person_id in old_ids:
                #     continue
                person.clear()
                person.find(person_id)
                # account_id = person.get_primary_account()
                for account_row in person.get_accounts():
                    # consider all accounts belonging to this person
                    account_id = account_row['account_id']
                    if account_id:
                        history = [
                            x['set_at'] for x in ph.get_history(account_id)
                        ]
                        if history and (self.today - max(history) > max_age):
                            old.add(account_id)
                        else:
                            # The account does not have an expired password
                            # according to the special rules.
                            # Remove it from old_ids if it was put there
                            # by the default rules.
                            try:
                                old_ids.remove(account_id)
                            except KeyError:
                                pass
            self.logger.info(
                'Accounts with affiliation %s with old password: %s',
                str(affiliation), len(old))
            return old

        ph = PasswordHistory(self.db)

        self.logger.info('Fetching accounts with password older than %d days',
                         self.config.max_password_age)
        old_ids = set([
            int(x['account_id']) for x in ph.find_old_password_accounts((
                self.today - dt.DateTimeDelta(self.config.max_password_age)
            ).strftime(DATE_FORMAT))
        ])
        self.logger.info('Fetching accounts with no password history')
        old_ids.update(
            set([int(x['account_id']) for x in ph.find_no_history_accounts()]))
        # Do we have special rules for certain person affiliations?
        # We want to end with the smallest 'max_password_age'
        aff_mappings = sorted(self.config.affiliation_mappings,
                              key=lambda k: k['max_password_age'],
                              reverse=True)
        for aff_mapping in aff_mappings:
            self.logger.info(
                'Fetching accounts with affiliation %s '
                'with password older than %d days',
                str(aff_mapping['affiliation']),
                aff_mapping['max_password_age'])
            old_ids.update(
                _with_aff(affiliation=aff_mapping['affiliation'],
                          max_age=dt.DateTimeDelta(
                              aff_mapping['max_password_age'])))
        self.logger.info('Fetching quarantines')
        # TODO: Select only autopassword quarantines?
        quarantined_ids = QuarantineHandler.get_locked_entities(
            self.db,
            entity_types=self.constants.entity_account,
            entity_ids=old_ids)

        old_ids = old_ids - quarantined_ids
        return old_ids