Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

warehouse: Friendlier token "username", prefix #6342

Merged
merged 10 commits into from
Aug 5, 2019
2 changes: 2 additions & 0 deletions tests/unit/macaroons/test_auth_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
("maybeafuturemethod foobar", None),
("token foobar", "foobar"),
("basic QHRva2VuOmZvb2Jhcg==", "foobar"), # "@token:foobar"
("basic X190b2tlbl9fOmZvb2Jhcg==", "foobar"), # "__token__:foobar"
],
)
def test_extract_http_macaroon(auth, result):
Expand All @@ -49,6 +50,7 @@ def test_extract_http_macaroon(auth, result):
("bm90YXJlYWx0b2tlbg==", None), # "notarealtoken"
("QGJhZHVzZXI6Zm9vYmFy", None), # "@baduser:foobar"
("QHRva2VuOmZvb2Jhcg==", "foobar"), # "@token:foobar"
("X190b2tlbl9fOmZvb2Jhcg==", "foobar"), # "__token__:foobar"
],
)
def test_extract_basic_macaroon(auth, result):
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/macaroons/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def test_creation(self):
("noprefixhere", None),
("invalid:prefix", None),
("pypi:validprefix", "validprefix"),
("pypi-validprefix", "validprefix"),
],
)
def test_extract_raw_macaroon(self, macaroon_service, raw_macaroon, result):
Expand Down Expand Up @@ -74,7 +75,7 @@ def test_find_userid_invalid_macaroon(self, macaroon_service):
key=b"fake key",
version=pymacaroons.MACAROON_V2,
).serialize()
raw_macaroon = f"pypi:{raw_macaroon}"
raw_macaroon = f"pypi-{raw_macaroon}"

assert macaroon_service.find_userid(raw_macaroon) is None

Expand Down Expand Up @@ -107,7 +108,7 @@ def test_verify_no_macaroon(self, macaroon_service):
key=b"fake key",
version=pymacaroons.MACAROON_V2,
).serialize()
raw_macaroon = f"pypi:{raw_macaroon}"
raw_macaroon = f"pypi-{raw_macaroon}"

with pytest.raises(services.InvalidMacaroon):
macaroon_service.verify(
Expand Down
3 changes: 2 additions & 1 deletion warehouse/macaroons/auth_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ def _extract_basic_macaroon(auth):
except ValueError:
return None

if auth_method != "@token":
# TODO: Remove @token as an acceptable token username (GH-6345)
if auth_method != "@token" and auth_method != "__token__":
return None

return auth
Expand Down
14 changes: 7 additions & 7 deletions warehouse/macaroons/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@ class DatabaseMacaroonService:
def __init__(self, db_session):
self.db = db_session

def _extract_raw_macaroon(self, raw_macaroon):
def _extract_raw_macaroon(self, prefixed_macaroon):
"""
Returns the base64-encoded macaroon component of a PyPI macaroon,
dropping the prefix.

Returns None if the macaroon is None, has no prefix, or has the
wrong prefix.
"""
if raw_macaroon is None:
if prefixed_macaroon is None:
return None

try:
prefix, raw_macaroon = raw_macaroon.split(":", 1)
except ValueError:
return None
prefix, split, raw_macaroon = prefixed_macaroon.partition("-")
# TODO: Remove ':' as an acceptable delimiter for tokens (GH-6345)
if prefix != "pypi" or not split:
prefix, _, raw_macaroon = prefixed_macaroon.partition(":")

if prefix != "pypi":
return None
Expand Down Expand Up @@ -129,7 +129,7 @@ def create_macaroon(self, location, user_id, description, caveats):
version=pymacaroons.MACAROON_V2,
)
m.add_first_party_caveat(json.dumps(caveats))
serialized_macaroon = f"pypi:{m.serialize()}"
serialized_macaroon = f"pypi-{m.serialize()}"
return serialized_macaroon, dm

def delete_macaroon(self, macaroon_id):
Expand Down
4 changes: 2 additions & 2 deletions warehouse/templates/pages/help.html
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ <h3 id="apitoken">{{ apitoken() }}</h3>
<p>To use an API token:</p>

<ul>
<li>Set your username to <code>@token</code></li>
<li>Set your password to the token value</li>
<li>Set your username to <code>__token__</code></li>
<li>Set your password to the token value, including the <code>pypi-</code> prefix</li>
</ul>

<p>Where you edit or add these values will depend on your individual use case. For example, some users may need to edit <a href="https://packaging.python.org/guides/distributing-packages-using-setuptools/#create-an-account" title="External link" target="_blank" rel="noopener">their <code>.pypirc</code> file</a>, while others may need to update their CI configuration file (e.g. <a href="https://docs.travis-ci.com/user/deployment/pypi/" title="External link" target="_blank" rel="noopener"><code>travis.yml</code> if you are using Travis</a>).</p>
Expand Down