def test_password_long_password_uniqueness(self): """ UTILS | Test uniqueness of long generated passwords """ passwords = [] duplicates = [] i = 0 while i < 1000: passw = password.mkpasswd(30) if passw in duplicates: pass elif passw in passwords: duplicates.append(passw) print "Found duplicate: %s" % passw else: passwords.append(passw) i += 1 time.sleep(0.001) # Race condition, but we're using random numbers.. print "Found %s duplicates" % len(duplicates) nosetools.eq_(0, len(duplicates), "1000 passwords")
def gen_salt(self): allowed = "".join([chr(x) for x in range(0, 255)]) salt = mkpasswd(64, allowed_chars=allowed) h = hashlib.new(self.algo) h.update(salt) return h.hexdigest()
def test_password_conforms(self): """ UTILS | Test whether passwords conform to defined specifications """ digits = "0123456789" lower = "abcdefghijklmnopqrstuvwxyz" upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" num_digits = 0 num_lower = 0 num_upper = 0 num_invalid = 0 passw = password.mkpasswd(10, 3, 3, 3) nosetools.eq_(10, len(passw)) for char in passw: if char in digits: num_digits += 1 elif char in lower: num_lower += 1 elif char in upper: num_upper += 1 else: num_invalid += 1 nosetools.assert_true(num_digits > 2) nosetools.assert_true(num_lower > 2) nosetools.assert_true(num_upper > 2) nosetools.eq_(0, num_invalid)
def create_user(self, username, password): """ Create a new user account with a given username and password. The salt will be generated randomly, at a length of 64. Creation will fail if the user account already exists. :param username: The username of the account :param password: The password to be used :type username: str :type password: str :return: Whether the account was created successfully :rtype: bool """ username = username.lower() with self.data: if username in self.data: return False salt = mkpasswd(64, 21, 22, 21) hashed = self.hash(salt, password) self.data[username] = {"password": hashed, "salt": salt} return True
def create_user(self, username, password): """ Create a new user account with a given username and password. The salt will be generated randomly, at a length of 64. Creation will fail if the user account already exists. :param username: The username of the account :param password: The password to be used :type username: str :type password: str :return: Whether the account was created successfully :rtype: bool """ username = username.lower() with self.data: if username in self.data: return False salt = mkpasswd(64, 21, 22, 21) hashed = self.hash(salt, password) self.data[username] = { "password": hashed, "salt": salt } return True
def create_superadmin_account(self): """ Creates the default superadmin account, if no accounts exist. If the superadmin setting is enabled, this account will have access to all available permissions. It's given a 32-length randomly generated password. We test for uniqueness in the unit tests! """ if len(self.data): if _("superadmin") in self.data: self.plugin.logger.warn(_("Superadmin account exists!")) self.plugin.logger.warn( _("You should remove this account " "as soon as possible!")) return self.plugin.logger.info( _("Generating a default auth account and " "password.")) self.plugin.logger.info( _("You will need to either use this to add " "permissions to your user account, or just " "create an account and edit the permissions " "file.")) self.plugin.logger.info( _("Remember to delete this account when " "you've created your own admin account!")) password = mkpasswd(32) self.create_user(_("superadmin"), password) self.plugin.logger.info("============================================") self.plugin.logger.info(_("Super admin username: superadmin")) self.plugin.logger.info(_("Super admin password: %s") % password) self.plugin.logger.info("============================================") p_handler = self.plugin.get_permissions_handler() if p_handler: if not p_handler.create_user(_("superadmin")): self.plugin.logger.warn( _("Unable to create permissions " "section for the superadmin " "account!")) if not p_handler.set_user_option(_("superadmin"), _("superadmin"), True): self.plugin.logger.warn( _("Unable to set 'superadmin' flag on " "the superadmin account!")) else: self.plugin.logger.warn( _("Unable to set permissions for the " "superadmin account as the bundled " "permissions system isn't being used.")) self.plugin.logger.warn(_("Please do this manually!"))
def create_session(self, username, remember=False): username = username.lower() key = mkpasswd(100, 32, 34, 34) s = { "username": username, "remember": remember, "time": time.mktime(datetime.datetime.now().timetuple()) } with self.sessions: self.sessions[key] = s return key
def create_superadmin_account(self): """ Creates the default superadmin account, if no accounts exist. If the superadmin setting is enabled, this account will have access to all available permissions. It's given a 32-length randomly generated password. We test for uniqueness in the unit tests! """ if len(self.data): if _("superadmin") in self.data: self.plugin.logger.warn(_("Superadmin account exists!")) self.plugin.logger.warn(_("You should remove this account " "as soon as possible!")) return self.plugin.logger.info(_("Generating a default auth account and " "password.")) self.plugin.logger.info(_("You will need to either use this to add " "permissions to your user account, or just " "create an account and edit the permissions " "file.")) self.plugin.logger.info(_("Remember to delete this account when " "you've created your own admin account!")) password = mkpasswd(32, 11, 11, 10) self.create_user(_("superadmin"), password) self.plugin.logger.info("============================================") self.plugin.logger.info(_("Super admin username: superadmin")) self.plugin.logger.info(_("Super admin password: %s") % password) self.plugin.logger.info("============================================") p_handler = self.plugin.get_permissions_handler() if p_handler: if not p_handler.create_user(_("superadmin")): self.plugin.logger.warn(_("Unable to create permissions " "section for the superadmin " "account!")) if not p_handler.set_user_option(_("superadmin"), _("superadmin"), True): self.plugin.logger.warn(_("Unable to set 'superadmin' flag on " "the superadmin account!")) else: self.plugin.logger.warn(_("Unable to set permissions for the " "superadmin account as the bundled " "permissions system isn't being used.")) self.plugin.logger.warn(_("Please do this manually!"))
def create_key(self, username, tries=0): username = username.lower() if tries > 4: raise KeyError("Unable to generate a unique API key!") key = mkpasswd(32) if key in self.data: time.sleep(0.01) return self.create_key(username, tries=tries + 1) with self.data: self.data[key] = username return key
def change_password(self, username, old, new): """ Change a user's password. This function requires the user's old password, and will fail if the user's account doesn't exist or the old password doesn't match. A new salt will also be generated. :param username: The username of the account :param old: The old password to check :param new: The new password to change to :type username: str :type old: str :type new: str :return: Whether the password was changed :rtype: bool """ username = username.lower() with self.data: if username not in self.data: return False user_data = self.data[username] calculated = self.hash(user_data["salt"], old) real_hash = user_data["password"] if calculated != real_hash: return False salt = mkpasswd(64, 21, 22, 21) hashed = self.hash(salt, new) self.data[username]["password"] = hashed self.data[username]["salt"] = salt return True
def load(self): if "secret" not in self.data: self.logger.warn("Generating secret. DO NOT SHARE IT WITH ANYONE!") self.logger.warn("It's stored in data/plugins/web/data.json - " "keep this file secure!") with self.data: self.data["secret"] = mkpasswd(60, 20, 20, 20) self.template_loader = TemplateLoader(self) if self.config.get("output_requests", True): log_function = self.log_request else: log_function = self.null_log self.application = Application( list(self.handlers.items()), # Handler list ## General settings xheaders=True, log_function=log_function, gzip=True, # Are there browsers that don't support this now? # error_handler=ErrorHandler, ## Security settings cookie_secret=self.data["secret"], login_url="/login", ## Template settings template_loader=self.template_loader, ## Static file settings static_path="web/static" ) if self.config.get("hosted", False): hosted = self.config["hosted"] if isinstance(hosted, dict): self.interface = os.environ.get(hosted["hostname"], False) self.port = os.environ.get(hosted["port"], False) if not self.interface: self.logger.error( "Unknown env var: %s" % hosted["hostname"] ) return False if not self.port: self.logger.error( "Unknown env var: %s" % hosted["port"] ) return False else: if hosted in ["openshift"]: self.interface = os.environ.get("OPENSHIFT__IP", False) self.port = os.environ.get("OPENSHIFT__PORT", False) if not self.interface: self.logger.error( "Unknown env var: OPENSHIFT__IP - Are you on " "OpenShift?" ) return False if not self.port: self.logger.error( "Unknown env var: OPENSHIFT__PORT - Are you on " "OpenShift?" ) return False else: self.logger.error("Unknown hosted service: %s" % hosted) return False else: if self.config.get("hostname", "0.0.0.0").strip() == "0.0.0.0": self.interface = "" else: self.interface = self.config.get("hostname") self.listen_port = self.config.get("port", 8080) return True