Ejemplo n.º 1
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
Ejemplo n.º 2
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