示例#1
0
    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
示例#2
0
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
示例#3
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
示例#4
0
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
示例#6
0
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
示例#8
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)