Return species information as part of the flowcell json information.
authorDiane Trout <diane@caltech.edu>
Wed, 23 Sep 2009 19:09:58 +0000 (19:09 +0000)
committerDiane Trout <diane@caltech.edu>
Wed, 23 Sep 2009 19:09:58 +0000 (19:09 +0000)
Additionally instead of using django authentication use an apikey
for authenticating access to the json data.

Currently the apikey is just a value stored in the settings.py file
(DEFAULT_API_KEY), but in the future could be linked to users.

htsworkflow/frontend/auth.py [new file with mode: 0644]
htsworkflow/frontend/experiments/experiments.py
htsworkflow/frontend/experiments/fixtures/test_flowcells.json
htsworkflow/frontend/experiments/tests.py
htsworkflow/frontend/samples/fixtures/initial_data.json
htsworkflow/frontend/samples/fixtures/test_samples.json
htsworkflow/frontend/samples/tests.py
htsworkflow/frontend/samples/views.py
htsworkflow/frontend/settings.py

diff --git a/htsworkflow/frontend/auth.py b/htsworkflow/frontend/auth.py
new file mode 100644 (file)
index 0000000..4df771b
--- /dev/null
@@ -0,0 +1,22 @@
+"""
+Define some alternate authentication methods
+"""
+from django.core.exceptions import PermissionDenied
+
+from htsworkflow.frontend import settings
+
+apidata = {'apiid': u'0', 'apikey': settings.DEFAULT_API_KEY}
+
+def require_api_key(request):
+    # make sure we have the api component
+    if not (request.REQUEST.has_key('apiid') or request.REQUEST.has_key('apikey')):
+        raise PermissionDenied
+
+    # make sure the id and key are right
+    if request.REQUEST['apiid'] == apidata['apiid'] and \
+       request.REQUEST['apikey'] == apidata['apikey']:
+        return True
+    else:
+        raise PermissionDenied
+        
+    
index f9144b01095e979a96a83cc7d09f91878df7b2d3..331bdde59a2e57a42fd66d633eac580c40e1660b 100755 (executable)
@@ -16,6 +16,7 @@ from django.http import HttpResponse, Http404
 from htsworkflow.frontend import settings
 from htsworkflow.frontend.experiments.models import FlowCell, DataRun
 from htsworkflow.frontend.samples.models import Library
+from htsworkflow.frontend.auth import require_api_key
 
 def flowcell_information(flowcell_id):
     """
@@ -35,6 +36,7 @@ def flowcell_information(flowcell_id):
             'lane_number': int(lane.lane_number),
             'library_name': lane.library.library_name,
             'library_id': lane.library.library_id,
+            'library_species': lane.library.library_species.scientific_name,
             'pM': float(lane.pM),
         }
     info = {
@@ -56,11 +58,12 @@ def flowcell_information(flowcell_id):
     
     return info
 
-@login_required    
 def flowcell_json(request, fc_id):
     """
     Return a JSON blob containing enough information to generate a config file.
     """
+    require_api_key(request)
+    
     fc_dict = flowcell_information(fc_id)
 
     if fc_dict is None:
index 09876795ac3aa0d3219e083ae590ca1948db8a79..1ce52506e76cbee03c3fb7a38ccfdd8c2ff5df0b 100644 (file)
@@ -92,7 +92,7 @@
             "library_name": "Paired End Pfl #3 MP 7/24/9 a", 
             "creation_date": "2009-08-06", 
             "cell_line": 1, 
-            "library_species": 22
+            "library_species": 2, 
             "library_type": 2, 
             "made_by": "Lorian", 
             "affiliations": [
index 6f4bc3dbf5e602299dd7d0d6d4ae3d468a9fa37c..a4a53155f7fa3ca88f11a4b44da48ee74305dcb8 100644 (file)
@@ -6,6 +6,7 @@ except ImportError, e:
 from django.test import TestCase
 from htsworkflow.frontend.experiments import models
 from htsworkflow.frontend.experiments import experiments
+from htsworkflow.frontend.auth import apidata
 
 class ExperimentsTestCases(TestCase):
     fixtures = ['test_flowcells.json']
@@ -36,9 +37,10 @@ class ExperimentsTestCases(TestCase):
                 self.failUnlessEqual(lane_dict['library_name'], lane.library.library_name)
                 self.failUnlessEqual(lane_dict['library_id'], lane.library.library_id)
                 self.failUnlessAlmostEqual(lane_dict['pM'], float(lane.pM))
+                self.failUnlessEqual(lane_dict['library_species'],
+                                     lane.library.library_species.scientific_name)
                     
-            self.client.login(username='test', password='BJOKL5kAj6aFZ6A5')
-            response = self.client.get('/experiments/config/%s/json' % (fc_id,))
+            response = self.client.get('/experiments/config/%s/json' % (fc_id,), apidata)
             # strptime isoformat string = '%Y-%m-%dT%H:%M:%S'
             fc_json = json.loads(response.content)
             self.failUnlessEqual(fc_json['flowcell_id'], fc_id)
@@ -57,35 +59,38 @@ class ExperimentsTestCases(TestCase):
                 self.failUnlessEqual(lane_dict['library_name'], lane.library.library_name)
                 self.failUnlessEqual(lane_dict['library_id'], lane.library.library_id)
                 self.failUnlessAlmostEqual(lane_dict['pM'], float(lane.pM))
+                self.failUnlessEqual(lane_dict['library_species'],
+                                     lane.library.library_species.scientific_name)
 
     def test_invalid_flowcell(self):
         """
         Make sure we get a 404 if we request an invalid flowcell ID
         """
-        self.client.login(username='test', password='BJOKL5kAj6aFZ6A5')
-        response = self.client.get('/experiments/config/nottheone/json')
+        response = self.client.get('/experiments/config/nottheone/json', apidata)
         self.failUnlessEqual(response.status_code, 404)
 
-    def test_not_logged_in(self):
+    def test_no_key(self):
         """
         Require logging in to retrieve meta data
         """
         response = self.client.get(u'/experiments/config/303TUAAXX/json')
-        self.failUnlessEqual(response.status_code, 302)
+        self.failUnlessEqual(response.status_code, 403)
 
     def test_library_id(self):
         """
         Library IDs should be flexible, so make sure we can retrive a non-numeric ID
         """
-        self.client.login(username='test', password='BJOKL5kAj6aFZ6A5')
-        response = self.client.get('/experiments/config/303TUAAXX/json')
+        response = self.client.get('/experiments/config/303TUAAXX/json', apidata)
         self.failUnlessEqual(response.status_code, 200)
         flowcell = json.loads(response.content)
 
         self.failUnlessEqual(flowcell['lane_set']['3']['library_id'], 'SL039')
 
-        response = self.client.get('/samples/library/SL039/json')
+        response = self.client.get('/samples/library/SL039/json', apidata)
         self.failUnlessEqual(response.status_code, 200)
         library_sl039 = json.loads(response.content)
 
         self.failUnlessEqual(library_sl039['library_id'], 'SL039')
+
+#class RetriveConfigTestCases(TestCase):
+#    fixtures = ['test_flowcells.json']
index dbdcc7a27049b40371c285314c3ff4034b99693f..27eeccfdbcf7214528382c3a4d25cf301d6e2b22 100644 (file)
         "name": "Multiplexed"
      }
   },
-  {
-     "model": "samples.Species",
-     "pk": 1,
-     "fields": {
-        "scientific_name": "Mus musculus",
-        "common_name": "mouse"
-     }
-  },
   {
      "model": "samples.Species",
      "pk": 2,
         "common_name": ""
      }
   },
+  {
+     "model": "samples.Species",
+     "pk": 6,
+     "fields": {
+        "scientific_name": "Arabidopsis thaliana"
+     }
+  },
   {
      "model": "samples.Species",
      "pk": 8,
         "scientific_name": "Homo sapiens",
         "common_name": ""
      }
+  },
+  {
+     "model": "samples.Species",
+     "pk": 9,
+     "fields": {
+        "scientific_name": "Mus musculus",
+        "common_name": "mouse"
+     }
+  },
+  {
+     "model": "samples.Species",
+     "pk": 10,
+     "fields": {
+        "scientific_name": "Strongylocentrotus purpuratus"
+     }
   }
-
 ]
index dba08b6626de4185298f4826a8834b6a9a3cac9d..ae998723b8588ea5e23b7a2201bb96ecd2b26c8e 100644 (file)
@@ -53,7 +53,7 @@
             "library_name": "Paired End Pfl #3 MP 7/24/9 a", 
             "creation_date": "2009-08-06", 
             "cell_line": 1, 
-            "library_species": 1
+            "library_species": 9
             "library_type": 2, 
             "made_by": "Lorian", 
             "affiliations": [
             "library_name": "Paired End Pfl #3 MP 7/24/9", 
             "creation_date": "2009-08-05", 
             "cell_line": 1, 
-            "library_species": 1
+            "library_species": 8
             "library_type": 2, 
             "made_by": "Lorian", 
             "affiliations": [
index 595727e13510c0eaa369e668056cef5c005b988d..d85a46672ebc4e8902bce1a53fad6078b604ec34 100644 (file)
@@ -18,6 +18,8 @@ from htsworkflow.frontend.samples.views import \
      library_dict, \
      library_json
 
+from htsworkflow.frontend.auth import apidata
+
 # The django test runner flushes the database between test suites not cases,
 # so to be more compatible with running via nose we flush the database tables
 # of interest before creating our sample data.
@@ -123,9 +125,8 @@ class SampleWebTestCase(TestCase):
 
         for lib in Library.objects.all():
             lib_dict = library_dict(lib.library_id)
-            self.client.login(username='test', password='BJOKL5kAj6aFZ6A5')
             url = '/samples/library/%s/json' % (lib.library_id,)
-            lib_response = self.client.get(url)
+            lib_response = self.client.get(url, apidata)
             self.failUnlessEqual(lib_response.status_code, 200)
             lib_json = json.loads(lib_response.content)
 
@@ -164,17 +165,15 @@ class SampleWebTestCase(TestCase):
         """
         Make sure we get a 404 if we request an invalid library id
         """
-        self.client.login(username='test', password='BJOKL5kAj6aFZ6A5')
-        response = self.client.get('/samples/library/nottheone/json')
+        response = self.client.get('/samples/library/nottheone/json', apidata)
         self.failUnlessEqual(response.status_code, 404)
 
             
-    def test_library_not_logged_in(self):
+    def test_library_no_key(self):
         """
         Make sure we get a 302 if we're not logged in
         """
         response = self.client.get('/samples/library/10981/json')
-        self.failUnlessEqual(response.status_code, 302)
-        self.client.login(username='test', password='BJOKL5kAj6aFZ6A5')
-        response = self.client.get('/samples/library/10981/json')
+        self.failUnlessEqual(response.status_code, 403)
+        response = self.client.get('/samples/library/10981/json', apidata)
         self.failUnlessEqual(response.status_code, 200)
index f42c8bce7d53984ed227c696d487898a533ff755..b0a61f42117db2c1758b933041e64f0cb2377cb4 100644 (file)
@@ -7,6 +7,7 @@ try:
 except ImportError, e:
     import simplejson as json
 
+from htsworkflow.frontend.auth import require_api_key
 from htsworkflow.frontend.experiments.models import FlowCell
 from htsworkflow.frontend.samples.changelist import ChangeList
 from htsworkflow.frontend.samples.models import Library
@@ -491,11 +492,11 @@ def library_dict(library_id):
         info['library_type'] = lib.library_type.name
     return info
 
-@login_required
 def library_json(request, library_id):
     """
     Return a json formatted library dictionary
     """
+    require_api_key(request)
     # what validation should we do on library_id?
     
     lib = library_dict(library_id)
index 91eccf967e301615ae535fa6736df7c53d26ed3c..a1412836a7ef59686ca2108a400070bee3dfe2d9 100644 (file)
@@ -141,6 +141,9 @@ ADMIN_MEDIA_PREFIX = '/media/'
 # Make this unique, and don't share it with anybody.
 SECRET_KEY = '(ekv^=gf(j9f(x25@a7r+8)hqlz%&_1!tw^75l%^041#vi=@4n'
 
+# some of our urls need an api key
+DEFAULT_API_KEY = 'n7HsXGHIi0vp9j5u4TIRJyqAlXYc4wrH'
+
 # List of callables that know how to import templates from various sources.
 TEMPLATE_LOADERS = (
     'django.template.loaders.filesystem.load_template_source',