def test_admin_io_error(self): try: os.rename('/etc/ldap.secret', '/etc/ldap.secret.test') with self.assertRaises(ConnectionError) as cm: UDM.admin() assert str(cm.exception) == 'Could not read secret file' finally: os.rename('/etc/ldap.secret.test', '/etc/ldap.secret')
def test_machine_down_error(self): assert call(['systemctl', 'stop', 'slapd']) == 0 try: with self.assertRaises(ConnectionError) as cm: UDM.machine() assert str(cm.exception) == 'The LDAP Server is not running' finally: assert call(['systemctl', 'start', 'slapd']) == 0
def test_machine_credentials_error(self): pw = open('/etc/machine.secret').read() try: open('/etc/machine.secret', 'w').write('garbage') with self.assertRaises(ConnectionError) as cm: UDM.machine() assert str(cm.exception) == 'Credentials invalid' finally: open('/etc/machine.secret', 'w').write(pw)
def test_credentials_error(self): username = uts.random_name() password = uts.random_name() with self.assertRaises(ConnectionError) as cm: UDM.credentials(identity=username, password=password) assert str(cm.exception) == 'Cannot get DN for username' with self.assertRaises(ConnectionError) as cm: UDM.credentials(identity='Administrator', password=password) assert str(cm.exception) == 'Credentials invalid'
def test_credentials(self): password = uts.random_name() dn, username = self.udm_test.create_user(password=password) mod = UDM.credentials(identity=username, password=password).version(0).get('users/user') assert mod.connection.binddn == dn password = uts.random_name() dn, username = self.udm_test.create_user(password=password) mod = UDM.credentials(identity=dn, password=password).version(0).get('users/user') assert mod.connection.binddn == dn
def test_caching(self): assert UDM.admin().version(0).get('users/user') is UDM.admin().version( 0).get('users/user') assert UDM.admin().version(0).get( 'users/user') is not UDM.admin().version(1).get('users/user') assert UDM.admin().version(1).get('users/user') is UDM.admin().version( 1).get('users/user') assert UDM.admin().version(0).get( 'users/user') is not UDM.admin().version(0).get('groups/group') assert UDM.admin().version(0).get( 'users/user') is not UDM.machine().version(0).get('users/user')
def test_non_existing_dn(self): ucr_test = UCSTestConfigRegistry() ucr_test.load() udm = UDM.admin().version(1) with self.assertRaises(NoObject): udm.obj_by_dn('cn=fantasy,' + ucr_test['ldap/hostdn'])
def setUpClass(cls): cls.udm = UDM.admin().version(1) user_mod1 = cls.udm.get('users/user') assert user_mod1.__class__.__name__ == 'UsersUserModule', 'Wrong UDM module.' user_mod2 = cls.udm.get('users/user') assert user_mod1 is user_mod2, 'UDM module object cache miss.' cls.udm_test = UCSTestUDM() cls.ucr_test = UCSTestConfigRegistry() cls.ucr_test.load() try: cls.mail_domain = cls.ucr_test['mail/hosteddomains'].split()[0] except (AttributeError, IndexError): cls.mail_domain = cls.ucr_test['domainname'] try: cls.udm_test.create_object( 'mail/domain', position='cn=domain,cn=mail,{}'.format( cls.ucr_test['ldap/base']), name=cls.mail_domain, wait_for_replication=True) except UCSTestUDM_CreateUDMObjectFailed as exc: print('Creating mail domain {!r} failed: {}'.format( cls.mail_domain, exc))
def test_modify_user_homePostalAddress_as_dict(self): addresses = [ PostalAddress(random_string(), random_string(), random_string()), PostalAddress(random_string(), random_string(), random_string()), PostalAddress(random_string(), random_string(), random_string()), ] dn, username = self.udm_test.create_user() utils.verify_ldap_object( dn, expected_attr={ 'uid': [username], 'homePostalAddress': [], }, ) obj = UDM.admin().version(1).get('users/user').get(dn) assert username == obj.props.username obj.props.homePostalAddress.extend([ad._asdict() for ad in addresses]) obj.save() utils.verify_ldap_object( dn, expected_attr={ 'homePostalAddress': [ '{street}${zipcode}${city}'.format(**ad._asdict()) for ad in addresses ], }, )
def send_verification_token(self, username): MODULE.info("send_verification_token(): username: {}".format(username)) ucr.load() if ucr.is_false('umc/self-service/account-verification/backend/enabled', True): msg = _('The account verification was disabled via the Univention Configuration Registry.') MODULE.error('send_verification_token(): {}'.format(msg)) raise UMC_Error(msg) invalid_information = { 'success': False, 'failType': 'INVALID_INFORMATION' } users_mod = UDM.machine().version(2).get('users/user') try: user = users_mod.get_by_id(username) except NoObject: return invalid_information try: email = user.props.PasswordRecoveryEmail except AttributeError: return invalid_information else: if not email: return invalid_information self.send_message(username, 'verify_email', email, raise_on_success=False) return { 'success': True, 'data': { 'username': username, } }
def setUpClass(cls): # we want to use only 1 class for all UDM modules cls.udm = UDM.admin().version(0) cls.udm._module_object_cache.clear() univention.admin.modules.update() cls.avail_modules = sorted( [mod for mod in univention.admin.modules.modules.keys()])
def test_without_object_type(self): ucr_test = UCSTestConfigRegistry() ucr_test.load() udm = UDM.admin().version(1) with self.assertRaises(NoObject): udm.obj_by_dn('cn=backup,%s' % ucr_test['ldap/base'])
def _check_copied_user(orig_dn, orig_username, copied_username): attribute_list = [ 'title', 'initials', 'preferredDeliveryMethod', 'pwdChangeNextLogin', 'employeeNumber', 'homePostalAddress', 'mobileTelephoneNumber', 'pagerTelephoneNumber', 'birthday', 'jpegPhoto', 'unixhome', 'userCertificate', 'certificateIssuerCountry', 'certificateIssuerState', 'certificateIssuerLocation', 'certificateIssuerOrganisation', 'certificateIssuerMail', 'certificateSubjectCountry', 'certificateSubjectState', 'certificateSubjectLocation', 'certificateSubjectOrganisation', 'certificateSubjectOrganisationalUnit', 'certificateSubjectCommonName', 'certificateSubjectMail', 'certificateDateNotBefore', 'certificateDateNotAfter', 'certificateVersion', 'certificateSerial' ] udm_admin = UDM.admin().version(1) orig_user = list( udm_admin.get('users/user').search('username=%s' % (orig_username, )))[0] copied_user = list( udm_admin.get('users/user').search('username=%s' % (copied_username, )))[0] orig_user_props = orig_user.props.__dict__ copied_user_props = copied_user.props.__dict__ for attribute in attribute_list: print("Checking that %s is not copied" % (attribute, )) if attribute != 'jpegPhoto': assert orig_user_props[attribute] != copied_user_props[attribute] else: assert copied_user_props[attribute] is None return copied_user.__dict__['dn']
def user_info(udm): ''' The created user will have all properties set that were removed from being copyable (Bug 49823)''' dn, username = udm.create_user( gecos='', displayName='', title='Univ', initials='U.U.', preferredDeliveryMethod='any', pwdChangeNextLogin='******', employeeNumber='42', homePostalAddress='Mary-Somervile 28359 Bremen', mobileTelephoneNumber='+49 421 12345-0', pagerTelephoneNumber='+49 421 23456-0', birthday='2000-01-01', jpegPhoto= '/9j/4AAQSkZJRgABAQAAAQABAAD/4QBiRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAEAAAITAAMAAAABAAEAAAAAAAAAAAABAAAAAQAAAAEAAAAB/9sAQwADAgICAgIDAgICAwMDAwQGBAQEBAQIBgYFBgkICgoJCAkJCgwPDAoLDgsJCQ0RDQ4PEBAREAoMEhMSEBMPEBAQ/9sAQwEDAwMEAwQIBAQIEAsJCxAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ/8AAEQgAAQABAwERAAIRAQMRAf/EABQAAQAAAAAAAAAAAAAAAAAAAAX/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFAEBAAAAAAAAAAAAAAAAAAAACP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/ADBHP1//2Q==', unixhome='/home/username', userCertificate= "MIICEjCCAXsCAg36MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNjU0WhcNMTcwODIxMDUyNjU0WjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAm/xmkHmEQrurE/0re/jeFRLl8ZPjBop7uLHhnia7lQG/5zDtZIUC3RVpqDSwBuw/NTweGyuP+o8AG98HxqxTBwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABS2TLuBeTPmcaTaUW/LCB2NYOy8GMdzR1mx8iBIu2H6/E2tiY3RIevV2OW61qY2/XRQg7YPxx3ffeUugX9F4J/iPnnu1zAxxyBy2VguKv4SWjRFoRkIfIlHX0qVviMhSlNy2ioFLy7JcPZb+v3ftDGywUqcBiVDoea0Hn+GmxZACg==", ) copied_username = "******" % (username, ) yield { 'orig_dn': dn, 'orig_username': username, 'copied_username': copied_username } for user in UDM.admin().version(1).get('users/user').search( 'username=%s' % (copied_username, )): user.delete()
def test_local(self): password = uts.random_name() dn, username = self.udm_test.create_user(password=password) server = self.ucr_test['ldap/server/name'] port = self.ucr_test['ldap/server/port'] mod = UDM.credentials(identity=username, password=password, server=server, port=port).version(0).get('users/user') assert mod.connection.binddn == dn
def test_error_in_version(self): with self.assertRaises(NoApiVersionSet): UDM.admin().get('users/user') with self.assertRaises(ApiVersionNotSupported): UDM.admin().version('1') with self.assertRaises(ApiVersionMustNotChange): UDM.admin().version(0).version(1) with self.assertRaises(ApiVersionNotSupported): UDM.admin().version(20).get('users/user')
def test_existing_dn(self): ucr_test = UCSTestConfigRegistry() ucr_test.load() udm = UDM.admin().version(1) obj = udm.obj_by_dn(ucr_test['ldap/hostdn']) assert obj._udm_module == udm.get('computers/domaincontroller_master') assert obj.props.name == ucr_test['hostname']
def simple_udm(ucr): # type: () -> UDM account = utils.UCSTestDomainAdminCredentials() return UDM.credentials( account.binddn, account.bindpw, ucr["ldap/base"], ucr["ldap/master"], ucr["ldap/master/port"], ).version(1)
def udm_schema_obj_exists(name): name = os.path.splitext(os.path.basename(name))[0] udm = UDM.admin().version(1) try: udm.get('settings/ldapschema').get_by_id(name) except NoObject: return False else: return True
def run_module(): module_args = dict( module=dict(type='str', required=True), position=dict(type='str', required=False), set_properties=dict(type='list', required=False), unset_properties=dict(type='list', required=False), dn=dict(type='str', required=False), filter=dict(type='str', required=False), state=dict(type='str', default='present', coices=['present', 'absent'], required=False), options=dict(type='list', required=False), policies=dict(type='list', required=False), ) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) result = dict(changed=False, meta=dict(changed_objects=[]), message='') if not have_udm: module.fail_json(msg='The Python "univention.udm" is not available', **result) params = module.params udm_con = UDM.admin() # connection to UDM udm_con.version(1) udm_mod = udm_con.get(module.params['module']) stats = Stats() if params['state'] == 'present': if params['dn']: _create_or_modify_object(udm_mod, module, stats) if params['filter']: for obj in udm_mod.search(params['filter']): _modify_object(udm_mod, module, obj, stats) if not params['dn'] and not params['filter']: properties = { x['property']: x['value'] for x in params['set_properties'] } obj = None obj_id = properties.get('uid') or properties.get('name') if obj_id: obj = udm_mod.get_by_id(obj_id) if obj: _modify_object(udm_mod, module, obj, stats) else: _create_object(udm_mod, module, stats) elif params['state'] == 'absent': _remove_objects(udm_mod, module, stats) result['meta']['changed_objects'] = stats.changed_objects result['meta']['message'] = 'changed objects: %s' " ".join( stats.changed_objects) module.exit_json(**result)
def get_other_servers(): with UCSTestConfigRegistry() as ucr: role = ucr.get('server/role') udm = UDM.machine().version(2) others = [] for mod in [ 'computers/domaincontroller_master', 'computers/domaincontroller_backup', 'computers/domaincontroller_slave' ]: if role not in mod: others.extend(list(udm.get(mod).search())) return others
def get_writable_udm(binddn=None, bindpwdfile=None): # type: (Optional[str], Optional[str]) -> univention.udm.udm.UDM if binddn: if not bindpwdfile: error('"binddn" provided but not "bindpwdfile".') try: with open(bindpwdfile, 'r') as f: bindpwd = f.read().strip() except IOError as err: error('Could not open "bindpwdfile" "%s": %s' % ( bindpwdfile, err, )) ucr = ConfigRegistry() ucr.load() try: udm = UDM.credentials(binddn, bindpwd, ucr.get('ldap/base'), ucr.get('ldap/master'), ucr.get('ldap/master/port')) except univention.udm.exceptions.ConnectionError as err: error( 'Could not connect to server "%s" with provided "binddn" "%s" and "bindpwdfile" "%s": %s' % ( ucr.get('ldap/master'), binddn, bindpwdfile, err, )) else: try: udm = UDM.admin() except univention.udm.exceptions.ConnectionError as err: error( 'Could not create a writable connection to UDM on this server. Try to provide "binddn" and "bindpwdfile": %s' % (err, )) udm.version(2) return udm
def _deregister_account(self, username): try: user = UDM.admin().version(2).get('users/user').get_by_id(username) user.props.DeregisteredThroughSelfService = 'TRUE' user.props.DeregistrationTimestamp = datetime.datetime.strftime(datetime.datetime.utcnow(), DEREGISTRATION_TIMESTAMP_FORMATTING) user.props.disabled = True user.save() try: self._notify_about_account_deregistration(user.props.username, user.props.PasswordRecoveryEmail) except Exception: MODULE.error("_deregister_account(): sending of email failed: {}".format(traceback.format_exc())) return except Exception: MODULE.error("_deregister_account(): {}".format(traceback.format_exc())) raise
def list_users(self): """ convenience function for the username entry. Lists all user names. We don't return this as an array of {id, label} tuples because: (1) id and label are always the same here (2) at the frontend, we must do some postprocessing, and an array is easier to handle. (3) the ComboBox is able to handle a plain array. """ ucr = ConfigRegistry() ucr.load() identity = ucr.get('ldap/hostdn') password = open('/etc/machine.secret').read().rstrip('\n') server = ucr.get('ldap/server/name') udm = UDM.credentials(identity, password, server=server).version(1) users = udm.get('users/user').search() return [user.props.username for user in users]
def verify_contact(self, token, username, method): MODULE.info('verify_contact(): token: {} username: {} method: {}'.format(token, username, method)) ucr.load() if ucr.is_false('umc/self-service/account-verification/backend/enabled', True): msg = _('The account verification was disabled via the Univention Configuration Registry.') MODULE.error('verify_contact(): {}'.format(msg)) raise UMC_Error(msg) users_mod = UDM.admin().version(1).get('users/user') try: user = users_mod.get_by_id(username) except NoObject: return { 'success': False, 'failType': 'INVALID_INFORMATION', } next_steps = ucr.get('umc/self-service/account-verification/next-steps/%s' % self.locale.language, '') if not next_steps: next_steps = ucr.get('umc/self-service/account-verification/next-steps', '') plugin = self._get_send_plugin(method) if getattr(user.props, plugin.udm_property) == 'TRUE': # cleanup. map property to actual boolean? return { 'success': True, 'successType': 'ALREADY_VERIFIED', 'data': { 'username': username, 'nextSteps': next_steps, } } self._check_token(username, token, token_application=plugin.message_application()) setattr(user.props, plugin.udm_property, 'TRUE') user.save() self.db.delete_tokens(token=token, username=username) return { 'success': True, 'successType': 'VERIFIED', 'data': { 'username': username, 'nextSteps': next_steps, } }
def get_ldap_connections(): # type: () -> List[univention.admin.uldap.access] udm = UDM.machine().version(2) connections = [] modules = [ 'computers/domaincontroller_master', 'computers/domaincontroller_backup', 'computers/domaincontroller_slave' ] for module in modules: for comp in udm.get(module).search(): try: lo = univention.admin.uldap.access( host=comp.props.fqdn, base=udm.connection.base, binddn=udm.connection.binddn, bindpw=udm.connection.bindpw) except ldap.SERVER_DOWN: warning( 'Server "%s" is not reachable. The "authTimestamp" will not be read from it. Continuing.' % (comp.props.fqdn, )) else: connections.append(lo) return connections
def setUpClass(cls): cls.udm = UDM.admin().version(2)
# /usr/share/common-licenses/AGPL-3; if not, see # <https://www.gnu.org/licenses/>. # # this is just a "one-shot", non-packaged script # that generates the DiaryEvent objects on a live UCS Master # python $0 2> errors >> /usr/lib/python2.7/dist-packages/univention/admindiary/events.py from __future__ import print_function import sys from univention.lib.i18n import Translation from univention.udm import UDM from univention.udm.helpers import get_all_udm_module_names udm = UDM.admin().version(2) translation = Translation(None) def modules(): for m in get_all_udm_module_names(): yield udm.get(m)._orig_udm_module def print_events(m): name = m.module icon = 'domain' if name.startswith('users/'): icon = 'users' if name.startswith('groups/'):
def setUpClass(cls): cls.udm = UDM.admin().version(1) cls.udm_test = UCSTestUDM() cls.ucr_test = UCSTestConfigRegistry() cls.ucr_test.load()
def test_machine(self): mod = UDM.machine().version(0).get('users/user') assert mod.connection.binddn == self.ucr_test['ldap/hostdn']