def authenticate(passwordFile: HtpasswdFile, credentials: Credentials) -> None: """Checks a name and password combination against a password file. Returns if authentication succeeds. Raises `UnauthorizedLogin` if the given user name and password combination is not accepted. The hashed version of the password will be updated with a new hash function if the current one is depricated. """ name = credentials.name password = credentials.password try: checkPassword(password) except ValueError as ex: raise UnauthorizedLogin(ex) from ex # Have passlib check the password. When passed a None hash, it will # perform a dummy computation to keep the timing consistent. passwordFile.load_if_changed() correct, newHash = passwordFile.context.verify_and_update( password.encode(), passwordFile.get_hash(name)) if not correct: raise UnauthorizedLogin('Authentication failed') if newHash is not None: # Replace hash with better algorithm or config. passwordFile.set_hash(name, newHash) writePasswordFile(passwordFile)
class HtpasswdAuthenticator(object): """ Handles the user authentication for htpasswd files htpasswd is the location of the htpasswd to use """ def __init__(self): #try to locate the server config and load it server_folder = os.path.join(os.path.expanduser("~"), '.conan_server') server_conf = os.path.join(server_folder, "server.conf") htpasswd_location = os.path.join(server_folder, "plugins", "authentication", ".htpasswd") if os.path.exists(server_conf): conf = ConfigParser() conf.read(server_conf) new_loc = conf.get("server", "htpasswd_file") if os.path.exists(new_loc): htpasswd_location = new_loc self.htpasswd = HtpasswdFile(htpasswd_location) def valid_user(self, username, plain_password): """ username: Username to be authenticated plain_password: The password to authenticate with return: True if match False if don't """ # Update self.htpasswd.load_if_changed() # Verify return username in self.htpasswd.users() and \ self.htpasswd.check_password(username, plain_password)
def authenticate(self, request): """Authenticate the provided request.""" if (self.config.password_file is None or self.config.password_file == '.'): return True pwd_file = HtpasswdFile(self.config.password_file) pwd_file.load_if_changed() return pwd_file.check_password(*request.auth)
class TestAuthnz(object): def __init__(self, htpasswd_file=".htpasswd", perms_file=".repoperms", keys_file=".rsakeys"): self.htpasswd = HtpasswdFile(htpasswd_file) self.perms_file = perms_file self.keys_file = keys_file def can_read(self, username, path_info): return self._check_access(username, path_info, "r") def can_write(self, username, path_info): return self._check_access(username, path_info, "w") def _check_access(self, username, path_info, level): if username is None: username = "******" if path_info['repository_fs_path'] is None: return False repo = os.path.basename(path_info['repository_fs_path']) config = SafeConfigParser() config.read(self.perms_file) if not config.has_option(repo, username): return False return level in config.get(repo, username) def check_password(self, username, password): self.htpasswd.load_if_changed() return self.htpasswd.check_password(username, password) def check_publickey(self, username, keyblob): with open(self.keys_file, 'rb') as f: for line in f: try: user, key = line.split(':', 1) if (username == user.strip() and keyblob == keys.Key.fromString(data=key.strip() ).blob()): return True except: log.err(None, "Loading key failed") return False
class TestAuthnz(object): def __init__(self, htpasswd_file=".htpasswd", perms_file=".repoperms", keys_file=".rsakeys"): self.htpasswd = HtpasswdFile(htpasswd_file) self.perms_file = perms_file self.keys_file = keys_file def can_read(self, username, path_info): return self._check_access(username, path_info, "r") def can_write(self, username, path_info): return self._check_access(username, path_info, "w") def _check_access(self, username, path_info, level): if username is None: username = "******" if path_info['repository_fs_path'] is None: return False repo = os.path.basename(path_info['repository_fs_path']) config = SafeConfigParser() config.read(self.perms_file) if not config.has_option(repo, username): return False return level in config.get(repo, username) def check_password(self, username, password): self.htpasswd.load_if_changed() return self.htpasswd.check_password(username, password) def check_publickey(self, username, keyblob): with open(self.keys_file, 'rb') as f: for line in f: try: user, key = line.split(':', 1) if (username == user.strip() and keyblob == keys.Key.fromString(data=key.strip()).blob()): return True except: log.err(None, "Loading key failed") return False
class HtpasswdUsers(Component): implements(IUserAuthenticator) implements(IUserTranslator) implements(IUserStore) def __init__(self): config = self.get_component_config() if 'file' not in config: raise InsufficientConfiguration(missing='file', component=self.get_component_name()) self.htpasswd = HtpasswdFile(config['file']) def username_to_user(self, username): self.htpasswd.load_if_changed() if username in self.htpasswd.users(): return HtpasswdUser(self, username, username=username, full_name=username) def userid_to_user(self, userid): if userid is None or userid == '*': warnings.warn("You should not call this directly. Use cydra.get_user()", DeprecationWarning, stacklevel=2) return self.compmgr.get_user(userid='*') self.htpasswd.load_if_changed() if userid in self.htpasswd.users(): return HtpasswdUser(self, userid, username=userid, full_name=userid) else: # since the client was looking for a specific ID, # we return a dummy user object with empty data return User(self, userid, full_name='N/A') def groupid_to_group(self, groupid): pass def user_password(self, user, password): self.htpasswd.load_if_changed() return self.htpasswd.check_password(user.userid, password) def create_user(self, **kwargs): self.htpasswd.load_if_changed() userid = None if 'id' in kwargs: userid = kwargs['id'] elif 'username' in kwargs: userid = kwargs['username'] else: raise ValueError("No username/id specified") if userid in self.htpasswd.users(): raise ValueError("User with this id already exists") else: self.htpasswd.set_password(userid, hashlib.sha1(os.urandom(8)).hexdigest()) self.htpasswd.save() return userid
class HtpasswdUsers(Component): implements(IUserAuthenticator) implements(IUserTranslator) def __init__(self): config = self.get_component_config() if 'file' not in config: raise InsufficientConfiguration(missing='file', component=self.get_component_name()) self.htpasswd = HtpasswdFile(config['file']) def username_to_user(self, username): self.htpasswd.load_if_changed() if username in self.htpasswd.users(): return User(self.compmgr, username, username=username, full_name=username) def userid_to_user(self, userid): if userid is None or userid == '*': warnings.warn("You should not call this directly. Use cydra.get_user()", DeprecationWarning, stacklevel=2) return User(self.compmgr, '*', username='******', full_name='Guest') self.htpasswd.load_if_changed() if userid in self.htpasswd.users(): return User(self.compmgr, userid, username=userid, full_name=userid) else: # since the client was looking for a specific ID, # we return a dummy user object with empty data return User(self.compmgr, userid, full_name='N/A') def groupid_to_group(self, groupid): pass def user_password(self, user, password): self.htpasswd.load_if_changed() return self.htpasswd.check_password(user.userid, password)