def make_inital_users(db): print("Creating initial entities.") from Cerebrum import Constants from Cerebrum import Group from Cerebrum import Account from Cerebrum import Entity co = Constants.Constants() eg = Entity.Entity(db) eg.populate(co.entity_group) eg.write_db() ea = Entity.Entity(db) ea.populate(co.entity_account) ea.write_db() def false(*args): return False # TODO: These should have a permanent quarantine and be non-visible # Use Account.Account to avoid getting the wrong Account Mixins # fiddling with the bootstrap account. Every instance may use this # account as they see fit, but have to append functionality # manually afterwards. makedb an account that can be created with # a fully populated cereconf, but an empty database(which may # break a lot of Mixins). a = Account.Account(db) a.illegal_name = false a.populate( name=cereconf.INITIAL_ACCOUNTNAME, owner_type=co.entity_group, owner_id=eg.entity_id, np_type=int(co.account_program), creator_id=ea.entity_id, expire_date=None, description=None, parent=ea, ) # Get rid of errors because of missing prerequisites for password # mechanisms not needed for initial setup. # # TBD: implement cereconf.INITIAL_PASSWORD_MECHANISM? method = co.auth_type_md5_crypt a.affect_auth_types(method) enc = a.encrypt_password(method, cereconf.INITIAL_ACCOUNTNAME_PASSWORD) a.populate_authentication_type(method, enc) a.write_db() g = Group.Group(db) g.illegal_name = false g.populate(creator_id=a.entity_id, visibility=co.group_visibility_all, name=cereconf.INITIAL_GROUPNAME, group_type=co.group_type_internal, parent=eg) g.write_db() g.add_member(a.entity_id) db.commit()
def get_locked_entities(db, entity_types=None, only_active=True, entity_ids=None, ignore_quarantine_types=None): """Utility method that the returns the entity-id of all locked accounts. :param db: A database object :param entity_types: Entity types to filter on :param only_active: Only return locked and active quarantines :param entity_ids: Spesific entity-ids to check :param ignore_quarantine_types: Quarantines to ignore""" cache = defaultdict(list) eq = Entity.EntityQuarantine(db) for row in eq.list_entity_quarantines( entity_types=entity_types, only_active=only_active, entity_ids=entity_ids, ignore_quarantine_types=ignore_quarantine_types): cache[row['entity_id']].append(row['quarantine_type']) def is_locked(key): return QuarantineHandler(db, cache.get(key)).is_locked() return set(filter(is_locked, cache.keys()))
def _get_entity(self, entity_type=None, ident=None): """ Return a suitable entity subclass for the specified entity_id. This method is useful when we have entity_id only, but want the most specific object for that id. """ if ident is None: raise CerebrumError("Invalid id") if entity_type in ('account', self.const.entity_account): return self._get_account(ident) if entity_type in ('group', self.const.entity_group): return self._get_group(ident) if entity_type == 'stedkode': return self._get_ou(stedkode=ident) if entity_type == 'person': return self._get_person(*self._map_person_id(ident)) if entity_type is None: id_type, ident = self._human_repr2id(ident) if id_type == "id": ent = Entity.Entity(self.db) ent.find(ident) else: raise CerebrumError( "Unknown/unsupported id_type %s for id %s" % (id_type, str(ident))) # The find*() calls give us an entity_id from ident. The call # below returns the most specific object for that numeric # entity_id. entity_id = int(ent.entity_id) ent.clear() return ent.get_subclassed_object(entity_id) raise CerebrumError("Invalid entity type: %s" % str(entity_type))
def get_contacts(self, entity_id=None, contact_type=None, source_system=None, convert=None, verify=None, normalize=None): # Return a list of contact values for the specified parameters, # or if entity_id is None, a dict {entity_id: [contact values]}. entity = Entity.EntityContactInfo(self.db) cont_tab = {} if not convert: convert = str for row in entity.list_contact_info(entity_id=entity_id, source_system=source_system, contact_type=contact_type): c_list = [convert(str(row['contact_value']))] if '$' in c_list[0]: c_list = c_list[0].split('$') elif normalize == normalize_phone and '/' in c_list[0]: c_list = c_list[0].split('/') key = int(row['entity_id']) if cont_tab.has_key(key): cont_tab[key].extend(c_list) else: cont_tab[key] = c_list for key, c_list in cont_tab.iteritems(): cont_tab[key] = self.attr_unique(filter( verify, [c for c in c_list if c not in ('', '0')]), normalize=normalize) if entity_id is None: return cont_tab else: return (cont_tab.values() or ((), ))[0]
def get_creator_id(db): const = Factory.get('Constants')(db) entity_name = Entity.EntityName(db) entity_name.find_by_name(cereconf.INITIAL_ACCOUNTNAME, const.account_namespace) id = entity_name.entity_id return id
def fetch_name(entity_id, db): """Fetch entity_id's name, ignoring errors if it does not exist. """ ent = Entity.EntityName(db) try: ent.find(int(entity_id)) return ", ".join(x["name"] for x in ent.get_names()) except Errors.NotFoundError: return ""
def check_entity_quarantines(db, entity_id, spreads=None): """Utility method that returns an initiated QuarantineHandler for a given entity_id""" eq = Entity.EntityQuarantine(db) eq.find(entity_id) return QuarantineHandler(db, [ int(row['quarantine_type']) for row in eq.get_entity_quarantine(only_active=True) ], spreads)
def person_authn_methods(self): """ Returns a contact info mapping for update_person_authn. Initializes self.person_authn_methods with a dict that maps person entity_id to a list of dicts with contact info: person_id: [ {'contact_type': <const>, 'source_system': <const>, 'value': <str>, }, ... ], ... """ if not hasattr(self, '_person_authn_methods'): timer = make_timer(self.logger, 'Fetching authentication methods...') entity = Entity.EntityContactInfo(self.db) self._person_authn_methods = dict() # Find the unique systems and contact types for filtering source_systems = set( (v[0] for s in self.person_authn_selection.itervalues() for v in s)) contact_types = set( (v[1] for s in self.person_authn_selection.itervalues() for v in s)) if not source_systems or not contact_types: # No authn methods to cache return self._person_authn_methods # Cache contact info count = 0 for row in entity.list_contact_info( entity_type=self.const.entity_person, source_system=list(source_systems), contact_type=list(contact_types)): c_type = self.const.ContactInfo(row['contact_type']) system = self.const.AuthoritativeSystem(row['source_system']) self._person_authn_methods.setdefault(int( row['entity_id']), list()).append({ 'value': six.text_type(row['contact_value']), 'contact_type': c_type, 'source_system': system, }) count += 1 timer("...authentication methods done.") return self._person_authn_methods
def __init__(self, db, persons=None, accounts=None): self.db = db self.co = Factory.get('Constants')(db) self.persons = persons or {} self.accounts = accounts or {} # create list of all valid countries # TODO: Country codes should *really* not be part of the cerebrum # database. UiT is currently the only ones using it entity_address = Entity.EntityAddress(db) self.country_codes = { row['code_str'] for row in entity_address.list_country_codes() if row['code_str'] }
def main(): global db, co, ac, group, person, qua, logger global server, ou, child_ou c_data = {} ad_data = {} db = Factory.get('Database')() db.cl_init(change_program="adusync") co = Factory.get('Constants')(db) ac = Factory.get('Account')(db) ou = Factory.get("OU")(db) child_ou = Factory.get("OU")(db) group = Factory.get('Group')(db) person = Factory.get('Person')(db) qua = Entity.EntityQuarantine(db) logger = Factory.get_logger("cronjob") passwd = db._read_password(cereconf.AD_SERVER_HOST, cereconf.AD_SERVER_UNAME) # Connect to AD-service at NMH # server = xmlrpclib.Server( "https://%s@%s:%i" % (passwd, cereconf.AD_SERVER_HOST, cereconf.AD_SERVER_PORT)) try: opts, args = getopt.getopt(sys.argv[1:], '', ['help', 'dry_run']) except getopt.GetoptError: usage(1) dry_run = False for opt, val in opts: if opt == '--help': usage(1) elif opt == '--dry_run': dry_run = True c_data = get_cerebrum_data() # Fetch AD-data. Catch ProtocolError and don't write xpe.url to log # since it may contain a password. try: ad_data = get_ad_data() except xmlrpclib.ProtocolError, xpe: logger.critical("Error connecting to AD service. Giving up!: %s %s" % (xpe.errcode, xpe.errmsg)) return
def get_contact_aliases(self, contact_type=None, source_system=None, convert=None, verify=None, normalize=None): """Return a dict {entity_id: [list of contact aliases]}.""" # The code mimics a reduced modules/OrgLDIF.py:get_contacts(). entity = Entity.EntityContactInfo(self.db) cont_tab = defaultdict(list) if not convert: convert = str if not verify: verify = bool for row in entity.list_contact_info(source_system=source_system, contact_type=contact_type): alias = convert(str(row['contact_alias'])) if alias and verify(alias): cont_tab[int(row['entity_id'])].append(alias) return dict((key, self.attr_unique(values, normalize=normalize)) for key, values in cont_tab.iteritems())
def _get_entity_name(self, entity_id, entity_type=None): """Fetch a human-friendly name for the specified entity. @type entity_id: int @param entity_id: entity_id we are looking for. @type entity_type: const.EntityType instance (or None) @param entity_type: Restrict the search to the specifide entity. This parameter is really a speed-up only -- entity_id in Cerebrum uniquely determines the entity_type. However, should we know it, we save 1 db lookup. @rtype: str @return: Entity's name, obviously :) If none is found a magic string 'notfound:<entity id>' is returned (it's not perfect, but it's better than nothing at all). """ if entity_type is None: ety = Entity.Entity(self.db) try: ety.find(entity_id) entity_type = self.const.EntityType(ety.entity_type) except Errors.NotFoundError: return "notfound:%d" % entity_id if entity_type == self.const.entity_account: acc = self._get_account(entity_id, idtype='id') return acc.account_name elif entity_type in (self.const.entity_group, ): group = self._get_group(entity_id, idtype='id') return group.group_name elif entity_type == self.const.entity_disk: disk = Factory.get('Disk')(self.db) disk.find(entity_id) return disk.path elif entity_type == self.const.entity_host: host = Factory.get('Host')(self.db) host.find(entity_id) return host.name elif entity_type == self.const.entity_person: person = Factory.get('Person')(self.db) person.find(entity_id) return person.get_name(self.const.system_cached, self.const.name_full) # TODO: This should NOT be put in bofhd_core, as it should not require # the Email module! Subclassing? This is only a quickfix: if hasattr(self.const, 'entity_email_target'): if entity_type == self.const.entity_email_target: etarget = Factory.get('EmailTarget')(self.db) etarget.find(entity_id) return '%s:%s' % (str(etarget.get_target_type_name()), self._get_entity_name( etarget.get_target_entity_id())) elif entity_type == self.const.entity_email_address: ea = Email.EmailAddress(self.db) ea.find(entity_id) return ea.get_address() # Okey, we've run out of good options. Let's try a sensible fallback: # many entities have a generic name in entity_name. Let's use that: try: etname = type("entity_with_name", (Entity.EntityName, Entity.Entity), dict()) etname = etname(self.db) etname.find(entity_id) if etname.get_names(): # just grab any name. We don't really have a lot of choice. return etname.get_names()[0]["name"] else: # ... and if it does not exist -- return the id. We are out of # options at this point. return "%s:%s" % (entity_type, entity_id) except Errors.NotFoundError: return "notfound:%d" % entity_id # NOTREACHED assert False
def __init__(self, *args, **kwargs): super(ADfuSync, self).__init__(*args, **kwargs) self.person = Factory.get('Person')(self.db) self.qua = Entity.EntityQuarantine(self.db) self.ou = Factory.get('OU')(self.db)