mirror of
https://github.com/nikdoof/test-auth.git
synced 2025-12-14 06:42:16 +00:00
Massive reworking of eve_proxy to use sha1 ids for url_paths and various other small fixes
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import httplib
|
import httplib
|
||||||
import urllib
|
import urllib
|
||||||
import xml
|
import xml
|
||||||
|
import hashlib
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -13,40 +14,74 @@ class CachedDocumentManager(models.Manager):
|
|||||||
"""
|
"""
|
||||||
This manager handles querying or retrieving CachedDocuments.
|
This manager handles querying or retrieving CachedDocuments.
|
||||||
"""
|
"""
|
||||||
def cache_from_eve_api(self, cached_doc, url_path, params, no_cache=False):
|
|
||||||
|
def get_document_id(self, url_path, params):
|
||||||
|
if params:
|
||||||
|
if 'service' in params:
|
||||||
|
del params['service']
|
||||||
|
paramstr = urllib.urlencode(params)
|
||||||
|
else:
|
||||||
|
paramstr = ''
|
||||||
|
|
||||||
|
return hashlib.sha1('%s?%s' % (url_path, paramstr)).hexdigest()
|
||||||
|
|
||||||
|
def cache_from_eve_api(self, url_path, params, no_cache=False):
|
||||||
"""
|
"""
|
||||||
Connect to the EVE API server, send the request, and cache it to
|
Connect to the EVE API server, send the request, and cache it to
|
||||||
a CachedDocument. This is typically not something you want to call
|
a CachedDocument. This is typically not something you want to call
|
||||||
directly. Use api_query().
|
directly. Use api_query().
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
method = 'GET'
|
||||||
|
paramstr = ''
|
||||||
|
|
||||||
|
if params:
|
||||||
|
if 'service' in params:
|
||||||
|
service = params['service']
|
||||||
|
del params['service']
|
||||||
|
else:
|
||||||
|
service = 'auth'
|
||||||
|
paramstr = urllib.urlencode(params)
|
||||||
|
|
||||||
|
if len(paramstr.strip()) > 0:
|
||||||
|
method = 'POST'
|
||||||
|
|
||||||
headers = {"Content-type": "application/x-www-form-urlencoded"}
|
headers = {"Content-type": "application/x-www-form-urlencoded"}
|
||||||
# This is the connection to the EVE API server.
|
|
||||||
conn = httplib.HTTPConnection(API_URL)
|
conn = httplib.HTTPConnection(API_URL)
|
||||||
# Combine everything into an HTTP request.
|
conn.request(method, url_path, paramstr, headers)
|
||||||
conn.request("POST", url_path, params, headers)
|
|
||||||
# Retrieve the response from the server.
|
|
||||||
response = conn.getresponse()
|
response = conn.getresponse()
|
||||||
# Save the response (an XML document) to the CachedDocument.
|
|
||||||
cached_doc.body = unicode(response.read(), 'utf-8')
|
print url_path, paramstr, response.status
|
||||||
|
|
||||||
try:
|
|
||||||
# Parse the response via minidom
|
|
||||||
dom = minidom.parseString(cached_doc.body.encode('utf-8'))
|
|
||||||
except xml.parsers.expat.ExpatError:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Set the CachedDocument's time_retrieved and cached_until times based
|
if response.status == 200:
|
||||||
# on the values in the XML response. This will be used in future
|
doc_id = self.get_document_id(url_path, params)
|
||||||
# requests to see if the CachedDocument can be retrieved directly or
|
cached_doc, created = self.get_or_create(url_path=doc_id)
|
||||||
# if it needs to be re-cached.
|
cached_doc.body = unicode(response.read(), 'utf-8')
|
||||||
cached_doc.time_retrieved = datetime.utcnow()
|
cached_doc.time_retrieved = datetime.utcnow()
|
||||||
cached_doc.cached_until = dom.getElementsByTagName('cachedUntil')[0].childNodes[0].nodeValue
|
|
||||||
|
|
||||||
# Finish up and return the resulting document just in case.
|
|
||||||
if no_cache == False:
|
|
||||||
cached_doc.save()
|
|
||||||
|
|
||||||
return dom
|
try:
|
||||||
|
# Parse the response via minidom
|
||||||
|
dom = minidom.parseString(cached_doc.body.encode('utf-8'))
|
||||||
|
except xml.parsers.expat.ExpatError:
|
||||||
|
cached_doc.cached_until = datetime.utcnow()
|
||||||
|
else:
|
||||||
|
cached_doc.cached_until = dom.getElementsByTagName('cachedUntil')[0].childNodes[0].nodeValue
|
||||||
|
|
||||||
|
# If this is user related, write a log instance
|
||||||
|
if params and 'userID' in params:
|
||||||
|
log = ApiAccessLog()
|
||||||
|
log.userid = params['userID']
|
||||||
|
log.service = service
|
||||||
|
log.time_access = cached_doc.time_retrieved
|
||||||
|
log.document = url_path
|
||||||
|
log.save()
|
||||||
|
|
||||||
|
# Finish up and return the resulting document just in case.
|
||||||
|
if no_cache == False:
|
||||||
|
cached_doc.save()
|
||||||
|
cached_doc = self.get(id=cached_doc.pk)
|
||||||
|
|
||||||
|
return cached_doc
|
||||||
|
|
||||||
def api_query(self, url_path, params=None, no_cache=False, exceptions=True):
|
def api_query(self, url_path, params=None, no_cache=False, exceptions=True):
|
||||||
"""
|
"""
|
||||||
@@ -61,75 +96,35 @@ class CachedDocumentManager(models.Manager):
|
|||||||
the query: userID=1&characterID=xxxxxxxx
|
the query: userID=1&characterID=xxxxxxxx
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# If we have a service ID, store and strip it from the query string.
|
doc_id = self.get_document_id(url_path, params)
|
||||||
if 'service' in params:
|
|
||||||
service = params['service']
|
doc = None
|
||||||
del params['service']
|
if not no_cache:
|
||||||
else:
|
try:
|
||||||
service = 'auth'
|
doc = super(CachedDocumentManager, self).get_query_set().get(url_path=doc_id)
|
||||||
|
except self.model.DoesNotExist:
|
||||||
if 'userID' in params:
|
pass
|
||||||
userid = params['userID']
|
|
||||||
|
|
||||||
paramstr = urllib.urlencode(params)
|
|
||||||
|
|
||||||
if params == None or paramstr.strip() == '':
|
|
||||||
# For whatever reason, EVE API freaks out if there are no parameters.
|
|
||||||
# Add a bogus parameter if none are specified. I'm sure there's a
|
|
||||||
# better fix for this.
|
|
||||||
paramstr = 'odd_parm=1'
|
|
||||||
|
|
||||||
# Combine the URL path and the parameters to create the full query.
|
|
||||||
query_name = '%s?%s' % (url_path, paramstr)
|
|
||||||
|
|
||||||
if no_cache:
|
|
||||||
# If no_cache is enabled, don't even attempt a lookup.
|
|
||||||
cached_doc = CachedDocument()
|
|
||||||
created = False
|
|
||||||
else:
|
|
||||||
# Retrieve or create a new CachedDocument based on the full URL
|
|
||||||
# and parameters.
|
|
||||||
cached_doc, created = self.get_or_create(url_path=query_name)
|
|
||||||
|
|
||||||
# EVE uses UTC.
|
# EVE uses UTC.
|
||||||
current_eve_time = datetime.utcnow()
|
current_eve_time = datetime.utcnow()
|
||||||
|
|
||||||
# Figure out if we need hit EVE API and re-cache, or just pull from
|
if not doc or current_eve_time > doc.cached_until:
|
||||||
# the local cache (based on cached_until).
|
doc = self.cache_from_eve_api(url_path, params, no_cache=no_cache)
|
||||||
if no_cache or created or \
|
|
||||||
cached_doc.cached_until == None or \
|
|
||||||
current_eve_time > cached_doc.cached_until:
|
|
||||||
# Cache from EVE API
|
|
||||||
dom = self.cache_from_eve_api(cached_doc, url_path, paramstr,
|
|
||||||
no_cache=no_cache)
|
|
||||||
|
|
||||||
# If its a user related request, log the transaction.
|
if doc:
|
||||||
if 'userID' in params:
|
dom = minidom.parseString(doc.body.encode('utf-8'))
|
||||||
log = ApiAccessLog()
|
|
||||||
log.userid = userid
|
if dom:
|
||||||
log.service = service
|
error_node = dom.getElementsByTagName('error')
|
||||||
log.time_access = datetime.utcnow()
|
if error_node and exceptions:
|
||||||
log.document = url_path
|
error_code = error_node[0].getAttribute('code')
|
||||||
log.save()
|
# User specified an invalid userid and/or auth key.
|
||||||
else:
|
if error_code == '203':
|
||||||
# Parse the document here since it was retrieved from the
|
raise APIAuthException()
|
||||||
# database cache instead of queried for.
|
elif error_code == '106':
|
||||||
dom = minidom.parseString(cached_doc.body.encode('utf-8'))
|
raise APINoUserIDException()
|
||||||
|
|
||||||
# Check for the presence errors. Only check the bare minimum,
|
|
||||||
# generic stuff that applies to most or all queries. User-level code
|
|
||||||
# should check for the more specific errors.
|
|
||||||
if dom:
|
|
||||||
error_node = dom.getElementsByTagName('error')
|
|
||||||
if error_node and exceptions:
|
|
||||||
error_code = error_node[0].getAttribute('code')
|
|
||||||
# User specified an invalid userid and/or auth key.
|
|
||||||
if error_code == '203':
|
|
||||||
raise APIAuthException()
|
|
||||||
elif error_code == '106':
|
|
||||||
raise APINoUserIDException()
|
|
||||||
|
|
||||||
return cached_doc
|
return doc
|
||||||
|
|
||||||
class CachedDocument(models.Model):
|
class CachedDocument(models.Model):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.http import HttpResponse, HttpResponseNotFound
|
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseServerError
|
||||||
from eve_proxy.models import CachedDocument
|
from eve_proxy.models import CachedDocument
|
||||||
|
|
||||||
def retrieve_xml(request):
|
def retrieve_xml(request):
|
||||||
@@ -28,14 +28,7 @@ def retrieve_xml(request):
|
|||||||
if 'userID' in params and not 'service' in params:
|
if 'userID' in params and not 'service' in params:
|
||||||
return HttpResponse('No Service ID provided.')
|
return HttpResponse('No Service ID provided.')
|
||||||
|
|
||||||
# The query system will retrieve a cached_doc that was either previously
|
cached_doc = CachedDocument.objects.api_query(url_path, params, exceptions=False)
|
||||||
# or newly cached depending on cache intervals.
|
|
||||||
try:
|
|
||||||
cached_doc = CachedDocument.objects.api_query(url_path, params, exceptions=False)
|
|
||||||
except:
|
|
||||||
return HttpResponseServerError()
|
|
||||||
|
|
||||||
# Return the document's body as XML.
|
|
||||||
|
|
||||||
if cached_doc:
|
if cached_doc:
|
||||||
return HttpResponse(cached_doc.body, mimetype='text/xml')
|
return HttpResponse(cached_doc.body, mimetype='text/xml')
|
||||||
|
|||||||
Reference in New Issue
Block a user