def preprocess_entity(self, entity): """return a dictionary to use as extra argument to cursor.execute to insert/update an entity into a SQL database """ attrs = {} eschema = entity.e_schema converters = getattr(self.dbhelper, 'TYPE_CONVERTERS', {}) for attr, value in entity.cw_edited.items(): if value is not None and eschema.subjrels[attr].final: atype = str(entity.e_schema.destination(attr)) if atype in converters: # It is easier to modify preprocess_entity rather # than add_entity (native) as this behavior # may also be used for update. value = converters[atype](value) elif atype == 'Password': # XXX could be done using a TYPE_CONVERTERS callback # if value is a Binary instance, this mean we got it # from a query result and so it is already encrypted if isinstance(value, Binary): value = value.getvalue() else: value = crypt_password(value) value = self._binary(value) elif isinstance(value, Binary): value = self._binary(value.getvalue()) attrs[SQL_PREFIX + str(attr)] = value attrs[SQL_PREFIX + 'eid'] = entity.eid return attrs
def extentities_generator(self): self.debug('processing ldapfeed source %s %s', self.source, self.searchgroupfilterstr) # get existing users *not* managed by this source non_managed_users = dict( self._cw.execute( 'Any L, SN WHERE' ' U is CWUser, U login L,' ' U cw_source S, S name SN,' ' NOT S eid %(eid)s', {'eid': self.source.eid}, build_descr=False)) # generate users and email addresses for userdict in self.user_source_entities_by_extid.values(): attrs = self.ldap2cwattrs(userdict, 'CWUser') login = attrs['login'][0] try: source = non_managed_users[login] except KeyError: pass else: self.error( 'not synchronizing user %s. User already exist in source %s', login, source) continue pwd = attrs.get('upassword') if not pwd: # generate a dumb password if not fetched from ldap (see # userPassword) pwd = crypt_password(generate_password()) attrs['upassword'] = set([pwd]) self._source_uris.pop(userdict['dn'], None) extuser = importer.ExtEntity('CWUser', userdict['dn'].encode('ascii'), attrs) extuser.values['owned_by'] = set([extuser.extid]) for extemail in self._process_email(extuser, userdict): yield extemail groups = list( filter(None, [ self._get_group(name) for name in self.source.user_default_groups ])) if groups: extuser.values['in_group'] = groups yield extuser # generate groups for groupdict in self.group_source_entities_by_extid.values(): attrs = self.ldap2cwattrs(groupdict, 'CWGroup') self._source_uris.pop(groupdict['dn'], None) extgroup = importer.ExtEntity('CWGroup', groupdict['dn'].encode('ascii'), attrs) yield extgroup # record group membership for later insertion members = groupdict.get(self.source.group_rev_attrs['member'], ()) self._group_members[attrs['name']] = members
def run(self, args): """run the command with its specific arguments""" from cubicweb.server.utils import crypt_password, manager_userpasswd appid = args[0] config = ServerConfiguration.config_for(appid) sourcescfg = config.read_sources_file() try: adminlogin = sourcescfg['admin']['login'] except KeyError: print('-> Error: could not get cubicweb administrator login.') sys.exit(1) cnx = source_cnx(sourcescfg['system']) driver = sourcescfg['system']['db-driver'] dbhelper = get_db_helper(driver) cursor = cnx.cursor() # check admin exists cursor.execute("SELECT * FROM cw_CWUser WHERE cw_login=%(l)s", {'l': adminlogin}) if not cursor.fetchall(): print("-> error: admin user %r specified in sources doesn't exist " "in the database" % adminlogin) print(" fix your sources file before running this command") cnx.close() sys.exit(1) if self.config.password is None: # ask for a new password msg = 'new password for %s' % adminlogin _, pwd = manager_userpasswd(adminlogin, confirm=True, passwdmsg=msg) else: pwd = self.config.password try: cursor.execute( "UPDATE cw_CWUser SET cw_upassword=%(p)s WHERE cw_login=%(l)s", { 'p': dbhelper.binary_value(crypt_password(pwd)), 'l': adminlogin }) sconfig = Configuration(options=USER_OPTIONS) sconfig['login'] = adminlogin sconfig['password'] = pwd sourcescfg['admin'] = sconfig config.write_sources_file(sourcescfg) except Exception as ex: cnx.rollback() import traceback traceback.print_exc() print('-> an error occurred:', ex) else: cnx.commit() print('-> password reset, sources file regenerated.') cnx.close()
def add_user(self, user_name, password, group_name="users"): """ Add a new user in the database. Parameters ---------- user_name: str the login of the user in the database. password: str the password of the user in the database. group_name: str the database group name the user will be rattached to. """ # Get the activated State entity rql = "Any X Where X is State, X name 'activated'" rset = self.session.execute(rql) if rset.rowcount != 1: raise Exception("Can't insert users, no activated State entity " "detected.") state_eid = rset[0][0] # Insert the user crypted = crypt_password(password) user_entity, is_created = self._get_or_create_unique_entity( rql=("Any X Where X is CWUser, X login " "'{0}'".format(user_name)), check_unicity=True, entity_name="CWUser", login=unicode(user_name), upassword=Binary(crypted)) # If the user is created, add relation with the State entity if is_created: # Activate the account self._set_unique_relation( user_entity.eid, "in_state", state_eid, check_unicity=False) # Add the user to the default group rset = self.session.execute( "Any X Where X is CWGroup, X name '{0}'".format(group_name)) if rset.rowcount != 1: raise Exception( "Can't insert user '{0}' in group '{1}', got {2} " "matches.".format(user_name, group_name, rset.rowcount)) group_eid = rset[0][0] self._set_unique_relation( user_entity.eid, "in_group", group_eid, check_unicity=False)
def test_crypt(self): for hash in ( utils.crypt_password('xxx'), # default sha512 b'ab$5UsKFxRKKN.d8iBIFBnQ80', # custom md5 b'ab4Vlm81ZUHlg', # DES ): self.assertEqual(utils.crypt_password('xxx', hash), hash) self.assertEqual(utils.crypt_password(u'xxx', hash), hash) self.assertEqual( utils.crypt_password(u'xxx', hash.decode('ascii')), hash.decode('ascii')) self.assertEqual(utils.crypt_password('yyy', hash), b'') # accept any password for empty hashes (is it a good idea?) self.assertEqual(utils.crypt_password('xxx', ''), '') self.assertEqual(utils.crypt_password('yyy', ''), '')
def _process_ldap_item(self, dn, iterator): """Turn an ldap received item into a proper dict.""" itemdict = {'dn': dn} for key, value in iterator: if self.user_attrs.get( key) == 'upassword': # XXx better password detection value = value[0].encode('utf-8') # we only support ldap_salted_sha1 for ldap sources, see: server/utils.py if not value.startswith(b'{SSHA}'): value = utils.crypt_password(value) itemdict[key] = Binary(value) elif self.user_attrs.get(key) == 'modification_date': itemdict[key] = datetime.strptime(value[0], '%Y%m%d%H%M%SZ') else: if len(value) == 1: itemdict[key] = value = value[0] else: itemdict[key] = value # we expect memberUid to be a list of user ids, make sure of it member = self.group_rev_attrs['member'] if isinstance(itemdict.get(member), str): itemdict[member] = [itemdict[member]] return itemdict
def import_data(self): """ Method that import the users in cw. .. note:: This procedure create a user as a 'CWUser' entity which is related to different groups through the 'in_group' relation. | .. image:: ../schemas/users.png :width: 500px :align: center :alt: schema .. warning:: This procedure expect that the 'CWGroup' of interest are already created. """ # Get the activated State entity rql = "Any X Where X is State, X name 'activated'" rset = self.session.execute(rql) if rset.rowcount != 1: logging.error("Can't insert users, no activated State entity detected.") raise Exception("Can't insert users, no activated State entity " "detected.") state_eid = rset[0][0] # Go through the goup names nb_of_users = float(len(self.users)) maxsize = max([len(name) for name in self.users]) cnt_user = 1.0 for user_name, user_item in self.users.iteritems(): # Print a progress bar self._progress_bar( cnt_user / nb_of_users, title="{0}(users)".format(user_name), bar_length=40, maxsize=maxsize + 7 ) cnt_user += 1.0 # Create the user crypted = crypt_password(user_item["password"]) user_entity, is_created = self._get_or_create_unique_entity( rql=("Any X Where X is CWUser, X login " "'{0}'".format(user_item["login"])), check_unicity=True, entity_name="CWUser", login=unicode(user_item["login"]), upassword=Binary(crypted), ) # If the user is created, add relation with the State entity if is_created: self._set_unique_relation(user_entity.eid, "in_state", state_eid, check_unicity=False) # Go through group names for group_name in user_item["group_names"]: # Check if the group exists rql = "Any X Where X is CWGroup, X name '{0}'".format(group_name) # Execute the rql request rset = self.session.execute(rql) # The request returns some data -> do nothing if rset.rowcount != 1: logging.error( "Can't insert user '{0}' in group '{1}', got {2} " "matches.".format(user_name, group_name, rset.rowcount) ) continue # Get the group entity group_eid = rset[0][0] # > add relation with the user self._set_unique_relation(user_entity.eid, "in_group", group_eid, check_unicity=True) print # new line after last progress bar update
def import_data(self): """ Method that import the users in cw. .. note:: This procedure create a user as a 'CWUser' entity which is related to different groups through the 'in_group' relation. | .. image:: ../schemas/users.png :width: 500px :align: center :alt: schema .. warning:: This procedure expect that the 'CWGroup' of interest are already created. """ # Get the activated State entity rql = "Any X Where X is State, X name 'activated'" rset = self.session.execute(rql) if rset.rowcount != 1: logging.error( "Can't insert users, no activated State entity detected.") raise Exception("Can't insert users, no activated State entity " "detected.") state_eid = rset[0][0] # Go through the goup names nb_of_users = float(len(self.users)) maxsize = max([len(name) for name in self.users]) cnt_user = 1. for user_name, user_item in self.users.iteritems(): # Print a progress bar self._progress_bar( cnt_user / nb_of_users, title="{0}(users)".format(user_name), bar_length=40, maxsize=maxsize + 7) cnt_user += 1. # Create the user crypted = crypt_password(user_item["password"]) user_entity, is_created = self._get_or_create_unique_entity( rql=("Any X Where X is CWUser, X login " "'{0}'".format(user_item["login"])), check_unicity=True, entity_name="CWUser", login=unicode(user_item["login"]), upassword=Binary(crypted)) # If the user is created, add relation with the State entity if is_created: self._set_unique_relation(user_entity.eid, "in_state", state_eid, check_unicity=False) # Go through group names for group_name in user_item["group_names"]: # Check if the group exists rql = "Any X Where X is CWGroup, X name '{0}'".format(group_name) # Execute the rql request rset = self.session.execute(rql) # The request returns some data -> do nothing if rset.rowcount != 1: logging.error( "Can't insert user '{0}' in group '{1}', got {2} " "matches.".format(user_name, group_name, rset.rowcount)) continue # Get the group entity group_eid = rset[0][0] # > add relation with the user self._set_unique_relation(user_entity.eid, "in_group", group_eid, check_unicity=True) print # new line after last progress bar update
from __future__ import print_function from logilab.common.shellutils import generate_password from cubicweb.server.utils import crypt_password for user in rql('CWUser U WHERE U cw_source S, S name "system", U upassword P, U login L').entities(): salt = user.upassword.getvalue() if crypt_password('', salt) == salt: passwd = generate_password() print('setting random password for user %s' % user.login) user.set_attributes(upassword=passwd) commit()
import sys import getpass from cubicweb import Binary from cubicweb.server.utils import crypt_password if __args__: login = __args__.pop() else: login = raw_input("login? ") rset = rql('Any U WHERE U is CWUser, U login %(login)s', {'login': login}) if len(rset) != 1: sys.exit("user '%s' does not exist!" % login) pass1 = getpass.getpass(prompt='Enter new password? ') pass2 = getpass.getpass(prompt='Confirm? ') if pass1 != pass2: sys.exit("passwords don't match!") crypted = crypt_password(pass1) cwuser = rset.get_entity(0,0) cwuser.cw_set(upassword=Binary(crypted)) commit() print("password updated.")