def create_sito_account(self, existing_person, fnr): """ Create a sito account for a given person. """ p_obj = Factory.get('Person')(self.db) p_obj.find(existing_person.get_personid()) first_name = p_obj.get_name(self.co.system_cached, self.co.name_first) last_name = p_obj.get_name(self.co.system_cached, self.co.name_last) full_name = "%s %s" % (first_name, last_name) name_gen = UsernamePolicy(self.db) uname = name_gen.get_sito_uname(fnr, full_name) acc_obj = Factory.get('Account')(self.db) acc_obj.populate(uname, self.co.entity_person, p_obj.entity_id, None, get_creator_id(self.db), get_expire_date()) try: acc_obj.write_db() except Exception as m: logger.error("Failed create for %s, uname=%s, reason: %s", fnr, uname, m) else: password = acc_obj.make_passwd(uname) acc_obj.set_password(password) acc_obj.write_db() # register new account obj in existing accounts list self.accounts[acc_obj.entity_id] = ExistingAccount(fnr, uname, None) logger.info("Created sito account_id=%r (%s) for person_id=%r", acc_obj.entity_id, uname, existing_person.get_personid()) return acc_obj.entity_id
def generate_username(db, person_name, account_type): """Generate a new username""" cstart = cstart_map[account_type] name_gen = UsernamePolicy(db) inits = name_gen.get_initials(person_name) username = name_gen.get_serial(inits, cstart) logger.info("Generated username=%r", username) return username
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_accounts(fnr_list, db): ac = Factory.get('Account')(db) pe = Factory.get('Person')(db) co = Factory.get('Constants')(db) fagpersons_dict = {} for fnr in fnr_list: person_dict = {'username': '', 'note': ''} pe.clear() try: pe.find_by_external_id(co.externalid_fodselsnr, fnr, source_system=co.system_fs) except Errors.NotFoundError: person_dict['note'] = ("does not exist in cerebrum with source=FS." " Skipping.") else: # persons exits in cerebrum. now try to find the accounts try: # this should return all accounts accounts = pe.get_accounts(filter_expired=False) except Errors.NotFoundError: person_dict['note'] = "This person has no accounts" # some ppl har multiple accounts (sito). Make sure sito accounts # are filtered for account in accounts: ac.clear() ac.find(account[0]) username = ac.get_account_name() if UsernamePolicy.is_valid_uit_name(username): # this is a uit account. add it person_dict['username'] = username if ac.is_expired(): person_dict['note'] = 'is expired' fagpersons_dict[fnr] = person_dict return fagpersons_dict
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
from Cerebrum.modules.no.uit.Account import UsernamePolicy from Cerebrum.utils import transliterate from Cerebrum.utils.argutils import add_commit_args logger = logging.getLogger(__name__) db = Factory.get('Database')() db.cl_init(change_program='pop_itroles') account = Factory.get('Account')(db) person = Factory.get('Person')(db) const = Factory.get('Constants')(db) account2name = dict( (x["entity_id"], x["entity_name"]) for x in Factory.get("Group")(db).list_names(const.account_namespace)) name_gen = UsernamePolicy(db) class RolesXmlParser(xml.sax.ContentHandler): """Parserklasse for it_roles.xml.""" elements = { 'roles': False, 'role': True, 'member': True, } def __init__(self, filename, call_back_function): self.call_back_function = call_back_function xml.sax.parse(filename, self)
def parse_paga_csv(db, pagafile): persons = {} for detail in read_csv_file(pagafile, encoding=default_in_encoding, charsep=default_in_charsep): # De vi ønsker skal overføres er alle med ansattforhold: # E (engasjert) # F (fast) # K (kvalifisering) # U (utdanningsstilling) # V (vikar) # Å (åremål). # P (permisjon) # B (bistilling) # ÅP (postdoc) # L (lærling) # T (timelønnet) if (detail[KEY_HOVEDARBFORH] == 'H' and detail[KEY_TJFORH].upper() in ['E', 'F', 'K', 'U', 'V', 'Å', 'P', 'B', 'ÅP', 'L', 'T']): persons[detail[KEY_ANSATTNR]] = {} ac = Factory.get('Account')(db) pe = Factory.get('Person')(db) co = Factory.get('Constants')(db) personid_ansattnr = {} logger.info("Caching person ids...") for ansattnr in persons.keys(): pe.clear() try: pe.find_by_external_id(co.externalid_paga_ansattnr, ansattnr) personid_ansattnr[pe.entity_id] = ansattnr except Errors.NotFoundError: logger.error("Person not found in BAS with ansattnr=%r", ansattnr) continue for key, extid_type in (('fnr', co.externalid_fodselsnr), ('passnr', co.externalid_pass_number)): try: persons[ansattnr][key] = pe.get_external_id( source_system=co.system_paga, id_type=extid_type, )[0]['external_id'] except IndexError: logger.error("No id_type=%s for entity_id=%r, ansattnr=%r", extid_type, pe.entity_id, ansattnr) continue else: logger.debug("Using id_type=%s for entity_id=%r, ansattnr=%r", extid_type, pe.entity_id, ansattnr) break logger.info("Caching e-mails...") uname_mail = ac.getdict_uname2mailaddr() logger.info("Loading accounts...") for row in ac.search(expire_start=None): if not UsernamePolicy.is_valid_uit_name(row['name']): logger.debug("Skipping non-uit account id=%r, name=%r", row['account_id'], row['name']) continue if row['name'][3:5] == '99': logger.debug("Skipping 999 account id=%r, name=%r", row['account_id'], row['name']) continue pid = row['owner_id'] if (pid in personid_ansattnr and personid_ansattnr[pid] in persons.keys()): persons[personid_ansattnr[pid]]['brukernavn'] = row['name'] if row['name'] in uname_mail: persons[personid_ansattnr[pid]]['epost'] = \ uname_mail[row['name']] else: logger.warning("E-mail not found for account id=%r, name=%r", row['account_id'], row['name']) return persons
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)