Skip to content

Commit 330d368

Browse files
committed
Make empty URL:s work in ACL:s
Setting a different default access for a specific user didn't previously work because * the ACL must be sorted in reversed alphabetic order which means that an empty URL (ie. a default rule) must be last, and * the search for matching ACL rules stops when the top level domain of the a rule is alphabetically lower than the one searched for. Ie. given "default_access: allow" and the ACL: com,example)/ - {"access": "block"} - {"access": "block", "user": "unknown"} and searching for "http://iana.org", the last line would not be found so that the "unknown" user would still be "allowed".
1 parent 4a3e7dd commit 330d368

File tree

5 files changed

+24
-5
lines changed

5 files changed

+24
-5
lines changed

docs/manual/access-control.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ For example, the following access control settings restrict access to ``https://
139139
com,example)/restricted - {"access": "allow", "user": "staff"}
140140
com,example)/restricted - {"access": "block"}
141141

142+
As a special case one can add a default rule for a specific user by supplying an empty URL (note the leading space)::
143+
144+
com,example) - {"access": "allow", "user": "other"}
145+
- {"access": "block", "user": "other"}
146+
147+
which would give the ``other`` user access to the index for any URL but not to any data except for ``example.com``.
142148

143149
Combined with the embargo settings, this can also be used to override the embargo for internal organizational users, while keeping the embargo for general access::
144150

pywb/warcserver/access_checker.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,7 @@ def find_access_rule(self, url, ts=None, urlkey=None, collection=None, acl_user=
269269
last_obj = acl_obj
270270

271271
# if acl key already less than first tld,
272-
# no match can be found
273-
if acl_key < tld:
274-
break
272+
# keep going in case there's a user specific default rule
275273

276274
return last_obj if last_obj else self.default_rule
277275

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
com,example)/ - {"access": "block", "user": "staff"}
2+
com,example)/ - {"access": "allow", "user": "staff2"}
3+
- {"access": "block", "user": "staff2"}

tests/config_test_access.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ collections:
2424

2525
default_access: block
2626

27+
pywb-acl-user-default:
28+
index_paths: ./sample_archive/cdx/
29+
archive_paths: ./sample_archive/warcs/
30+
acl_paths: ./sample_archive/access/user-default.aclj
31+
32+
default_access: allow
33+
2734
pywb-embargo-before:
2835
index_paths: ./sample_archive/cdx/
2936
archive_paths: ./sample_archive/warcs/

tests/test_acl.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,10 @@ def test_allowed_different_coll_acl_dir(self):
8585

8686
assert '"http://httpbin.org/anything/resource.json"' in resp.text
8787

88-
89-
88+
def test_user_default(self):
89+
headers = {"X-Pywb-ACL-User": "staff"}
90+
self.testapp.get('/pywb-acl-user-default/mp_/http://www.iana.org/', headers=headers, status=200)
91+
self.testapp.get('/pywb-acl-user-default/mp_/http://www.example.com/', headers=headers, status=451)
92+
headers = {"X-Pywb-ACL-User": "staff2"}
93+
self.testapp.get('/pywb-acl-user-default/mp_/http://www.iana.org/', headers=headers, status=451)
94+
self.testapp.get('/pywb-acl-user-default/mp_/http://www.example.com/', headers=headers, status=200)

0 commit comments

Comments
 (0)