Skip to content
Snippets Groups Projects
Commit 4388a1fb authored by Philip ABBET's avatar Philip ABBET
Browse files

[algorithms, api] Add support for updating binary algorithms

parent b6459d4e
No related branches found
No related tags found
No related merge requests found
......@@ -27,6 +27,12 @@
from django.http import Http404
from django.http import HttpResponse
from django.http import HttpResponseForbidden
from django.http import HttpResponseBadRequest
from django.shortcuts import get_object_or_404
from django.conf import settings
import os
from .models import Algorithm
from .serializers import AlgorithmSerializer
......@@ -130,6 +136,9 @@ def binary(request, author_name, object_name, version=None):
"""Returns the shared library of a binary algorithm
"""
if request.method not in ['GET', 'POST']:
return HttpResponseNotAllowed(['GET', 'POST'])
# Retrieves the algorithm
if version:
algorithm = get_object_or_404(
......@@ -146,19 +155,34 @@ def binary(request, author_name, object_name, version=None):
else:
algorithm = algorithm[0]
(has_access, _, accessibility) = algorithm.accessibility_for(request.user, without_usable=True)
if not has_access:
raise Http404()
if not algorithm.is_binary():
raise Http404()
binary_data = algorithm.source_code
if request.method == 'GET':
(has_access, _, accessibility) = algorithm.accessibility_for(request.user, without_usable=True)
if not has_access:
raise Http404()
binary_data = algorithm.source_code
response = HttpResponse(binary_data, content_type='application/octet-stream')
response['Content-Length'] = len(binary_data)
response['Content-Disposition'] = 'attachment; filename=%d.so' % algorithm.version
return response
else:
if request.user.is_anonymous() or (request.user.username != author_name):
return HttpResponseForbidden()
response = HttpResponse(binary_data, content_type='application/octet-stream')
if not request.FILES.has_key('binary'):
return HttpResponseBadRequest()
response['Content-Length'] = len(binary_data)
response['Content-Disposition'] = 'attachment; filename=%d.so' % algorithm.version
file = request.FILES['binary']
with open(os.path.join(settings.ALGORITHMS_ROOT, algorithm.source_code_filename()), 'wb') as dest:
for chunk in file.chunks():
dest.write(chunk)
return response
return HttpResponse(status=204)
......@@ -562,6 +562,10 @@ class AlgorithmsAPIBase(AlgorithmsTestCase):
BINARY = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" \
"\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"
BINARY_UPDATE = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F" \
"\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF" \
"\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"
def setUp(self):
super(AlgorithmsAPIBase, self).setUp()
......
......@@ -31,6 +31,7 @@ import simplejson as json
from django.contrib.auth.models import User
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.files.uploadedfile import SimpleUploadedFile
from ...dataformats.models import DataFormat
from ...common.testutils import tearDownModule
......@@ -1587,6 +1588,90 @@ class AlgorithmUpdate(AlgorithmsAPIBase):
class AlgorithmBinaryUpdate(AlgorithmsAPIBase):
def setUp(self):
super(AlgorithmBinaryUpdate, self).setUp()
self.url = reverse('api_algorithms:binary', args=['jackdoe', 'binary_personal', 1])
self.updated_binary_file = SimpleUploadedFile("algo.so", AlgorithmsAPIBase.BINARY_UPDATE,
content_type="application/octet-stream")
def test_no_update_for_anonymous_user(self):
response = self.client.post(self.url,
{
'binary': self.updated_binary_file,
})
self.checkResponse(response, 403)
def test_fail_to_update_with_invalid_username(self):
self.client.login(username='jackdoe', password='1234')
url = reverse('api_algorithms:binary', args=['unknown', 'personal', 1])
response = self.client.post(url,
{
'binary': self.updated_binary_file,
})
self.checkResponse(response, 404)
def test_fail_to_update_with_invalid_algorithm_name(self):
self.client.login(username='jackdoe', password='1234')
url = reverse('api_algorithms:binary', args=['jackdoe', 'unknown', 1])
response = self.client.post(url,
{
'binary': self.updated_binary_file,
})
self.checkResponse(response, 404)
def test_no_update_without_content(self):
self.client.login(username='jackdoe', password='1234')
response = self.client.post(self.url,
{
})
self.checkResponse(response, 400)
def test_no_update_with_invalid_filename(self):
self.client.login(username='jackdoe', password='1234')
response = self.client.post(self.url,
{
'unknown': self.updated_binary_file,
})
self.checkResponse(response, 400)
def test_no_update_with_invalid_file_content(self):
self.client.login(username='jackdoe', password='1234')
response = self.client.post(self.url,
{
'binary': None,
})
self.checkResponse(response, 400)
def test_successfull_update(self):
self.client.login(username='jackdoe', password='1234')
response = self.client.post(self.url,
{
'binary': self.updated_binary_file,
})
self.checkResponse(response, 204)
algorithm = Algorithm.objects.get(author__username='jackdoe', name='binary_personal', version=1)
self.assertEqual(algorithm.source_code, AlgorithmsAPIBase.BINARY_UPDATE)
class AlgorithmRetrieval(AlgorithmsAPIBase):
def test_no_retrieval_of_confidential_algorithm_for_anonymous_user(self):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment