Ejemplo n.º 1
0
    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, {})
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
    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')
Ejemplo n.º 4
0
    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
Ejemplo n.º 8
0
 def test_already_converted(self):
     f = FilepickerFile(url="filepicker.io/api/file/ZXC", temporary=True)
     self.assertEqual(f.convert(w=10), 'File already converted')
Ejemplo n.º 9
0
 def setUp(self):
     self.file = FilepickerFile(handle=self.HANDLE)
Ejemplo n.º 10
0
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))