def post(self, request): data, files = parse_distutils_request(request) # XXX: Auth is currently a bit of a hack auth = request.META.get('HTTP_AUTHORIZATION') if not auth: response = HttpResponse('Missing auth header') response.status_code = 401 response['WWW-Authenticate'] = 'Basic realm="%s"' % basic_realm return response method, identity = auth.split() username, password = base64.decodestring(identity).split(':') user = authenticate(username=username, password=password) if not user: response = HttpResponse('Invalid username/password') response.status_code = 401 return response actions = { 'submit': handle_register_or_upload, 'file_upload': handle_register_or_upload, } handler = actions.get(data.get(':action')) if not handler: raise Http404('Unknown action') return handler(data, files, user)
def post(self, request): parse_distutils_request(request) # XXX: Auth is currently a bit of a hack method, identity = split_auth(request) if not method: return HttpResponseUnauthorized(content='Missing auth header') user = authenticate_user(request) if not user: return HttpResponse('Invalid username/password', status=401) actions = { 'submit': handle_register_or_upload, 'file_upload': handle_register_or_upload, } handler = actions.get(request.POST.get(':action')) if not handler: raise Http404('Unknown action') return handler(request.POST, request.FILES, user)
def post(self, request, repo): parse_distutils_request(request) actions = { 'submit': handle_register_or_upload, 'file_upload': handle_register_or_upload, } action = request.POST.get(':action') handler = actions.get(action) if not handler: return HttpResponseNotFound('Unknown action: %s' % action) if not request.user.is_authenticated() and not request.credentials: return HttpResponseForbidden( "You need to be authenticated to upload packages") # Both actions currently are upload actions, so check is simple if request.credentials and not request.credentials.allow_upload: return HttpResponseForbidden( "Upload is not allowed with the provided credentials") return handler(request.POST, request.FILES, request.user, self.repository)
def post(self, request): data, files = parse_distutils_request(request) # XXX: Auth is currently a bit of a hack method, identity = split_auth(request) if not method: return HttpResponseUnauthorized('Missing auth header') username, password = decode_credentials(identity) user = authenticate(username=username, password=password) if not user: return HttpResponse('Invalid username/password', status=401) actions = { 'submit': handle_register_or_upload, 'file_upload': handle_register_or_upload, } handler = actions.get(data.get(':action')) if not handler: raise Http404('Unknown action') return handler(data, files, user)
def test_register_post(self): data = ('\n----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="license"\n\n' 'BSD\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="name"\n\nlocalshop\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="metadata_version"\n\n' '1.0\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="author"\n\n' 'Michael van Tellingen\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="home_page"\n\n' 'http://github.com/mvantellingen/localshop\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name=":action"\n\n' 'submit\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="download_url"\n\n' 'UNKNOWN\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="summary"\n\n' 'A private pypi server including auto-mirroring of pypi.\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="author_email"\n\n' '[email protected]\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="version"\n\n' '0.1\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="platform"\n\n' 'UNKNOWN\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Development Status :: 2 - Pre-Alpha\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Framework :: Django\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Intended Audience :: Developers\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Intended Audience :: System Administrators\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Operating System :: OS Independent\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Topic :: Software Development\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="description"\n\n' 'UNKNOWN\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254--\n') request = Mock() request.raw_post_data = data request.FILES = MultiValueDict() parse_distutils_request(request) expected_post = MultiValueDict({ 'name': ['localshop'], 'license': ['BSD'], 'author': ['Michael van Tellingen'], 'home_page': ['http://github.com/mvantellingen/localshop'], ':action': ['submit'], 'download_url': [None], 'summary': ['A private pypi server including auto-mirroring of pypi.'], 'author_email': ['*****@*****.**'], 'metadata_version': ['1.0'], 'version': ['0.1'], 'platform': [None], 'classifiers': [ 'Development Status :: 2 - Pre-Alpha', 'Framework :: Django', 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'Operating System :: OS Independent', 'Topic :: Software Development' ], 'description': [None] }) expected_files = MultiValueDict() self.assertEqual(request.POST, expected_post) self.assertEqual(request.FILES, expected_files)
def test_register_post(self): data = ( '\n----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="license"\n\n' 'BSD\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="name"\n\nlocalshop\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="metadata_version"\n\n' '1.0\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="author"\n\n' 'Michael van Tellingen\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="home_page"\n\n' 'http://github.com/mvantellingen/localshop\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name=":action"\n\n' 'submit\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="download_url"\n\n' 'UNKNOWN\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="summary"\n\n' 'A private pypi server including auto-mirroring of pypi.\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="author_email"\n\n' '[email protected]\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="version"\n\n' '0.1\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="platform"\n\n' 'UNKNOWN\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Development Status :: 2 - Pre-Alpha\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Framework :: Django\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Intended Audience :: Developers\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Intended Audience :: System Administrators\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Operating System :: OS Independent\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="classifiers"\n\n' 'Topic :: Software Development\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n' 'Content-Disposition: form-data; name="description"\n\n' 'UNKNOWN\n' '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254--\n' ) request = Mock() request.raw_post_data = data request.FILES = MultiValueDict() parse_distutils_request(request) expected_post = MultiValueDict({ 'name': ['localshop'], 'license': ['BSD'], 'author': ['Michael van Tellingen'], 'home_page': ['http://github.com/mvantellingen/localshop'], ':action': ['submit'], 'download_url': [None], 'summary': [ 'A private pypi server including auto-mirroring of pypi.'], 'author_email': ['*****@*****.**'], 'metadata_version': ['1.0'], 'version': ['0.1'], 'platform': [None], 'classifiers': [ 'Development Status :: 2 - Pre-Alpha', 'Framework :: Django', 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'Operating System :: OS Independent', 'Topic :: Software Development' ], 'description': [None] }) expected_files = MultiValueDict() self.assertEqual(request.POST, expected_post) self.assertEqual(request.FILES, expected_files)