def load(cls, s): s = bstr(s) fields = s.rstrip().split(b":") name = fields[0] hash_algorithm, digest, salt = fields[1].split(b",") return cls(name, hash_algorithm, unhex_bytes(digest), unhex_bytes(salt))
def set_password(self, password): assert self.hash_algorithm == b"SHA-256" salt = bytearray(randint(0x00, 0xFF) for _ in range(16)) m = sha256() m.update(salt) m.update(bstr(password)) self.digest = m.digest() self.salt = salt
def remove(self, user_name): """ Remove a user. """ user_name = bstr(user_name) with open(self.name, "rb") as f: lines = [line for line in f.readlines() if not AuthUser.match(line, user_name)] with open(self.name, "wb") as f: f.writelines(lines)
def update(self, user_name, password): """ Add or update a user. """ user_name = bstr(user_name) password = bstr(password) updated = False with open(self.name, "rb") as f: lines = [] for line in f.readlines(): if AuthUser.match(line, user_name): lines.append(AuthUser.create(user_name, password).dump()) updated = True else: lines.append(line) if not updated: lines.append(AuthUser.create(user_name, password).dump()) with open(self.name, "wb") as f: f.writelines(lines)
def check_password(self, password): assert self.hash_algorithm == b"SHA-256" m = sha256() m.update(self.salt) m.update(bstr(password)) return m.digest() == self.digest
def __init__(self, name, hash_algorithm, digest, salt): assert hash_algorithm == b"SHA-256" self.name = bstr(name) self.hash_algorithm = bstr(hash_algorithm) self.digest = digest self.salt = salt
def dump(self, eol=b"\r\n"): return self.name + b":" + self.hash_algorithm + b"," + hex_bytes(self.digest) + b"," + \ hex_bytes(self.salt) + b":" + bstr(eol)
def match(cls, s, user_name): s = bstr(s) user_name = bstr(user_name) candidate_user_name, _, _ = s.partition(b":") return candidate_user_name == user_name
def create(cls, user_name, password): user_name = bstr(user_name) password = bstr(password) inst = cls(user_name, b"SHA-256", None, None) inst.set_password(password) return inst
def get_connection_data(uri=None, **settings): """ Generate a dictionary of connection data for an optional URI plus additional connection settings. :param uri: :param settings: :return: """ data = { "host": None, "password": None, "port": None, "scheme": None, "secure": None, "verified": None, "user": None, "user_agent": None, } # apply uri uri = coalesce(uri, NEO4J_URI) if uri is not None: parsed = urlsplit(uri) if parsed.scheme is not None: data["scheme"] = parsed.scheme if data["scheme"] in ["https"]: data["secure"] = True elif data["scheme"] in ["http"]: data["secure"] = False data["user"] = coalesce(parsed.username, data["user"]) data["password"] = coalesce(parsed.password, data["password"]) data["host"] = coalesce(parsed.hostname, data["host"]) data["port"] = coalesce(parsed.port, data["port"]) # apply auth (this can override `uri`) if "auth" in settings and settings["auth"] is not None: data["user"], data["password"] = settings["auth"] elif NEO4J_AUTH is not None: data["user"], _, data["password"] = NEO4J_AUTH.partition(":") # apply components (these can override `uri` and `auth`) data["user_agent"] = coalesce(settings.get("user_agent"), NEO4J_USER_AGENT, data["user_agent"]) data["secure"] = coalesce(settings.get("secure"), data["secure"], NEO4J_SECURE) data["verified"] = coalesce(settings.get("verified"), data["verified"], NEO4J_VERIFIED) data["scheme"] = coalesce(settings.get("scheme"), data["scheme"]) data["user"] = coalesce(settings.get("user"), data["user"]) data["password"] = coalesce(settings.get("password"), data["password"]) data["host"] = coalesce(settings.get("host"), data["host"]) data["port"] = coalesce(settings.get("port"), data["port"]) # apply correct scheme for security if data["secure"] is True and data["scheme"] == "http": data["scheme"] = "https" if data["secure"] is False and data["scheme"] == "https": data["scheme"] = "http" # apply default port for scheme if data["scheme"] and not data["port"]: if data["scheme"] == "http": data["port"] = DEFAULT_HTTP_PORT elif data["scheme"] == "https": data["port"] = DEFAULT_HTTPS_PORT elif data["scheme"] in ["bolt", "bolt+routing"]: data["port"] = DEFAULT_BOLT_PORT # apply other defaults if not data["user_agent"]: data["user_agent"] = http_user_agent() if data["scheme"] in [ "http", "https" ] else bolt_user_agent() if data["secure"] is None: data["secure"] = DEFAULT_SECURE if data["verified"] is None: data["verified"] = DEFAULT_VERIFIED if not data["scheme"]: data["scheme"] = DEFAULT_SCHEME if data["scheme"] == "http": data["secure"] = False data["verified"] = False if data["scheme"] == "https": data["secure"] = True data["verified"] = True if not data["user"]: data["user"] = DEFAULT_USER if not data["password"]: data["password"] = DEFAULT_PASSWORD if not data["host"]: data["host"] = DEFAULT_HOST if not data["port"]: data["port"] = DEFAULT_BOLT_PORT # apply composites data["auth"] = (data["user"], data["password"]) data["uri"] = "%s://%s:%s" % (data["scheme"], data["host"], data["port"]) h = hashlib_new("md5") for key in sorted(data): h.update(bstr(data[key])) data["hash"] = h.hexdigest() return data