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
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)