aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--license_protected_downloads/admin.py14
-rw-r--r--license_protected_downloads/migrations/0003_auto__add_field_apikeystore_description__add_field_apikeystore_last_us.py57
-rw-r--r--license_protected_downloads/models.py8
-rw-r--r--license_protected_downloads/tests/test_views.py4
4 files changed, 83 insertions, 0 deletions
diff --git a/license_protected_downloads/admin.py b/license_protected_downloads/admin.py
new file mode 100644
index 0000000..613d259
--- /dev/null
+++ b/license_protected_downloads/admin.py
@@ -0,0 +1,14 @@
+from django.contrib import admin
+
+from license_protected_downloads import models
+
+
+class APIKeyStoreAdmin(admin.ModelAdmin):
+ list_display = ('description', 'key', 'public', 'last_used')
+ fields = ('description', 'key', 'public')
+ read_only_fields = ('last_used',)
+
+
+admin.site.register(models.APIKeyStore, APIKeyStoreAdmin)
+admin.site.register(models.APILog)
+admin.site.register(models.License)
diff --git a/license_protected_downloads/migrations/0003_auto__add_field_apikeystore_description__add_field_apikeystore_last_us.py b/license_protected_downloads/migrations/0003_auto__add_field_apikeystore_description__add_field_apikeystore_last_us.py
new file mode 100644
index 0000000..024e8ee
--- /dev/null
+++ b/license_protected_downloads/migrations/0003_auto__add_field_apikeystore_description__add_field_apikeystore_last_us.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'APIKeyStore.description'
+ db.add_column('license_protected_downloads_apikeystore', 'description',
+ self.gf('django.db.models.fields.CharField')(default='', max_length=40),
+ keep_default=False)
+
+ # Adding field 'APIKeyStore.last_used'
+ db.add_column('license_protected_downloads_apikeystore', 'last_used',
+ self.gf('django.db.models.fields.DateTimeField')(auto_now=True, null=True, blank=True),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'APIKeyStore.description'
+ db.delete_column('license_protected_downloads_apikeystore', 'description')
+
+ # Deleting field 'APIKeyStore.last_used'
+ db.delete_column('license_protected_downloads_apikeystore', 'last_used')
+
+
+ models = {
+ 'license_protected_downloads.apikeystore': {
+ 'Meta': {'object_name': 'APIKeyStore'},
+ 'description': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '40'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
+ 'last_used': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}),
+ 'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'license_protected_downloads.apilog': {
+ 'Meta': {'object_name': 'APILog'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'key': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['license_protected_downloads.APIKeyStore']", 'null': 'True', 'blank': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+ 'path': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
+ 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
+ },
+ 'license_protected_downloads.license': {
+ 'Meta': {'object_name': 'License'},
+ 'digest': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'theme': ('django.db.models.fields.CharField', [], {'max_length': '60'})
+ }
+ }
+
+ complete_apps = ['license_protected_downloads'] \ No newline at end of file
diff --git a/license_protected_downloads/models.py b/license_protected_downloads/models.py
index 22f61ca..b7099d4 100644
--- a/license_protected_downloads/models.py
+++ b/license_protected_downloads/models.py
@@ -32,6 +32,12 @@ class APIKeyStore(models.Model):
key = models.CharField(max_length=80)
public = models.BooleanField()
+ description = models.CharField(max_length=40, default='')
+ last_used = models.DateTimeField(auto_now=True, blank=True, null=True)
+
+ def __unicode__(self):
+ return '%s: %s' % (self.description, self.public)
+
class APILog(models.Model):
timestamp = models.DateTimeField(auto_now_add=True)
@@ -47,3 +53,5 @@ class APILog(models.Model):
ip = request.META.get('REMOTE_ADDR')
ip = request.META.get('HTTP_X_FORWARDED_FOR', ip).split(',')[0]
APILog.objects.create(label=label, ip=ip, path=request.path, key=key)
+ if key:
+ key.save() # bump the last_used timestamp
diff --git a/license_protected_downloads/tests/test_views.py b/license_protected_downloads/tests/test_views.py
index 38c8d67..c84d652 100644
--- a/license_protected_downloads/tests/test_views.py
+++ b/license_protected_downloads/tests/test_views.py
@@ -18,6 +18,7 @@ from django.http import HttpResponse
from license_protected_downloads.buildinfo import BuildInfo
from license_protected_downloads.config import INTERNAL_HOSTS
+from license_protected_downloads.models import APIKeyStore
from license_protected_downloads.tests.helpers import temporary_directory
from license_protected_downloads.tests.helpers import TestHttpServer
from license_protected_downloads.views import _insert_license_into_db
@@ -887,6 +888,7 @@ class ViewTests(BaseServeViewTest):
# Don't care what the key is, as long as it isn't blank
self.assertRegexpMatches(response.content, "\S+")
key = response.content
+ last_used = APIKeyStore.objects.get(key=key).last_used
# Now write a file so we can upload it
file_content = "test_get_key_post_and_get_file"
@@ -918,6 +920,8 @@ class ViewTests(BaseServeViewTest):
response = self.client.get("http://testserver/file_name")
self.assertNotEqual(response.status_code, 200)
+ self.assertNotEqual(
+ APIKeyStore.objects.get(key=key).last_used, last_used)
finally:
# Delete the files generated by the test
shutil.rmtree(os.path.join(settings.UPLOAD_PATH, key))