Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,15 @@ The tests never touch the real `/etc`: they point `--config-dir` at a
temporary folder and fake `ip`, `systemctl` and `ufw`. GitHub Actions runs
them on Ubuntu for every pull request and every push to `main`.

`tests/test_server_http.py` talks to a real server on a free port of
127.0.0.1, with no client involved: the token, which paths exist, If-Match
(including two pushes racing for one revision), malformed and oversized
bodies, the history limit and the access log. It is the same file in
PassMan-Server-Windows.

`server/passman_server.py` and `server/passman_setup.py` are the same files
as in PassMan-Server-Windows — `passman_setup.py` holds the setup for both
systems. Make a change to either in both repositories, so the two servers
never drift apart. PassMan-Client-Windows keeps a copy of
`passman_server.py` for its end-to-end sync tests; refresh that too.
never drift apart. PassMan-Client-Windows and PassMan-Client-Linux each keep
a copy of `passman_server.py` for their end-to-end sync tests; refresh
those too.
10 changes: 9 additions & 1 deletion server/passman_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import tempfile
import threading
from datetime import datetime, timezone
from http import HTTPStatus
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

#: Refuse anything larger than this. A vault is kilobytes; a megabyte is
Expand Down Expand Up @@ -215,6 +216,13 @@ def log_message(self, fmt, *args):
sys.stderr.write("%s - %s\n" % (self.address_string(), fmt % args))
sys.stderr.flush()

def log_request(self, code="-", size="-"):
"""The standard access line, with the query string cut out."""
if isinstance(code, HTTPStatus):
code = code.value
line = re.sub(r"\?\S*", "", self.requestline, count=1)
self.log_message('"%s" %s %s', line, str(code), str(size))

def _authorised(self) -> bool:
header = self.headers.get("Authorization", "")
prefix = "Bearer "
Expand All @@ -227,7 +235,7 @@ def _authorised(self) -> bool:
def _user_from_path(self):
"""Parse /vault/<user>[/meta] and reject anything else."""
parts = [p for p in self.path.split("?")[0].split("/") if p]
if not parts or parts[0] != "vault" or len(parts) < 2:
if not parts or parts[0] != "vault" or not 2 <= len(parts) <= 3:
return None, None
user = parts[1]
tail = parts[2] if len(parts) > 2 else ""
Expand Down
2 changes: 1 addition & 1 deletion server/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
in PassMan-Server-Windows, which has its own version.
"""

__version__ = "1.4.0"
__version__ = "1.4.1"
Loading
Loading