def test_init_with_url(self): url = 'https://www.filepicker.io/api/file/{}'.format(self.HANDLE) file = FilepickerFile(url=url) self.assertEqual(file.url, url) self.assertEqual(file.handle, self.HANDLE) self.assertEqual(file.metadata, {})
def get_signed_url(url): if url is None or url == '': return now = timezone.now() fpfile = FilepickerFile(url=url) # remove existing query params base_url = fpfile.url.split('?')[0] sig = UrlSignature.objects.filter( file_handle=fpfile.handle, expires__gte=now).order_by('-expires').first() if sig: return '{0}?policy={1}&signature={2}'.format(base_url, sig.policy, sig.signature) expiry = str(EXPIRY) json_policy = '{"handle":"%s","expiry":%s}' % (fpfile.handle, expiry) policy = base64.urlsafe_b64encode(json_policy) signature = hmac.new(settings.FILEPICKER_APP_SECRET, policy, hashlib.sha256).hexdigest() new_sig = UrlSignature(file_handle=fpfile.handle, policy=policy, signature=signature, expires=now + timezone.timedelta(0, EXPIRES_IN_SECONDS)) new_sig.save() return '{0}?policy={1}&signature={2}'.format(base_url, policy, signature)
def test_init_with_dict(self): file_dict = { 'url': "https://www.filepicker.io/api/file/" + self.HANDLE, 'size': 8811, 'type': 'image/jpg', 'filename': 'awesome.jpg' } file = FilepickerFile(response_dict=file_dict.copy()) self.assertEqual(file.url, file_dict['url']) self.assertEqual(file.handle, self.HANDLE) self.assertNotEqual(file.metadata, None) self.assertEqual(file.mimetype, file_dict['type']) self.assertRaises(AttributeError, file.__getattribute__, 'non_existent_attr')
def __post(self, storage, data=None, files=None, params=None): storage = storage or self.storage post_url = '{}/store/{}'.format(self.API_URL, storage) params['key'] = self.api_key response = requests.post(post_url, data=data, files=files, params=params, headers=self.HEADERS) try: response_dict = json.loads(response.text) return FilepickerFile(response_dict=response_dict, api_key=self.api_key, app_secret=self.app_secret, policies=self.policies) except ValueError: return response.raise_for_status()
def test_already_converted(self): f = FilepickerFile(url="filepicker.io/api/file/ZXC", temporary=True) self.assertEqual(f.convert(w=10), 'File already converted')
def setUp(self): self.file = FilepickerFile(handle=self.HANDLE)
class FilepickerFileTest(unittest2.TestCase): HANDLE = 'XXMadeUpHandleXX' def setUp(self): self.file = FilepickerFile(handle=self.HANDLE) def test_init_with_handle(self): self.assertEqual(self.file.handle, self.HANDLE) self.assertEqual(self.file.url, self.file.FILE_API_URL + self.HANDLE) self.assertEqual(self.file.metadata, {}) def test_init_with_url(self): url = 'https://www.filepicker.io/api/file/{}'.format(self.HANDLE) file = FilepickerFile(url=url) self.assertEqual(file.url, url) self.assertEqual(file.handle, self.HANDLE) self.assertEqual(file.metadata, {}) def test_init_with_dict(self): file_dict = { 'url': "https://www.filepicker.io/api/file/" + self.HANDLE, 'size': 8811, 'type': 'image/jpg', 'filename': 'awesome.jpg'} file = FilepickerFile(response_dict=file_dict.copy()) self.assertEqual(file.url, file_dict['url']) self.assertEqual(file.handle, self.HANDLE) self.assertNotEqual(file.metadata, None) self.assertEqual(file.mimetype, file_dict['type']) self.assertRaises(AttributeError, file.__getattribute__, 'non_existent_attr') def test_set_api_key(self): self.assertEqual(self.file.api_key, None) self.file.set_api_key('my_key') self.assertEqual(self.file.api_key, 'my_key') def test_set_app_secret(self): self.assertEqual(self.file.app_secret, None) self.file.set_app_secret('my_s') self.assertEqual(self.file.app_secret, 'my_s') def test_update_metada(self): self.assertEqual(self.file.metadata, {}) @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}/metadata'.format(self.HANDLE), method='get', scheme='https') def metadata_url(url, request): for attr in self.file.METADATA_ATTRS: self.assertIn('{}=true'.format(attr), url.query) return {'status_code': 200, 'content': json.dumps({'md5': '123abc'}).encode('utf-8')} with HTTMock(metadata_url): self.file.update_metadata() self.assertEqual(self.file.md5, '123abc') def test_delete(self): @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}'.format(self.HANDLE), method='delete', scheme='https') def delete_file(url, request): # return 'success' return {'status_code': 200, 'content': 'success'.encode('utf-8')} self.assertEqual(self.file.api_key, None) self.assertEqual(self.file.delete(), 'Please set API key first') self.file.set_api_key('key') with HTTMock(delete_file): response = self.file.delete() self.assertIsInstance(response, requests.Response) self.assertEqual(response.text, 'success') self.assertEqual(response.status_code, 200) def test_download(self): dest_path = 'delete_this_test_leftover' f_content = 'downloaded file content' @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}'.format(self.HANDLE), method='get', scheme='https') def download_file(url, request): return {'status_code': 200, 'content': f_content.encode('utf-8')} # return "downloaded file content" with HTTMock(download_file): self.file.download(dest_path) try: with open(dest_path) as f: self.assertEqual(f.read(), f_content) os.remove(dest_path) except IOError as e: print("Looks like something went wrong: {}".format(e)) self.assertTrue(False) def test_download_with_security_enabled(self): dest_path = 'delete_this_test_leftover' secured_msg = 'This action has been secured' @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}'.format(self.HANDLE), method='get', scheme='https') def download_file(url, request): if all(item in url.query for item in ['policy', 'signature']): # just checking if policy and signature are added to query # string, not the actual value return {'status_code': 200, 'content': 'downloaded file content'.encode('utf-8')} return {'status_code': 200, 'content': secured_msg.encode('utf-8')} with HTTMock(download_file): self.file.download(dest_path) # download with no policy try: with open(dest_path) as f: self.assertEqual(f.read(), secured_msg) os.remove(dest_path) except IOError as e: print("Looks like something went wrong: {}".format(e)) self.assertTrue(False) self.file.set_app_secret("SECRET") self.file.add_policy('newpolicy', {'call': 'download', 'expiry': 999}) with HTTMock(download_file): self.file.download(dest_path, policy_name='newpolicy') try: with open(dest_path) as f: self.assertEqual(f.read(), 'downloaded file content') os.remove(dest_path) except IOError as e: print("Looks like something went wrong: {}".format(e)) self.assertTrue(False) def test_overwrite(self): @all_requests def overwrite_file(url, request): self.assertEqual(request.url, self.file.url) self.assertEqual(request.method, 'POST') self.assertIn(urllib.quote('somenew.url/new.png', ''), request.body) j = {"url": "https://www.filepicker.io/api/file/ZXC", "filename": "name.jpg"} return {'status_code': 200, 'content': json.dumps(j).encode('utf-8')} with HTTMock(overwrite_file): self.file.overwrite(url='somenew.url/new.png') @all_requests def overwrite_file(url, request): self.assertEqual(request.url, self.file.url) self.assertEqual(request.method, 'POST') self.assertIn('name="fileUpload"', str(request.body)) j = {"url": "https://www.filepicker.io/api/file/ZXC", "filename": "name.jpg"} return {'status_code': 200, 'content': json.dumps(j).encode('utf-8')} with HTTMock(overwrite_file): self.file.overwrite(filepath=__file__) def test_already_converted(self): f = FilepickerFile(url="filepicker.io/api/file/ZXC", temporary=True) self.assertEqual(f.convert(w=10), 'File already converted') def test_convert(self): converted_file = self.file.convert(filter='blur', blurAmount=2, w=20) self.assertRegexpMatches(converted_file.url, r'convert.+filter=blur') self.assertRegexpMatches(converted_file.url, r'convert.+blurAmount=2') self.assertRegexpMatches(converted_file.url, r'convert.+w=20') self.assertTrue(converted_file.temporary) def test_convert_and_store(self): self.assertIsNone(self.file.api_key) self.assertEqual(self.file.convert(w=10, storeLocation='S3'), 'Please set API key first') self.file.set_api_key('APIKEY') fp_response = { "size": 999, "type": "image/jpeg", "url": "https://www.filepicker.io/api/file/ZXC", "filename": "logo.jpg"} @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}/convert'.format(self.HANDLE), method='post', scheme='https') def convert_and_store(url, request): self.assertIn('w=10', url.query) self.assertIn('key=APIKEY', url.query) self.assertIn('storeLocation=Azure', url.query) return {'status_code': 200, 'content': json.dumps(fp_response).encode('utf-8')} with HTTMock(convert_and_store): converted_file = self.file.convert(w=10, storeLocation='Azure') self.assertFalse(converted_file.temporary) self.assertEqual(converted_file.url, fp_response['url']) self.assertEqual(converted_file.handle, 'ZXC') def test_key_inheritance(self): self.file.set_api_key('APIKEY') converted_file = self.file.convert(filter='blur', blurAmount=2, w=20) self.assertEqual(self.file.api_key, converted_file.api_key) self.assertEqual(self.file.app_secret, converted_file.app_secret) self.assertEqual(self.file.policies, converted_file.policies) fp_response = { "size": 999, "type": "image/jpeg", "url": "https://www.filepicker.io/api/file/ZXC", "filename": "logo.jpg"} @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}/convert'.format(self.HANDLE), method='post', scheme='https') def convert_and_store(url, request): return {'status_code': 200, 'content': json.dumps(fp_response).encode('utf-8')} secret_before = self.file.app_secret self.file.set_app_secret('APPSECRET') secret_after = self.file.app_secret self.file.add_policy('foo', {'expiry': 15}) with HTTMock(convert_and_store): converted_file = self.file.convert(w=10, storeLocation='Azure') self.assertIn('foo', converted_file.policies) self.assertNotEqual(secret_before, secret_after) self.assertEqual(self.file.app_secret, converted_file.app_secret) self.assertEqual(self.file.api_key, converted_file.api_key) def test_add_policy(self): self.assertTrue(len(self.file.policies) == 0) self.assertIsNone(self.file.app_secret) self.assertRaises(Exception, self.file.add_policy, 'zz', {'expiry': 1}) self.file.set_app_secret('sec') self.file.add_policy('new_policy', {'expiry': 1, 'call': 'read'}) self.assertTrue(len(self.file.policies) == 1) def test_signed_url(self): self.file.set_app_secret('sec') self.file.add_policy('new_policy', {'expiry': 1, 'call': 'read'}) url = self.file.get_signed_url('new_policy') self.assertRegexpMatches( url, r'{}.+signature.+'.format(self.file.url)) self.assertRegexpMatches( url, r'{}.+policy.+'.format(self.file.url)) def test_user_agent_header(self): dest_path = 'delete_this_test_leftover' @all_requests def api(url, request): user_agent = request.headers.get('User-Agent', None) self.assertTrue(user_agent is not None) self.assertTrue(user_agent.startswith('filepicker-python')) j = {"url": "https://www.filepicker.io/api/file/ZXC", "filename": "name.jpg"} return {'status_code': 200, 'content': json.dumps(j).encode('utf-8')} with HTTMock(api): self.file.update_metadata() self.file.overwrite(url='somenew.url/new.png') self.file.download(dest_path) try: # clean up after download os.remove(dest_path) except IOError: pass
class FilepickerFileTest(unittest2.TestCase): HANDLE = 'XXMadeUpHandleXX' def setUp(self): self.file = FilepickerFile(handle=self.HANDLE) def test_init_with_handle(self): self.assertEqual(self.file.handle, self.HANDLE) self.assertEqual(self.file.url, self.file.FILE_API_URL + self.HANDLE) self.assertEqual(self.file.metadata, {}) def test_init_with_url(self): url = 'https://www.filepicker.io/api/file/{}'.format(self.HANDLE) file = FilepickerFile(url=url) self.assertEqual(file.url, url) self.assertEqual(file.handle, self.HANDLE) self.assertEqual(file.metadata, {}) def test_init_with_dict(self): file_dict = { 'url': "https://www.filepicker.io/api/file/" + self.HANDLE, 'size': 8811, 'type': 'image/jpg', 'filename': 'awesome.jpg' } file = FilepickerFile(response_dict=file_dict.copy()) self.assertEqual(file.url, file_dict['url']) self.assertEqual(file.handle, self.HANDLE) self.assertNotEqual(file.metadata, None) self.assertEqual(file.mimetype, file_dict['type']) self.assertRaises(AttributeError, file.__getattribute__, 'non_existent_attr') def test_set_api_key(self): self.assertEqual(self.file.api_key, None) self.file.set_api_key('my_key') self.assertEqual(self.file.api_key, 'my_key') def test_set_app_secret(self): self.assertEqual(self.file.app_secret, None) self.file.set_app_secret('my_s') self.assertEqual(self.file.app_secret, 'my_s') def test_update_metada(self): self.assertEqual(self.file.metadata, {}) @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}/metadata'.format(self.HANDLE), method='get', scheme='https') def metadata_url(url, request): for attr in self.file.METADATA_ATTRS: self.assertIn('{}=true'.format(attr), url.query) return { 'status_code': 200, 'content': json.dumps({ 'md5': '123abc' }).encode('utf-8') } with HTTMock(metadata_url): self.file.update_metadata() self.assertEqual(self.file.md5, '123abc') def test_delete(self): @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}'.format(self.HANDLE), method='delete', scheme='https') def delete_file(url, request): # return 'success' return {'status_code': 200, 'content': 'success'.encode('utf-8')} self.assertEqual(self.file.api_key, None) self.assertEqual(self.file.delete(), 'Please set API key first') self.file.set_api_key('key') with HTTMock(delete_file): response = self.file.delete() self.assertIsInstance(response, requests.Response) self.assertEqual(response.text, 'success') self.assertEqual(response.status_code, 200) def test_download(self): dest_path = 'delete_this_test_leftover' f_content = 'downloaded file content' @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}'.format(self.HANDLE), method='get', scheme='https') def download_file(url, request): return {'status_code': 200, 'content': f_content.encode('utf-8')} # return "downloaded file content" with HTTMock(download_file): self.file.download(dest_path) try: with open(dest_path) as f: self.assertEqual(f.read(), f_content) os.remove(dest_path) except IOError as e: print("Looks like something went wrong: {}".format(e)) self.assertTrue(False) def test_download_with_security_enabled(self): dest_path = 'delete_this_test_leftover' secured_msg = 'This action has been secured' @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}'.format(self.HANDLE), method='get', scheme='https') def download_file(url, request): if all(item in url.query for item in ['policy', 'signature']): # just checking if policy and signature are added to query # string, not the actual value return { 'status_code': 200, 'content': 'downloaded file content'.encode('utf-8') } return {'status_code': 200, 'content': secured_msg.encode('utf-8')} with HTTMock(download_file): self.file.download(dest_path) # download with no policy try: with open(dest_path) as f: self.assertEqual(f.read(), secured_msg) os.remove(dest_path) except IOError as e: print("Looks like something went wrong: {}".format(e)) self.assertTrue(False) self.file.set_app_secret("SECRET") self.file.add_policy('newpolicy', {'call': 'download', 'expiry': 999}) with HTTMock(download_file): self.file.download(dest_path, policy_name='newpolicy') try: with open(dest_path) as f: self.assertEqual(f.read(), 'downloaded file content') os.remove(dest_path) except IOError as e: print("Looks like something went wrong: {}".format(e)) self.assertTrue(False) def test_overwrite(self): @all_requests def overwrite_file(url, request): self.assertEqual(request.url, self.file.url) self.assertEqual(request.method, 'POST') self.assertIn(urllib.quote('somenew.url/new.png', ''), request.body) j = { "url": "https://www.filepicker.io/api/file/ZXC", "filename": "name.jpg" } return { 'status_code': 200, 'content': json.dumps(j).encode('utf-8') } with HTTMock(overwrite_file): self.file.overwrite(url='somenew.url/new.png') @all_requests def overwrite_file(url, request): self.assertEqual(request.url, self.file.url) self.assertEqual(request.method, 'POST') self.assertIn('name="fileUpload"', str(request.body)) j = { "url": "https://www.filepicker.io/api/file/ZXC", "filename": "name.jpg" } return { 'status_code': 200, 'content': json.dumps(j).encode('utf-8') } with HTTMock(overwrite_file): self.file.overwrite(filepath=__file__) def test_already_converted(self): f = FilepickerFile(url="filepicker.io/api/file/ZXC", temporary=True) self.assertEqual(f.convert(w=10), 'File already converted') def test_convert(self): converted_file = self.file.convert(filter='blur', blurAmount=2, w=20) self.assertRegexpMatches(converted_file.url, r'convert.+filter=blur') self.assertRegexpMatches(converted_file.url, r'convert.+blurAmount=2') self.assertRegexpMatches(converted_file.url, r'convert.+w=20') self.assertTrue(converted_file.temporary) def test_convert_and_store(self): self.assertIsNone(self.file.api_key) self.assertEqual(self.file.convert(w=10, storeLocation='S3'), 'Please set API key first') self.file.set_api_key('APIKEY') fp_response = { "size": 999, "type": "image/jpeg", "url": "https://www.filepicker.io/api/file/ZXC", "filename": "logo.jpg" } @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}/convert'.format(self.HANDLE), method='post', scheme='https') def convert_and_store(url, request): self.assertIn('w=10', url.query) self.assertIn('key=APIKEY', url.query) self.assertIn('storeLocation=Azure', url.query) return { 'status_code': 200, 'content': json.dumps(fp_response).encode('utf-8') } with HTTMock(convert_and_store): converted_file = self.file.convert(w=10, storeLocation='Azure') self.assertFalse(converted_file.temporary) self.assertEqual(converted_file.url, fp_response['url']) self.assertEqual(converted_file.handle, 'ZXC') def test_key_inheritance(self): self.file.set_api_key('APIKEY') converted_file = self.file.convert(filter='blur', blurAmount=2, w=20) self.assertEqual(self.file.api_key, converted_file.api_key) self.assertEqual(self.file.app_secret, converted_file.app_secret) self.assertEqual(self.file.policies, converted_file.policies) fp_response = { "size": 999, "type": "image/jpeg", "url": "https://www.filepicker.io/api/file/ZXC", "filename": "logo.jpg" } @urlmatch(netloc=r'www\.filepicker\.io', path='/api/file/{}/convert'.format(self.HANDLE), method='post', scheme='https') def convert_and_store(url, request): return { 'status_code': 200, 'content': json.dumps(fp_response).encode('utf-8') } secret_before = self.file.app_secret self.file.set_app_secret('APPSECRET') secret_after = self.file.app_secret self.file.add_policy('foo', {'expiry': 15}) with HTTMock(convert_and_store): converted_file = self.file.convert(w=10, storeLocation='Azure') self.assertIn('foo', converted_file.policies) self.assertNotEqual(secret_before, secret_after) self.assertEqual(self.file.app_secret, converted_file.app_secret) self.assertEqual(self.file.api_key, converted_file.api_key) def test_add_policy(self): self.assertTrue(len(self.file.policies) == 0) self.assertIsNone(self.file.app_secret) self.assertRaises(Exception, self.file.add_policy, 'zz', {'expiry': 1}) self.file.set_app_secret('sec') self.file.add_policy('new_policy', {'expiry': 1, 'call': 'read'}) self.assertTrue(len(self.file.policies) == 1) def test_signed_url(self): self.file.set_app_secret('sec') self.file.add_policy('new_policy', {'expiry': 1, 'call': 'read'}) url = self.file.get_signed_url('new_policy') self.assertRegexpMatches(url, r'{}.+signature.+'.format(self.file.url)) self.assertRegexpMatches(url, r'{}.+policy.+'.format(self.file.url))