def register_view(request): data = get_data(request) if not isinstance(data, dict) or 'hash' not in data: return error_handler(request, 404, {"location": "body", "name": "hash", "description": "Not Found"}) md5 = data['hash'] if not md5.startswith('md5:'): return error_handler(request, 422, {"location": "body", "name": "hash", "description": [u'Hash type is not supported.']}) if len(md5) != 36: return error_handler(request, 422, {"location": "body", "name": "hash", "description": [u'Hash value is wrong length.']}) if set(md5[4:]).difference('0123456789abcdef'): return error_handler(request, 422, {"location": "body", "name": "hash", "description": [u'Hash value is not hexadecimal.']}) try: uuid = request.registry.storage.register(md5) except StorageUploadError as exc: LOGGER.error('Storage error: %s', exc.message, extra=context_unpack(request, {'MESSAGE_ID': 'storage_error'})) return error_handler(request, 502, {"description": "Upload failed, please try again later"}) LOGGER.info('Registered new document upload {}'.format(uuid), extra=context_unpack(request, {'MESSAGE_ID': 'registered_upload'}, {'doc_id': uuid, 'doc_hash': md5})) signature = quote(b64encode(request.registry.signer.signature(uuid))) upload_url = request.route_url('upload_file', doc_id=uuid, _query={'Signature': signature, 'KeyID': request.registry.dockey}, _host=request.registry.upload_host or request.domain, _port=request.host_port) signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, md5[4:])))) data['url'] = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) request.response.status = 201 request.response.headers['Location'] = upload_url return {'data': data, 'upload_url': upload_url}
def upload_view(request): if 'file' not in request.POST or not hasattr(request.POST['file'], 'filename'): return error_handler(request, 404, {"location": "body", "name": "file", "description": "Not Found"}) post_file = request.POST['file'] try: uuid, md5, content_type, filename = request.registry.storage.upload(post_file) except StorageUploadError as exc: LOGGER.error('Storage error: %s', exc.message, extra=context_unpack(request, {'MESSAGE_ID': 'storage_error'})) return error_handler(request, 502, {"description": "Upload failed, please try again later"}) LOGGER.info('Uploaded new document {}'.format(uuid), extra=context_unpack(request, {'MESSAGE_ID': 'uploaded_new_document'}, {'doc_id': uuid, 'doc_hash': md5})) expires = int(time()) + EXPIRES signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, md5[4:])))) url = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, expires)))) get_url = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'Expires': expires, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) request.response.headers['Location'] = get_url return {'data': {'url': url, 'hash': md5, 'format': content_type, 'title': filename}, 'get_url': get_url}
def register_view(request): data = get_data(request) if not isinstance(data, dict) or 'hash' not in data: return error_handler(request, 404, {"location": "body", "name": "hash", "description": "Not Found"}) md5 = data['hash'] if not md5.startswith('md5:'): return error_handler(request, 422, {"location": "body", "name": "hash", "description": [u'Hash type is not supported.']}) if len(md5) != 36: return error_handler(request, 422, {"location": "body", "name": "hash", "description": [u'Hash value is wrong length.']}) if set(md5[4:]).difference('0123456789abcdef'): return error_handler(request, 422, {"location": "body", "name": "hash", "description": [u'Hash value is not hexadecimal.']}) uuid = request.registry.storage.register(md5) LOGGER.info('Registered new document upload {}'.format(uuid), extra=context_unpack(request, {'MESSAGE_ID': 'registered_upload'}, {'doc_id': uuid, 'doc_hash': md5})) signature = quote(b64encode(request.registry.signer.signature(uuid))) upload_url = request.route_url('upload_file', doc_id=uuid, _query={'Signature': signature, 'KeyID': request.registry.dockey}, _host=request.registry.upload_host or request.domain, _port=request.host_port) signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, md5[4:])))) data['url'] = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) request.response.status = 201 request.response.headers['Location'] = upload_url return {'data': data, 'upload_url': upload_url}
def upload_view(request): if 'file' not in request.POST or not hasattr(request.POST['file'], 'filename'): return error_handler(request, 404, {"location": "body", "name": "file", "description": "Not Found"}) post_file = request.POST['file'] uuid, md5, content_type, filename = request.registry.storage.upload(post_file) LOGGER.info('Uploaded new document {}'.format(uuid), extra=context_unpack(request, {'MESSAGE_ID': 'uploaded_new_document'}, {'doc_id': uuid, 'doc_hash': md5})) expires = int(time()) + EXPIRES signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, md5[4:])))) url = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, expires)))) get_url = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'Expires': expires, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) request.response.headers['Location'] = get_url return {'data': {'url': url, 'hash': md5, 'format': content_type, 'title': filename}, 'get_url': get_url}
def upload_file_view(request): if 'file' not in request.POST or not hasattr(request.POST['file'], 'filename'): return error_handler(request, 404, {"location": "body", "name": "file", "description": "Not Found"}) uuid = request.matchdict['doc_id'] keyid = request.GET.get('KeyID', request.registry.dockey) if keyid not in request.registry.dockeyring: return error_handler(request, 403, {"location": "url", "name": "KeyID", "description": "Key Id does not exist"}) key = request.registry.dockeyring.get(keyid) if 'Signature' not in request.GET: return error_handler(request, 403, {"location": "url", "name": "Signature", "description": "Not Found"}) signature = request.GET['Signature'] try: signature = b64decode(unquote(signature)) except TypeError: return error_handler(request, 403, {"location": "url", "name": "Signature", "description": "Signature invalid"}) try: if uuid != key.verify(signature + uuid.encode("utf-8")): raise ValueError except ValueError: return error_handler(request, 403, {"location": "url", "name": "Signature", "description": "Signature does not match"}) post_file = request.POST['file'] try: uuid, md5, content_type, filename = request.registry.storage.upload(post_file, uuid) except KeyNotFound: return error_handler(request, 404, {"location": "url", "name": "doc_id", "description": "Not Found"}) except ContentUploaded: return error_handler(request, 403, {"location": "url", "name": "doc_id", "description": "Content already uploaded"}) except HashInvalid: return error_handler(request, 403, {"location": "body", "name": "file", "description": "Invalid checksum"}) except StorageUploadError as exc: LOGGER.error('Storage error: %s', exc.message, extra=context_unpack(request, {'MESSAGE_ID': 'storage_error'})) return error_handler(request, 502, {"description": "Upload failed, please try again later"}) LOGGER.info('Uploaded document {}'.format(uuid), extra=context_unpack(request, {'MESSAGE_ID': 'uploaded_document'}, {'doc_hash': md5})) expires = int(time()) + EXPIRES signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, md5[4:])))) url = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, expires)))) get_url = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'Expires': expires, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) return {'data': {'url': url, 'hash': md5, 'format': content_type, 'title': filename}, 'get_url': get_url}
def get_view(request): uuid = request.matchdict['doc_id'] now = int(time()) expires = request.GET.get('Expires') if expires and expires.isdigit() and int(expires) < now: return error_handler(request, 403, {"location": "url", "name": "Expires", "description": "Request has expired"}) keyid = request.GET.get('KeyID', request.registry.dockey) if keyid not in (request.registry.apikey, request.registry.dockey) and not expires: return error_handler(request, 403, {"location": "url", "name": "KeyID", "description": "Key Id does permit to get private document"}) if keyid not in request.registry.keyring: return error_handler(request, 403, {"location": "url", "name": "KeyID", "description": "Key Id does not exist"}) mess = "{}\0{}".format(uuid, expires) if expires else uuid if request.GET.get('Prefix'): mess = '{}/{}'.format(request.GET['Prefix'], mess) uuid = '{}/{}'.format(request.GET['Prefix'], uuid) key = request.registry.keyring.get(keyid) if 'Signature' not in request.GET: return error_handler(request, 403, {"location": "url", "name": "Signature", "description": "Not Found"}) signature = request.GET['Signature'] try: signature = b64decode(unquote(signature)) except TypeError: return error_handler(request, 403, {"location": "url", "name": "Signature", "description": "Signature invalid"}) try: if mess != key.verify(signature + mess.encode("utf-8")): raise ValueError except ValueError: return error_handler(request, 403, {"location": "url", "name": "Signature", "description": "Signature does not match"}) try: doc = request.registry.storage.get(uuid) except KeyNotFound: return error_handler(request, 404, {"location": "url", "name": "doc_id", "description": "Not Found"}) except NoContent: return HTTPNoContent() except StorageRedirect as e: request.response.status = 302 request.response.headers['Location'] = e.url return e.url else: request.response.content_type = doc['Content-Type'] request.response.content_disposition = doc['Content-Disposition'] request.response.body = doc['Content'] return request.response
def upload_file_view(request): if 'file' not in request.POST or not hasattr(request.POST['file'], 'filename'): return error_handler(request, 404, {"location": "body", "name": "file", "description": "Not Found"}) uuid = request.matchdict['doc_id'] keyid = request.GET.get('KeyID', request.registry.dockey) if keyid not in request.registry.dockeyring: return error_handler(request, 403, {"location": "url", "name": "KeyID", "description": "Key Id does not exist"}) key = request.registry.dockeyring.get(keyid) if 'Signature' not in request.GET: return error_handler(request, 403, {"location": "url", "name": "Signature", "description": "Not Found"}) signature = request.GET['Signature'] try: signature = b64decode(unquote(signature)) except TypeError: return error_handler(request, 403, {"location": "url", "name": "Signature", "description": "Signature invalid"}) try: if uuid != key.verify(signature + uuid.encode("utf-8")): raise ValueError except ValueError: return error_handler(request, 403, {"location": "url", "name": "Signature", "description": "Signature does not match"}) post_file = request.POST['file'] try: uuid, md5, content_type, filename = request.registry.storage.upload(post_file, uuid) except KeyNotFound: return error_handler(request, 404, {"location": "url", "name": "doc_id", "description": "Not Found"}) except ContentUploaded: return error_handler(request, 403, {"location": "url", "name": "doc_id", "description": "Content already uploaded"}) except HashInvalid: return error_handler(request, 403, {"location": "body", "name": "file", "description": "Invalid checksum"}) LOGGER.info('Uploaded document {}'.format(uuid), extra=context_unpack(request, {'MESSAGE_ID': 'uploaded_document'}, {'doc_hash': md5})) expires = int(time()) + EXPIRES signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, md5[4:])))) url = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) signature = quote(b64encode(request.registry.signer.signature("{}\0{}".format(uuid, expires)))) get_url = request.route_url('get', doc_id=uuid, _query={'Signature': signature, 'Expires': expires, 'KeyID': request.registry.dockey}, _host=request.registry.get_host or request.domain, _port=request.host_port) return {'data': {'url': url, 'hash': md5, 'format': content_type, 'title': filename}, 'get_url': get_url}