Skip to content

Commit

Permalink
Added logging to views and command line functions. Fixes #26. Also ad…
Browse files Browse the repository at this point in the history
…ded fixture data for command line requester. Added admin flag to Requester model Fixes #24.  Also authenticate requests by remote IP address. Fixes #23.
  • Loading branch information
Joshua Gomez committed May 2, 2012
1 parent 6ef9b1e commit 825abb4
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 41 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,4 +1,5 @@
*.pyc *.pyc
*.log
ENV ENV
lids/lids/local_settings.py lids/lids/local_settings.py
*~ *~
Expand Down
3 changes: 3 additions & 0 deletions lids/lidapp/management/commands/bind.py
@@ -1,6 +1,7 @@
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from lidapp.models import ID from lidapp.models import ID
from optparse import make_option from optparse import make_option
import logging




class Command(BaseCommand): class Command(BaseCommand):
Expand All @@ -26,6 +27,7 @@ class Command(BaseCommand):
) )


def handle(self, *args, **options): def handle(self, *args, **options):
logger = logging.getLogger('lidapp.actions')
identifier = args[0] identifier = args[0]
try: try:
id = ID.objects.get(identifier=identifier) id = ID.objects.get(identifier=identifier)
Expand All @@ -38,4 +40,5 @@ def handle(self, *args, **options):
kwargs[opt] = options[opt] kwargs[opt] = options[opt]
id.bind(**kwargs) id.bind(**kwargs)


logger.info('Action: bind IP: 127.0.0.1 ID: %s Result:SUCCESS. Data: %s' % (identifier, kwargs))
self.stdout.write(id.dump_string() + '\n') self.stdout.write(id.dump_string() + '\n')
3 changes: 3 additions & 0 deletions lids/lidapp/management/commands/lookup.py
@@ -1,16 +1,19 @@
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from lidapp.models import ID from lidapp.models import ID
import logging




class Command(BaseCommand): class Command(BaseCommand):
args = '<identifier>' args = '<identifier>'
help = 'Get metadata for an identifier' help = 'Get metadata for an identifier'


def handle(self, *args, **options): def handle(self, *args, **options):
logger = logging.getLogger('lidapp.actions')
identifier = args[0] identifier = args[0]
try: try:
id = ID.objects.get(identifier=identifier) id = ID.objects.get(identifier=identifier)
except ID.DoesNotExist: except ID.DoesNotExist:
raise CommandError('Identifier "%s" does not exist' % identifier) raise CommandError('Identifier "%s" does not exist' % identifier)


logger.info('Action: lookup IP: 127.0.0.1 ID: %s Result:SUCCESS.' % identifier)
self.stdout.write(id.dump_string() + '\n') self.stdout.write(id.dump_string() + '\n')
13 changes: 8 additions & 5 deletions lids/lidapp/management/commands/mint.py
Expand Up @@ -2,6 +2,7 @@
from lidapp.models import ID, Minter, Requester from lidapp.models import ID, Minter, Requester
from optparse import make_option from optparse import make_option
from django.utils.timezone import now from django.utils.timezone import now
import logging


class Command(BaseCommand): class Command(BaseCommand):
args = '<minter_name>' args = '<minter_name>'
Expand All @@ -22,21 +23,23 @@ class Command(BaseCommand):
) )


def handle(self, *args, **options): def handle(self, *args, **options):
logger = logging.getLogger('lidapp.actions')
try: try:
minter_name = args[0] minter_name = args[0]
minter = Minter.objects.get(name=minter_name)
requester = Requester.objects.get(ip='127.0.0.1')
except IndexError: except IndexError:
raise CommandError('Please specify a minter') raise CommandError('Please specify a minter')
try:
minter = Minter.objects.get(name=minter_name)
except Minter.DoesNotExist: except Minter.DoesNotExist:
raise CommandError('Minter "%s" does not exist' % minter_name) raise CommandError('Minter "%s" does not exist' % minter_name)
try:
requester = Requester.objects.get(name='CommandLine')
except Requester.DoesNotExist: except Requester.DoesNotExist:
requester = Requester.objects.create(name='CommandLine', date_created=now()) requester = Requester.objects.create(name='Command Line', date_created=now(),admin=True, ip='127.0.0.1')


ids = minter.mint(requester=requester, quantity=options['quantity']) ids = minter.mint(requester=requester, quantity=options['quantity'])


for x in range(options['quantity']):
logger.info('Action: mint %s of %s IP: 127.0.0.1 Result:SUCCESS. Minted %s' % (x+1, options['quantity'], ids[x].identifier))

if not options['verbose']: if not options['verbose']:
output = '\n'.join([id.identifier for id in ids]) output = '\n'.join([id.identifier for id in ids])
self.stdout.write(output+'\n') self.stdout.write(output+'\n')
Expand Down
4 changes: 3 additions & 1 deletion lids/lidapp/models.py
Expand Up @@ -7,8 +7,10 @@
class Requester(models.Model): class Requester(models.Model):


name = models.CharField(max_length=63, unique=True) name = models.CharField(max_length=63, unique=True)
organization = models.CharField(max_length=63) organization = models.CharField(max_length=63, blank=True)
ip = models.IPAddressField(unique=True)
date_created = models.DateTimeField() date_created = models.DateTimeField()
admin = models.BooleanField(default=False)
description = models.TextField(blank=True) description = models.TextField(blank=True)


def __unicode__(self): def __unicode__(self):
Expand Down
1 change: 1 addition & 0 deletions lids/lidapp/sql/requester.sql
@@ -0,0 +1 @@
INSERT INTO lidapp_requester (name, ip, date_created, admin) VALUES ('Command Line', '127.0.0.1', NOW(), TRUE);
60 changes: 52 additions & 8 deletions lids/lidapp/views.py
@@ -1,32 +1,76 @@
from django.http import HttpResponse from django.http import HttpResponse, Http404, HttpResponseForbidden
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import redirect
from django.utils.timezone import now
from lidapp.models import ID, Minter, Requester from lidapp.models import ID, Minter, Requester
import logging
import json import json


logger = logging.getLogger('lidapp.actions')

def _ids_to_json(ids): def _ids_to_json(ids):
return json.dumps([id.dump_dict() for id in ids], indent=2) return json.dumps([id.dump_dict() for id in ids], indent=2)


def mint(request, minter_name, quantity=1): def mint(request, minter_name, quantity=1):
minter = get_object_or_404(Minter, name=minter_name) ip = request.META['REMOTE_ADDR']
requester = get_object_or_404(Requester, name=request.GET['requester']) quantity = int(quantity)
try:
requester = Requester.objects.get(ip=ip)
minter = Minter.objects.get(name=minter_name)
except Requester.DoesNotExist:
logger.info('Action: mint %s IP: %s Result:FAILED. IP not recognized' %(quantity, ip))
raise Http404('You are not permitted to mint IDs from IP address %s' % ip)
except Minter.DoesNotExist:
logger.info('Action: mint %s IP: %s Result:FAILED. Minter %s does not exist' % (quantity, ip, minter_name))
raise Http404('Minter %s does not exist' % minter_name)
ids = minter.mint(requester=requester, quantity=quantity) ids = minter.mint(requester=requester, quantity=quantity)
for x in range(quantity):
logger.info('Action: mint %s of %s IP: %s Result:SUCCESS. Minted %s' % (x+1, quantity, ip, ids[x].identifier))
return HttpResponse(_ids_to_json(ids), content_type='application/json') return HttpResponse(_ids_to_json(ids), content_type='application/json')


def bind(request, identifier): def bind(request, identifier):
id = get_object_or_404(ID, identifier=identifier) ip = request.META['REMOTE_ADDR']
try:
requester = Requester.objects.get(ip=ip)
id = ID.objects.get(identifier=identifier)
except Requester.DoesNotExist:
logger.info('Action: bind IP: %s ID: %s Result:FAILED. IP not recognized' % (ip, identifier))
raise Http404('You are not permitted to bind IDs from IP address %s' % ip)
except ID.DoesNotExist:
logger.info('Action: bind IP: %s ID: %s Result:FAILED. Identifier does not exist' % (ip, identifier))
raise Http404('ID %s does not exist %s' % identifier)
if requester.admin == False and not id.requester.ip == requester.ip:
logger.info('Action: bind IP: %s ID: %s Result:FAILED. Requester not authorized to edit ID' % (ip, identifier))
return HttpResponseForbidden('You are not authorized to bind data to ID %s from IP address %s' % (identifier, ip))
kwargs = {} kwargs = {}
for field in id.bindable_fields: for field in id.bindable_fields:
if field in request.GET: if field in request.GET:
kwargs[field] = request.GET[field] kwargs[field] = request.GET[field]
id.bind(**kwargs) id.bind(**kwargs)
logger.info('Action: bind IP: %s ID: %s Result:SUCCESS. Data: %s' % (ip, identifier, kwargs))
return HttpResponse(_ids_to_json([id]), content_type='application/json') return HttpResponse(_ids_to_json([id]), content_type='application/json')


def lookup(request, identifier): def lookup(request, identifier):
id = get_object_or_404(ID,identifier=identifier) ip = request.META['REMOTE_ADDR']
try:
id = ID.objects.get(identifier=identifier)
except ID.DoesNotExist:
logger.info('Action: lookup IP: %s ID: %s Result:FAILED. Identifier does not exist' % (ip, identifier))
raise Http404('ID %s does not exist %s' % identifier)
logger.info('Action: lookup IP: %s ID: %s Result:SUCCESS.' % (ip, identifier))
return HttpResponse(_ids_to_json([id]), content_type='application/json') return HttpResponse(_ids_to_json([id]), content_type='application/json')


def resolve(request, identifier): def resolve(request, identifier):
id = get_object_or_404(ID,identifier=identifier) ip = request.META['REMOTE_ADDR']
try:
id = ID.objects.get(identifier=identifier)
except ID.DoesNotExist:
logger.info('Action: resolve IP: %s ID: %s Result:FAILED. Identifier does not exist' % (ip, identifier))
raise Http404('ID %s does not exist' % identifier)
if id.object_url: if id.object_url:
url = id.object_url if id.object_url.startswith('http://') else 'http://'+id.object_url url = id.object_url if id.object_url.startswith('http') else 'http://'+id.object_url
logger.info('Action: resolve IP: %s ID: %s Result:SUCCESS.' % (ip, identifier))
return redirect(url) return redirect(url)
else:
logger.info('Action: resolve IP: %s ID: %s Result:FAILED. Identifier has not been bound to a url' % (ip, identifier))
raise Http404('ID %s has not been bound to a url' % identifier)
#TODO: provide a more graceful resolution error page
52 changes: 25 additions & 27 deletions lids/lids/settings.py
Expand Up @@ -127,34 +127,32 @@
'lidapp', 'lidapp',
) )


# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = { LOGGING = {
'version': 1, 'version': 1,
'disable_existing_loggers': False, 'disable_existing_loggers': True,
'filters': { 'formatters': {
'require_debug_false': { 'standard': {
'()': 'django.utils.log.RequireDebugFalse' 'format': '%(asctime)s %(levelname)s: %(message)s'
} },
}, },
'handlers': { 'handlers': {
'mail_admins': { 'file': {
'level': 'ERROR', 'level': 'INFO',
'filters': ['require_debug_false'], 'class': 'logging.handlers.RotatingFileHandler',
'class': 'django.utils.log.AdminEmailHandler' 'filename': os.path.join(os.path.dirname(__file__), 'logs', 'actions.log'),
} 'maxBytes': 1024*1024*5,
}, 'backupCount': 10,
'loggers': { 'formatter': 'standard'
'django.request': { },
'handlers': ['mail_admins'], },
'level': 'ERROR', 'loggers': {
'propagate': True, 'lidapp.actions': {
}, 'handlers': ['file'],
} 'level': 'INFO',
} 'propogate': False,
},
},
}


# Models settings # Models settings
OBJECT_TYPES = ( OBJECT_TYPES = (
Expand Down

0 comments on commit 825abb4

Please sign in to comment.