mirror of
https://github.com/nikdoof/test-auth.git
synced 2025-12-14 14:52:15 +00:00
Added API access tracking to EVE Proxy and presented via SSO.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from eve_proxy.models import CachedDocument
|
from eve_proxy.models import CachedDocument, ApiAccessLog
|
||||||
|
|
||||||
class CachedDocumentAdmin(admin.ModelAdmin):
|
class CachedDocumentAdmin(admin.ModelAdmin):
|
||||||
model = CachedDocument
|
model = CachedDocument
|
||||||
@@ -7,3 +7,10 @@ class CachedDocumentAdmin(admin.ModelAdmin):
|
|||||||
verbose_name = 'Cached Document'
|
verbose_name = 'Cached Document'
|
||||||
verbose_name_plural = 'Cached Documents'
|
verbose_name_plural = 'Cached Documents'
|
||||||
admin.site.register(CachedDocument, CachedDocumentAdmin)
|
admin.site.register(CachedDocument, CachedDocumentAdmin)
|
||||||
|
|
||||||
|
class ApiAccessLogAdmin(admin.ModelAdmin):
|
||||||
|
model = ApiAccessLog
|
||||||
|
list_display = ('userid', 'service', 'document', 'time_access')
|
||||||
|
verbose_name = 'API Access Log'
|
||||||
|
verbose_name_plural = 'API Access Logs'
|
||||||
|
admin.site.register(ApiAccessLog, ApiAccessLogAdmin)
|
||||||
|
|||||||
@@ -60,17 +60,17 @@ class CachedDocumentManager(models.Manager):
|
|||||||
May also be a string representation of
|
May also be a string representation of
|
||||||
the query: userID=1&characterID=xxxxxxxx
|
the query: userID=1&characterID=xxxxxxxx
|
||||||
"""
|
"""
|
||||||
if type({}) == type(params):
|
|
||||||
# If 'params' is a dictionary, convert it to a URL string.
|
paramstr = urllib.urlencode(params)
|
||||||
params = urllib.urlencode(params)
|
|
||||||
elif params == None or params.strip() == '':
|
if params == None or paramstr.strip() == '':
|
||||||
# For whatever reason, EVE API freaks out if there are no parameters.
|
# 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
|
# Add a bogus parameter if none are specified. I'm sure there's a
|
||||||
# better fix for this.
|
# better fix for this.
|
||||||
params = 'odd_parm=1'
|
paramstr = 'odd_parm=1'
|
||||||
|
|
||||||
# Combine the URL path and the parameters to create the full query.
|
# Combine the URL path and the parameters to create the full query.
|
||||||
query_name = '%s?%s' % (url_path, params)
|
query_name = '%s?%s' % (url_path, paramstr)
|
||||||
|
|
||||||
if no_cache:
|
if no_cache:
|
||||||
# If no_cache is enabled, don't even attempt a lookup.
|
# If no_cache is enabled, don't even attempt a lookup.
|
||||||
@@ -84,14 +84,33 @@ class CachedDocumentManager(models.Manager):
|
|||||||
# EVE uses UTC.
|
# EVE uses UTC.
|
||||||
current_eve_time = datetime.utcnow()
|
current_eve_time = datetime.utcnow()
|
||||||
|
|
||||||
|
# If we have a service ID, store and strip it from the query string.
|
||||||
|
if 'service' in params:
|
||||||
|
service = params['service']
|
||||||
|
del params['service']
|
||||||
|
else:
|
||||||
|
service = 'auth'
|
||||||
|
|
||||||
|
if 'userID' in params:
|
||||||
|
userid = params['userID']
|
||||||
|
|
||||||
# Figure out if we need hit EVE API and re-cache, or just pull from
|
# Figure out if we need hit EVE API and re-cache, or just pull from
|
||||||
# the local cache (based on cached_until).
|
# the local cache (based on cached_until).
|
||||||
if no_cache or created or \
|
if no_cache or created or \
|
||||||
cached_doc.cached_until == None or \
|
cached_doc.cached_until == None or \
|
||||||
current_eve_time > cached_doc.cached_until:
|
current_eve_time > cached_doc.cached_until:
|
||||||
# Cache from EVE API
|
# Cache from EVE API
|
||||||
dom = self.cache_from_eve_api(cached_doc, url_path, params,
|
dom = self.cache_from_eve_api(cached_doc, url_path, paramstr,
|
||||||
no_cache=no_cache)
|
no_cache=no_cache)
|
||||||
|
|
||||||
|
# If its a user related request, log the transaction.
|
||||||
|
if 'userID' in params:
|
||||||
|
log = ApiAccessLog()
|
||||||
|
log.userid = userid
|
||||||
|
log.service = service
|
||||||
|
log.time_access = datetime.utcnow()
|
||||||
|
log.document = url_path
|
||||||
|
log.save()
|
||||||
else:
|
else:
|
||||||
# Parse the document here since it was retrieved from the
|
# Parse the document here since it was retrieved from the
|
||||||
# database cache instead of queried for.
|
# database cache instead of queried for.
|
||||||
@@ -100,14 +119,16 @@ class CachedDocumentManager(models.Manager):
|
|||||||
# Check for the presence errors. Only check the bare minimum,
|
# Check for the presence errors. Only check the bare minimum,
|
||||||
# generic stuff that applies to most or all queries. User-level code
|
# generic stuff that applies to most or all queries. User-level code
|
||||||
# should check for the more specific errors.
|
# should check for the more specific errors.
|
||||||
error_node = dom.getElementsByTagName('error')
|
|
||||||
if error_node:
|
if dom:
|
||||||
error_code = error_node[0].getAttribute('code')
|
error_node = dom.getElementsByTagName('error')
|
||||||
# User specified an invalid userid and/or auth key.
|
if error_node:
|
||||||
if error_code == '203':
|
error_code = error_node[0].getAttribute('code')
|
||||||
raise APIAuthException()
|
# User specified an invalid userid and/or auth key.
|
||||||
elif error_code == '106':
|
if error_code == '203':
|
||||||
raise APINoUserIDException()
|
raise APIAuthException()
|
||||||
|
elif error_code == '106':
|
||||||
|
raise APINoUserIDException()
|
||||||
|
|
||||||
return cached_doc
|
return cached_doc
|
||||||
|
|
||||||
@@ -122,3 +143,12 @@ class CachedDocument(models.Model):
|
|||||||
|
|
||||||
# The custom manager handles the querying.
|
# The custom manager handles the querying.
|
||||||
objects = CachedDocumentManager()
|
objects = CachedDocumentManager()
|
||||||
|
|
||||||
|
class ApiAccessLog(models.Model):
|
||||||
|
"""
|
||||||
|
Provides a list of API accesses made by applications or Auth
|
||||||
|
"""
|
||||||
|
userid = models.IntegerField()
|
||||||
|
service = models.CharField(max_length=255)
|
||||||
|
time_access = models.DateTimeField()
|
||||||
|
document = models.CharField(max_length=255)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse, HttpResponseNotFound
|
||||||
from eve_proxy.models import CachedDocument
|
from eve_proxy.models import CachedDocument
|
||||||
|
|
||||||
def retrieve_xml(request):
|
def retrieve_xml(request):
|
||||||
@@ -12,18 +12,28 @@ def retrieve_xml(request):
|
|||||||
# The parameters attached to the end of the URL path.
|
# The parameters attached to the end of the URL path.
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
params = request.POST.urlencode()
|
p = request.POST
|
||||||
print params
|
|
||||||
else:
|
else:
|
||||||
params = request.META['QUERY_STRING']
|
p = request.GET
|
||||||
print params
|
|
||||||
|
# Convert the QuerySet object into a dict
|
||||||
|
params = {}
|
||||||
|
for key,value in p.items():
|
||||||
|
params[key] = value
|
||||||
|
|
||||||
if url_path == '/' or url_path == '':
|
if url_path == '/' or url_path == '':
|
||||||
# If they don't provide any kind of query, shoot a quick error message.
|
# If they don't provide any kind of query, shoot a quick error message.
|
||||||
return HttpResponse('No API query specified.')
|
return HttpResponse('No API query specified.')
|
||||||
|
|
||||||
|
if not 'service' in params:
|
||||||
|
return HttpResponse('No Service ID provided.')
|
||||||
|
|
||||||
# The query system will retrieve a cached_doc that was either previously
|
# The query system will retrieve a cached_doc that was either previously
|
||||||
# or newly cached depending on cache intervals.
|
# or newly cached depending on cache intervals.
|
||||||
cached_doc = CachedDocument.objects.api_query(url_path, params)
|
cached_doc = CachedDocument.objects.api_query(url_path, params)
|
||||||
# Return the document's body as XML.
|
# Return the document's body as XML.
|
||||||
return HttpResponse(cached_doc.body, mimetype='text/xml')
|
|
||||||
|
if cached_doc:
|
||||||
|
return HttpResponse(cached_doc.body, mimetype='text/xml')
|
||||||
|
|
||||||
|
return HttpResponseNotFound('Error retrieving the document')
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ urlpatterns = patterns('',
|
|||||||
(r'^profile/del/reddit/$', views.reddit_del),
|
(r'^profile/del/reddit/$', views.reddit_del),
|
||||||
(r'^profile/del/reddit/(?P<redditid>\d+)/$', views.reddit_del),
|
(r'^profile/del/reddit/(?P<redditid>\d+)/$', views.reddit_del),
|
||||||
(r'^profile/refresh/eveapi/(?P<userid>\d+)/$', views.eveapi_refresh),
|
(r'^profile/refresh/eveapi/(?P<userid>\d+)/$', views.eveapi_refresh),
|
||||||
|
(r'^profile/log/eveapi/(?P<userid>\d+)/$', views.eveapi_log),
|
||||||
(r'^profile/characters$', views.characters),
|
(r'^profile/characters$', views.characters),
|
||||||
(r'^profile/characters/(?P<charid>.*)/$', views.characters),
|
(r'^profile/characters/(?P<charid>.*)/$', views.characters),
|
||||||
(r'^users/(?P<username>.*)/$', views.user_view),
|
(r'^users/(?P<username>.*)/$', views.user_view),
|
||||||
|
|||||||
17
sso/views.py
17
sso/views.py
@@ -12,6 +12,8 @@ from eve_api.api_exceptions import APIAuthException, APINoUserIDException
|
|||||||
from eve_api.api_puller.accounts import import_eve_account
|
from eve_api.api_puller.accounts import import_eve_account
|
||||||
from eve_api.models.api_player import EVEAccount, EVEPlayerCharacter
|
from eve_api.models.api_player import EVEAccount, EVEPlayerCharacter
|
||||||
|
|
||||||
|
from eve_proxy.models import ApiAccessLog
|
||||||
|
|
||||||
from sso.models import ServiceAccount, Service, SSOUser, ExistingUser, ServiceError
|
from sso.models import ServiceAccount, Service, SSOUser, ExistingUser, ServiceError
|
||||||
from sso.forms import EveAPIForm, UserServiceAccountForm, ServiceAccountResetForm, RedditAccountForm, UserLookupForm
|
from sso.forms import EveAPIForm, UserServiceAccountForm, ServiceAccountResetForm, RedditAccountForm, UserLookupForm
|
||||||
|
|
||||||
@@ -132,6 +134,21 @@ def eveapi_refresh(request, userid=0):
|
|||||||
|
|
||||||
return HttpResponseRedirect(reverse('sso.views.profile'))
|
return HttpResponseRedirect(reverse('sso.views.profile'))
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def eveapi_log(request, userid=0):
|
||||||
|
if userid > 0 :
|
||||||
|
|
||||||
|
try:
|
||||||
|
acc = EVEAccount.objects.get(id=userid)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if acc and (acc.user == request.user or request.user.is_staff):
|
||||||
|
logs = ApiAccessLog.objects.filter(userid=userid)[:50]
|
||||||
|
return render_to_response('sso/eveapi_log.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
return HttpResponseRedirect(reverse('sso.views.profile'))
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def service_add(request):
|
def service_add(request):
|
||||||
clsform = UserServiceAccountForm(request.user)
|
clsform = UserServiceAccountForm(request.user)
|
||||||
|
|||||||
19
templates/sso/eveapi_log.html
Normal file
19
templates/sso/eveapi_log.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}EVE API Access Logs{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h1>Access Logs for API Key {{ userid }}</h1>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th>Service ID</th><th>Date / Time</th><th>API</th></tr>
|
||||||
|
{% for log in logs %}
|
||||||
|
<tr><td>{{ log.service }}</td>
|
||||||
|
<td>{{ log.time_access }}</td>
|
||||||
|
<td>{{ log.document }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -69,6 +69,7 @@ setup.</p>
|
|||||||
<td>{{ acc.api_status_description }}</td>
|
<td>{{ acc.api_status_description }}</td>
|
||||||
<td>{{ acc.api_last_updated|naturaltimediff }}</td>
|
<td>{{ acc.api_last_updated|naturaltimediff }}</td>
|
||||||
<td><a href="{% url sso.views.eveapi_refresh acc.api_user_id %}">Refresh</a>,
|
<td><a href="{% url sso.views.eveapi_refresh acc.api_user_id %}">Refresh</a>,
|
||||||
|
<a href="{% url sso.views.eveapi_log acc.api_user_id %}">Logs</a>,
|
||||||
<a href="{% url sso.views.eveapi_del acc.api_user_id %}">Delete</a></td>
|
<a href="{% url sso.views.eveapi_del acc.api_user_id %}">Delete</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user