diff --git a/mapbox/services/uploads.py b/mapbox/services/uploads.py index 94dcd75..66d36b5 100644 --- a/mapbox/services/uploads.py +++ b/mapbox/services/uploads.py @@ -1,6 +1,7 @@ """ Mapbox Uploads API """ +import re from boto3.session import Session as boto3_session from uritemplate import URITemplate @@ -54,8 +55,12 @@ def _validate_tileset(self, tileset): """ if '.' not in tileset: tileset = "{0}.{1}".format(self.username, tileset) - if len(tileset) > 64: - raise ValidationError('tileset including username must be < 64 char') + + pattern = '^[a-z0-9-_]{1,32}\.[a-z0-9-_]{1,32}$' + if not re.match(pattern, tileset, flags=re.IGNORECASE): + raise ValidationError( + f'tileset {tileset} is invalid, must match r"{pattern}"') + return tileset def stage(self, fileobj, creds=None, callback=None): diff --git a/tests/test_upload.py b/tests/test_upload.py index 9b2ec99..4bb31d9 100644 --- a/tests/test_upload.py +++ b/tests/test_upload.py @@ -416,7 +416,7 @@ def ensure_patch(request): with open('tests/moors.json', 'rb') as src: res = mapbox.Uploader(access_token=access_token).upload( - src, 'testuser.test1', name='test1', patch=True) + src, 'testuser.Test1', name='test1', patch=True) assert res.status_code == 201 job = res.json() @@ -426,8 +426,17 @@ def ensure_patch(request): def test_upload_tileset_validation(): with pytest.raises(mapbox.errors.ValidationError): with open('tests/moors.json', 'rb') as src: + # limited to 32 chars, try 40 mapbox.Uploader(access_token=access_token).upload( - src, 'a' * 65, name='test1', patch=True) + src, 'username.' + 'aA' * 20, name='test1') + + +def test_upload_tileset_validation_specialchar(): + with pytest.raises(mapbox.errors.ValidationError): + with open('tests/moors.json', 'rb') as src: + # limited to a-z0-9-_ chars + mapbox.Uploader(access_token=access_token).upload( + src, 'username.&#!', name='test1') def test_upload_tileset_validation_username():