示例#1
0
    def get_sito_account(self, existing_person):
        account = Factory.get('Account')(self.db)
        person_id = existing_person.get_personid()
        sito_account = None

        for acc in existing_person._accounts:
            account.clear()
            account.find(acc)
            for acc_type in account.get_account_types():
                if self.co.affiliation_ansatt_sito in acc_type:
                    sito_account = account.entity_id
                    logger.info(
                        "Found sito account_id=%r (%s) for "
                        "person_id=%r (from acc_type)", sito_account,
                        account.account_name, person_id)
                    break

        if sito_account is None:
            # An account may have its account type not set.
            # in these cases, the only way to check if an acocunt is a sito
            # account is to check the last 2 letters in the account name.
            # if they are'-s', then its a sito account.
            for acc in existing_person._accounts:
                account.clear()
                account.find(acc)
                # Account did not have a sito type (only set on active
                # accounts).  we will have to check account name in case we
                # have to reopen an inactive account.
                if UsernamePolicy.is_valid_sito_name(account.account_name):
                    sito_account = account.entity_id
                    logger.info(
                        "Found sito account_id=%r (%s) for "
                        "person_id=%r (from username)", sito_account,
                        account.account_name, person_id)
                    break

        if sito_account is None:
            raise NotFound("No sito account for %r", existing_person)
        else:
            return sito_account
def get_existing_accounts(db):
    co = Factory.get('Constants')(db)
    ou = Factory.get('OU')(db)
    stedkoder = ou.get_stedkoder()
    ou_stedkode_mapping = {}
    for stedkode in stedkoder:
        ou_stedkode_mapping[stedkode['ou_id']] = str(
            stedkode['fakultet']).zfill(2) + str(
                stedkode['institutt']).zfill(2) + str(
                    stedkode['avdeling']).zfill(2)

    # get persons that comes from sysX and their accounts
    pers = Factory.get("Person")(db)

    # getting deceased persons
    deceased = pers.list_deceased()

    tmp_persons = {}
    logger.debug("Loading persons...")
    pid2sysxid = {}
    sysx2pid = {}
    for row in pers.search_external_ids(id_type=co.externalid_sys_x_id,
                                        fetchall=False):
        # denne henter ut alle fra system x

        if (row['source_system'] == int(co.system_x)
                or (int(row['entity_id']) not in pid2sysxid)):

            pid2sysxid[int(row['entity_id'])] = int(row['external_id'])
            sysx2pid[int(row['external_id'])] = int(row['entity_id'])
            tmp_persons[int(row['external_id'])] = ExistingPerson()

            if int(row['entity_id']) in deceased:
                tmp_persons[int(row['external_id'])].set_deceased_date(
                    deceased[int(row['entity_id'])])

    logger.debug("Loading affiliations...")
    for row in pers.list_affiliations(source_system=co.system_x,
                                      fetchall=False):
        # Denne henter ut alle personer med AKTIV system_x affiliation

        tmp = pid2sysxid.get(row['person_id'], None)
        if tmp is not None:
            ou.clear()
            try:
                ou.find(int(row['ou_id']))
                tmp_persons[tmp].append_affiliation(int(row['affiliation']),
                                                    int(row['ou_id']),
                                                    int(row['status']))
                try:
                    sys_x_affs[tmp] = ou_stedkode_mapping[row['ou_id']]
                except Exception:
                    logger.warning("person_id=%r has expired sko=%r",
                                   row['person_id'], row['ou_id'])
            except EntityExpiredError:
                logger.error("Skipping aff for sysx_id=%r, ou_id=%r (expired)",
                             tmp, row['ou_id'])
                continue

    tmp_ac = {}
    account_obj = Factory.get('Account')(db)
    account_name_obj = Factory.get('Account')(db)

    #
    # hente alle kontoer for en person
    #
    logger.info("Loading accounts...")
    for row in account_obj.list(filter_expired=False, fetchall=False):
        sysx_id = pid2sysxid.get(int(row['owner_id']), None)

        if not sysx_id or sysx_id not in tmp_persons:
            continue

        #
        # Need to exclude all non-uit accounts
        #
        account_name_obj.clear()
        account_name_obj.find(row['account_id'])
        if UsernamePolicy.is_valid_sito_name(account_name_obj.account_name):
            logger.debug("Skipping sito account_id=%r (%s)",
                         account_name_obj.entity_id,
                         account_name_obj.account_name)
            continue

        #
        # Exclude accounts that ends with 999 (they are admin accounts and not
        # to be counted when checking for existing accounts)
        #
        if account_name_obj.account_name[3:6] == '999':
            logger.debug("Skipping admin account_id=%r (%s)",
                         account_name_obj.entity_id,
                         account_name_obj.account_name)
            continue

        tmp_ac[row['account_id']] = ExistingAccount(sysx_id,
                                                    row['expire_date'])

    # Posixusers
    logger.info("Loading posix users...")
    posix_user_obj = Factory.get('PosixUser')(db)
    for row in posix_user_obj.list_posix_users():
        tmp = tmp_ac.get(int(row['account_id']), None)
        if tmp is not None:
            tmp.set_posix(int(row['posix_uid']))

    # quarantines
    logger.info("Loading posix quarantines...")
    for row in account_obj.list_entity_quarantines(
            entity_types=co.entity_account):
        tmp = tmp_ac.get(int(row['entity_id']), None)
        if tmp is not None:
            tmp.append_quarantine(int(row['quarantine_type']))

    # Spreads
    logger.info("Loading spreads...")
    spread_list = [
        co.spread_uit_ldap_people,
        co.spread_uit_fronter_account,
        co.spread_uit_ldap_system,
        co.spread_uit_ad_account,
        co.spread_uit_cristin,
        co.spread_uit_exchange,
    ]
    for spread_id in spread_list:
        is_account_spread = is_person_spread = False
        spread = co.Spread(spread_id)
        if spread.entity_type == co.entity_account:
            is_account_spread = True
        elif spread.entity_type == co.entity_person:
            is_person_spread = True
        else:
            logger.warning("Unknown spread code=%r (%r)", spread_id, spread)
            continue
        for row in account_obj.list_all_with_spread(spread_id):
            if is_account_spread:
                tmp = tmp_ac.get(int(row['entity_id']), None)
            if is_person_spread:
                tmp = tmp_persons.get(int(row['entity_id']), None)
            if tmp is not None:
                tmp.append_spread(int(spread_id))

    # Account homes
    # FIXME: This does not work for us!
    logger.info("Loading account homedirs...")
    for row in account_obj.list_account_home():
        tmp = tmp_ac.get(int(row['account_id']), None)
        if tmp is not None and row['disk_id']:
            tmp.set_home(int(row['home_spread']), int(row['disk_id']),
                         int(row['homedir_id']))

    # Affiliations
    logger.info("Loading account affs...")
    for row in account_obj.list_accounts_by_type(filter_expired=False):
        tmp = tmp_ac.get(int(row['account_id']), None)
        if tmp is not None:
            ou.clear()
            try:
                ou.find(int(row['ou_id']))
                tmp.append_affiliation(int(row['affiliation']),
                                       int(row['ou_id']))
            except EntityExpiredError:
                logger.warning(
                    "Skipping account aff for account_id=%r "
                    "to ou_id=%r (expired)", row['account_id'], row['ou_id'])
                continue

    # traits
    logger.info("Loading traits...")
    for row in account_obj.list_traits(co.trait_sysx_registrar_notified):
        tmp = tmp_ac.get(int(row['entity_id']), None)
        if tmp is not None:
            tmp.append_trait(co.trait_sysx_registrar_notified, row['strval'])
    for row in account_obj.list_traits(co.trait_sysx_user_notified):
        tmp = tmp_ac.get(int(row['entity_id']), None)
        if tmp is not None:
            tmp.append_trait(co.trait_sysx_user_notified, row['strval'])

    # organize sysx id's
    for acc_id, tmp in tmp_ac.items():
        sysx_id = tmp_ac[acc_id].get_sysxid()
        logger.info("Got existing sysx account_id=%r for sysx_id=%r", acc_id,
                    sysx_id)
        tmp_persons[sysx_id].append_account(acc_id)

    logger.info("Found %i persons and %i accounts", len(tmp_persons),
                len(tmp_ac))
    return tmp_persons, tmp_ac
示例#3
0
def get_existing_accounts(db):
    """
    Get persons that comes from Paga and their accounts.
    """
    const = Factory.get('Constants')(db)
    person = Factory.get('Person')(db)
    account_obj = Factory.get('Account')(db)

    logger.info("Loading persons...")
    person_cache = {}
    account_cache = {}
    pid2fnr = {}
    pid2passnr = {}

    # getting deceased persons
    deceased = person.list_deceased()

    # Get ExistingPerson objects by ssn
    for row in person.search_external_ids(id_type=const.externalid_fodselsnr,
                                          source_system=const.system_paga,
                                          fetchall=False):
        p_id = int(row['entity_id'])
        key = (int(const.externalid_fodselsnr), row['external_id'])
        if p_id not in pid2fnr:
            pid2fnr[p_id] = row['external_id']
            person_cache[key] = ExistingPerson(person_id=p_id)
            if p_id in deceased:
                person_cache[key].set_deceased_date(deceased[p_id])
        del p_id, key

    # Get remaining ExistingPerson objects by passport number
    for row in person.search_external_ids(id_type=const.externalid_pass_number,
                                          source_system=const.system_paga,
                                          fetchall=False):
        p_id = int(row['entity_id'])
        key = (int(const.externalid_pass_number), row['external_id'])
        if p_id not in pid2fnr and p_id not in pid2passnr:
            pid2passnr[p_id] = row['external_id']
            person_cache[key] = ExistingPerson(person_id=p_id)
            logger.debug("Using passport id for person_id=%r", p_id)
            if p_id in deceased:
                person_cache[key].set_deceased_date(deceased[p_id])
        del p_id, key

    logger.info("Loading person affiliations...")
    for row in person.list_affiliations(source_system=const.system_paga,
                                        fetchall=False):
        p_id = int(row['person_id'])
        if p_id in pid2fnr:
            key = (int(const.externalid_fodselsnr), pid2fnr[p_id])
        elif p_id in pid2passnr:
            key = (int(const.externalid_pass_number), pid2passnr[p_id])
        else:
            key = None

        if key is not None:
            person_cache[key].append_affiliation(int(row['affiliation']),
                                                 int(row['ou_id']),
                                                 int(row['status']))
        del p_id, key

    logger.info("Loading accounts...")
    for row in account_obj.search(expire_start=None):
        a_id = int(row['account_id'])
        id_type = id_value = None
        if not row['owner_id']:
            continue
        if int(row['owner_id']) in pid2fnr:
            id_type = const.externalid_fodselsnr
            id_value = pid2fnr[int(row['owner_id'])]
        elif int(row['owner_id']) in pid2passnr:
            id_type = const.externalid_pass_number
            id_value = pid2passnr[int(row['owner_id'])]
        else:
            continue
        if UsernamePolicy.is_valid_sito_name(row['name']):
            # this is a sito account, do not process as part of uit employees
            logger.debug("Omitting account id=%r (%s), sito account", a_id,
                         row['name'])
            continue
        account_cache[a_id] = ExistingAccount(id_type, id_value, row['name'],
                                              row['expire_date'])
        del a_id

    # Posixusers
    logger.info("Loading posixinfo...")
    posix_user_obj = PosixUser.PosixUser(db)
    for row in posix_user_obj.list_posix_users():
        a_obj = account_cache.get(int(row['account_id']), None)
        if a_obj is not None:
            a_obj.set_posix(int(row['posix_uid']))
        del a_obj

    # quarantines
    logger.info("Loading account quarantines...")
    for row in account_obj.list_entity_quarantines(
            entity_types=const.entity_account):
        a_obj = account_cache.get(int(row['entity_id']), None)
        if a_obj is not None:
            a_obj.append_quarantine(int(row['quarantine_type']))
        del a_obj

    # Spreads
    logger.info("Loading spreads... %r ", cereconf.EMPLOYEE_SPREADLIST)
    spread_list = [int(const.Spread(x)) for x in cereconf.EMPLOYEE_SPREADLIST]
    for spread_id in spread_list:
        is_account_spread = is_person_spread = False
        spread = const.Spread(spread_id)
        if spread.entity_type == const.entity_account:
            is_account_spread = True
        elif spread.entity_type == const.entity_person:
            is_person_spread = True
        else:
            logger.warning("Unknown spread type (%r)", spread)
            continue
        for row in account_obj.list_all_with_spread(spread_id):
            e_id = int(row['entity_id'])
            if is_account_spread and e_id in account_cache:
                account_cache[e_id].append_spread(spread_id)
            elif is_person_spread and e_id in pid2fnr:
                person_cache[int(const.externalid_fodselsnr),
                             pid2fnr[e_id]].append_spread(spread_id)
            elif is_person_spread and e_id in pid2passnr:
                person_cache[int(const.externalid_pass_number),
                             pid2passnr[e_id]].append_spread(spread_id)
            del e_id

    # Account Affiliations
    logger.info("Loading account affs...")
    for row in account_obj.list_accounts_by_type(filter_expired=False,
                                                 primary_only=False,
                                                 fetchall=False):
        tmp = account_cache.get(int(row['account_id']))
        if tmp is not None:
            tmp.append_affiliation(int(row['affiliation']), int(row['ou_id']),
                                   int(row['priority']))
        del tmp

    # persons accounts....
    for ac_id, ac_obj in account_cache.items():
        id_type = ac_obj.get_external_id_type()
        id_value = ac_obj.get_external_id()
        key = (int(id_type), id_value)
        person_cache[key].append_account(ac_id)
        for aff in ac_obj.get_affiliations():
            aff, ou_id, pri = aff
            person_cache[key].set_primary_account(ac_id, pri)

    logger.info("Found %d persons and %d accounts", len(person_cache),
                len(account_cache))
    return person_cache, account_cache
def process_mail(db):
    co = Factory.get('Constants')(db)
    ac = Factory.get('Account')(db)
    # TODO: Use `Email` module logger
    em = Email.email_address(db, logger=logger.getChild('email_address'))

    generate_addr = AddressGenerator(db)
    spread = co.spread_uit_exchange

    logger.info("Fetching all sito persons...")
    sito_persons = list(get_sito_persons(db))
    logger.info("Got %s persons", len(sito_persons))

    exch_users = dict()
    uname2accid = dict()
    ownerid2uname = dict()
    stats = {'included': 0, 'skipped': 0}

    logger.info("Fetching all sito accounts with %r spread...", spread)
    for a in ac.search(spread=spread):
        if not UsernamePolicy.is_valid_sito_name(a['name']):
            stats['skipped'] += 1
            continue
        if a['owner_id'] not in sito_persons:
            stats['skipped'] += 1
            continue

        stats['included'] += 1
        exch_users[a['account_id']] = a['name']
        uname2accid[a['name']] = a['account_id']
        ownerid2uname.setdefault(a['owner_id'], []).append(a['name'])
    logger.info('Got %d accounts (%d considered, %d skipped)',
                stats['included'], sum(stats.values()), stats['skipped'])
    logger.debug("%d account ids, %d usernames", len(exch_users),
                 len(uname2accid))

    for owner, usernames in (t for t in ownerid2uname.items()
                             if len(t[1]) > 1):
        logger.debug("owner_id=%r has %d accounts: %s", owner, len(usernames),
                     usernames)

    logger.info("Fetching all sito email targets...")
    sito_mails = dict()
    for uname, data in ac.getdict_uname2mailinfo().items():
        if uname not in uname2accid:
            continue
        # this is a sito user
        for row in filter(lambda r: r['domain'] == sito_domain, data):
            sito_mails[uname] = format_addr(row['local_part'], row['domain'])
    logger.info('Got email address for %d sito accounts', len(sito_mails))

    # list to hold those we will build addresses for
    all_emails = dict()

    for account_id, uname in exch_users.items():
        if uname in sito_mails:
            logger.debug("User %s has existing address %r", uname,
                         sito_mails[uname])
        else:
            logger.info("User %s does not have an address!", uname)
            try:
                cn_addr = generate_addr.reserve_addr(uname, sito_domain)
                all_emails.setdefault(account_id, []).append(cn_addr)
            except Exception:
                logger.error('Unable to generate email address for %r/%r',
                             uname,
                             sito_domain,
                             exc_info=True)

    # update all email addresses
    logger.debug('Updating %d sito addresses', len(all_emails))
    for acc_id, emaillist in all_emails.items():
        for local_part, domain_part in emaillist:
            # TBD: is_primary always set to True?
            is_primary = True
            addr = format_addr(local_part, domain_part)
            logger.info('Setting address for %r to %r (primary=%r)', acc_id,
                        addr, is_primary)
            em.process_mail(acc_id, addr, is_primary=is_primary)