forked from 0x2620/pandora
session data for users and guests
This commit is contained in:
parent
e669790e0f
commit
3cec9cefa2
6 changed files with 170 additions and 83 deletions
|
@ -13,7 +13,7 @@ from django.db.models import Max, Sum
|
||||||
from ox.django.shortcuts import render_to_json_response, json_response
|
from ox.django.shortcuts import render_to_json_response, json_response
|
||||||
from ox.utils import json
|
from ox.utils import json
|
||||||
|
|
||||||
from user.models import init_user, get_ui
|
from user.models import init_user
|
||||||
from item.models import ItemSort
|
from item.models import ItemSort
|
||||||
|
|
||||||
from actions import actions
|
from actions import actions
|
||||||
|
@ -69,11 +69,7 @@ def init(request):
|
||||||
key['format']['args'][0] = value
|
key['format']['args'][0] = value
|
||||||
|
|
||||||
response['data']['site'] = config
|
response['data']['site'] = config
|
||||||
if request.user.is_authenticated():
|
response['data']['user'] = init_user(request.user, request)
|
||||||
response['data']['user'] = init_user(request.user, request)
|
|
||||||
else:
|
|
||||||
response['data']['user'] = response['data']['site']['user']
|
|
||||||
response['data']['user']['ui'] = get_ui(json.loads(request.session.get('ui', '{}')))
|
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
actions.register(init)
|
actions.register(init)
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ from django.contrib.auth.models import User
|
||||||
import ox.jsonc
|
import ox.jsonc
|
||||||
from ox.utils import json
|
from ox.utils import json
|
||||||
|
|
||||||
|
|
||||||
_win = (sys.platform == "win32")
|
_win = (sys.platform == "win32")
|
||||||
|
|
||||||
RUN_RELOADER = True
|
RUN_RELOADER = True
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
from django.contrib.auth.models import User
|
from django.db.models import Q, Manager
|
||||||
|
from ox.django.query import QuerySet
|
||||||
from django.db.models import Q
|
|
||||||
|
|
||||||
def parseCondition(condition, user):
|
def parseCondition(condition, user):
|
||||||
k = condition.get('key', 'name')
|
k = condition.get('key', 'name')
|
||||||
k = {
|
k = {
|
||||||
'firstseen': 'created',
|
'email': 'user__email',
|
||||||
'lastseen': 'last_login',
|
|
||||||
'user': 'username',
|
'user': 'username',
|
||||||
'name': 'username',
|
|
||||||
}.get(k, k)
|
}.get(k, k)
|
||||||
v = condition['value']
|
v = condition['value']
|
||||||
op = condition.get('operator')
|
op = condition.get('operator')
|
||||||
|
@ -61,12 +58,40 @@ def parseConditions(conditions, operator, user):
|
||||||
return q
|
return q
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def find_user(data, user):
|
class SessionDataManager(Manager):
|
||||||
qs = User.objects.all()
|
|
||||||
query = data.get('query', {})
|
def get_query_set(self):
|
||||||
conditions = parseConditions(query.get('conditions', []),
|
return QuerySet(self.model)
|
||||||
query.get('operator', '&'),
|
|
||||||
user)
|
def find(self, data, user):
|
||||||
if conditions:
|
'''
|
||||||
qs = qs.filter(conditions)
|
query: {
|
||||||
return qs
|
conditions: [
|
||||||
|
{
|
||||||
|
value: "war"
|
||||||
|
}
|
||||||
|
{
|
||||||
|
key: "year",
|
||||||
|
value: "1970-1980,
|
||||||
|
operator: "!="
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "country",
|
||||||
|
value: "f",
|
||||||
|
operator: "^"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
operator: "&"
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
|
#join query with operator
|
||||||
|
qs = self.get_query_set()
|
||||||
|
|
||||||
|
query = data.get('query', {})
|
||||||
|
conditions = parseConditions(query.get('conditions', []),
|
||||||
|
query.get('operator', '&'),
|
||||||
|
user)
|
||||||
|
if conditions:
|
||||||
|
qs = qs.filter(conditions)
|
||||||
|
return qs
|
||||||
|
|
|
@ -4,6 +4,7 @@ import copy
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib.sessions.models import Session
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Max
|
from django.db.models import Max
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -14,6 +15,86 @@ from ox.utils import json
|
||||||
|
|
||||||
from itemlist.models import List, Position
|
from itemlist.models import List, Position
|
||||||
|
|
||||||
|
import managers
|
||||||
|
|
||||||
|
class SessionData(models.Model):
|
||||||
|
session_key = models.CharField(max_length=40, primary_key=True)
|
||||||
|
user = models.ForeignKey(User, unique=True, null=True, blank=True, related_name='data')
|
||||||
|
firstseen = models.DateTimeField(auto_now_add=True, db_index=True)
|
||||||
|
lastseen = models.DateTimeField(auto_now=True, db_index=True)
|
||||||
|
username = models.CharField(max_length=255, null=True, db_index=True)
|
||||||
|
|
||||||
|
timesseen = models.IntegerField(default=0)
|
||||||
|
ip = models.CharField(default='', max_length=255)
|
||||||
|
useragent = models.CharField(default='', max_length=255)
|
||||||
|
windowsize = models.CharField(default='', max_length=255)
|
||||||
|
screensize = models.CharField(default='', max_length=255)
|
||||||
|
info = DictField(default={})
|
||||||
|
|
||||||
|
|
||||||
|
objects = managers.SessionDataManager()
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return u"%s" % self.session_key
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if self.user:
|
||||||
|
self.username = self.user.username
|
||||||
|
self.firstseen = self.user.date_joined
|
||||||
|
super(SessionData, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_or_create(cls, request):
|
||||||
|
session_key = request.session.session_key
|
||||||
|
if request.user.is_authenticated():
|
||||||
|
cls.objects.filter(user=request.user).update(session_key=session_key)
|
||||||
|
data, created = cls.objects.get_or_create(session_key=session_key)
|
||||||
|
if request.user.is_authenticated():
|
||||||
|
data.user = request.user
|
||||||
|
data.info = json.loads(request.POST.get('data', '{}'))
|
||||||
|
screen = data.info.get('screen', {})
|
||||||
|
if 'height' in screen and 'width' in screen:
|
||||||
|
data.screensize = '%sx%s' % (screen['width'], screen['height'])
|
||||||
|
window = data.info.get('window', {})
|
||||||
|
if 'outerHeight' in window and 'outerWidth' in window:
|
||||||
|
data.windowsize = '%sx%s' % (window['outerWidth'], window['outerHeight'])
|
||||||
|
data.ip = request.META['REMOTE_ADDR']
|
||||||
|
data.useragent = request.META['HTTP_USER_AGENT']
|
||||||
|
if not data.timesseen:
|
||||||
|
data.timesseen = 0
|
||||||
|
data.timesseen += 1
|
||||||
|
data.save()
|
||||||
|
return data
|
||||||
|
|
||||||
|
def json(self, keys=None, user=None):
|
||||||
|
j = {
|
||||||
|
'disabled': False,
|
||||||
|
'email': '',
|
||||||
|
'firstseen': self.firstseen,
|
||||||
|
'ip': self.ip,
|
||||||
|
'id': self.user and ox.to26(self.user.id) or self.session_key,
|
||||||
|
'lastseen': self.lastseen,
|
||||||
|
'level': 'guest',
|
||||||
|
'notes': '',
|
||||||
|
'numberoflists': 0,
|
||||||
|
'screensize': self.screensize,
|
||||||
|
'timesseen': self.timesseen,
|
||||||
|
'username': self.username or '',
|
||||||
|
'useragent': self.useragent,
|
||||||
|
'windowsize': self.windowsize,
|
||||||
|
}
|
||||||
|
if self.user:
|
||||||
|
p = self.user.get_profile()
|
||||||
|
j['disabled'] = not self.user.is_active
|
||||||
|
j['email'] = self.user.email
|
||||||
|
j['level'] = p.get_level()
|
||||||
|
j['notes'] = p.notes
|
||||||
|
j['numberoflists'] = self.user.lists.count()
|
||||||
|
if keys:
|
||||||
|
for key in j.keys():
|
||||||
|
if key not in keys:
|
||||||
|
del j[key]
|
||||||
|
return j
|
||||||
|
|
||||||
class UserProfile(models.Model):
|
class UserProfile(models.Model):
|
||||||
reset_code = models.CharField(max_length=255, blank=True, null=True, unique=True)
|
reset_code = models.CharField(max_length=255, blank=True, null=True, unique=True)
|
||||||
|
@ -25,12 +106,6 @@ class UserProfile(models.Model):
|
||||||
ui = DictField(default={})
|
ui = DictField(default={})
|
||||||
preferences = DictField(default={})
|
preferences = DictField(default={})
|
||||||
|
|
||||||
timesseen = models.IntegerField(default=0)
|
|
||||||
ip = models.CharField(default='', max_length=255)
|
|
||||||
useragent = models.CharField(default='', max_length=255)
|
|
||||||
windowsize = models.CharField(default='', max_length=255)
|
|
||||||
screensize = models.CharField(default='', max_length=255)
|
|
||||||
info = DictField(default={})
|
|
||||||
notes = models.TextField(default='')
|
notes = models.TextField(default='')
|
||||||
|
|
||||||
def get_ui(self):
|
def get_ui(self):
|
||||||
|
@ -105,54 +180,39 @@ def get_ui(user_ui, user=None):
|
||||||
del ui['lists'][i]
|
del ui['lists'][i]
|
||||||
return ui
|
return ui
|
||||||
|
|
||||||
def user_json(user, keys=None, request_user=None):
|
def init_user(user, request=None):
|
||||||
|
data = SessionData.get_or_create(request)
|
||||||
|
if user.is_anonymous():
|
||||||
|
result = settings.CONFIG['user'].copy()
|
||||||
|
result['ui'] = get_ui(json.loads(request.session.get('ui', '{}')))
|
||||||
|
else:
|
||||||
|
profile = user.get_profile()
|
||||||
|
result = {}
|
||||||
|
for key in ('username', ):
|
||||||
|
result[key] = getattr(user, key)
|
||||||
|
result['level'] = profile.get_level()
|
||||||
|
result['groups'] = [g.name for g in user.groups.all()]
|
||||||
|
result['email'] = user.email
|
||||||
|
result['ui'] = profile.get_ui()
|
||||||
|
result['volumes'] = [v.json() for v in user.volumes.all()]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def user_json(user, keys=None):
|
||||||
p = user.get_profile()
|
p = user.get_profile()
|
||||||
j = {
|
j = {
|
||||||
'disabled': not user.is_active,
|
'disabled': not user.is_active,
|
||||||
'email': user.email,
|
'email': user.email,
|
||||||
'firstseen': user.date_joined,
|
'firstseen': user.date_joined,
|
||||||
'ip': p.ip,
|
|
||||||
'id': ox.to26(user.id),
|
'id': ox.to26(user.id),
|
||||||
'lastseen': user.last_login,
|
'lastseen': user.last_login,
|
||||||
'level': p.get_level(),
|
'level': p.get_level(),
|
||||||
'notes': p.notes,
|
'notes': p.notes,
|
||||||
'numberoflists': user.lists.count(),
|
'numberoflists': user.lists.count(),
|
||||||
'screensize': p.screensize,
|
|
||||||
'timesseen': p.timesseen,
|
|
||||||
'username': user.username,
|
'username': user.username,
|
||||||
'useragent': p.useragent,
|
|
||||||
'windowsize': p.windowsize,
|
|
||||||
}
|
}
|
||||||
if keys:
|
if keys:
|
||||||
for key in j.keys():
|
for key in j.keys():
|
||||||
if key not in keys:
|
if key not in keys:
|
||||||
del j[key]
|
del j[key]
|
||||||
return j
|
return j
|
||||||
|
|
||||||
def init_user(user, request=None):
|
|
||||||
profile = user.get_profile()
|
|
||||||
if request:
|
|
||||||
data = json.loads(request.POST.get('data', '{}'))
|
|
||||||
profile.info = data
|
|
||||||
screen = data.get('screen', {})
|
|
||||||
if 'height' in screen and 'width' in screen:
|
|
||||||
profile.screensize = '%sx%s' % (screen['width'], screen['height'])
|
|
||||||
window = data.get('window', {})
|
|
||||||
if 'outerHeight' in window and 'outerWidth' in window:
|
|
||||||
profile.windowsize = '%sx%s' % (window['outerWidth'], window['outerHeight'])
|
|
||||||
profile.ip = request.META['REMOTE_ADDR']
|
|
||||||
profile.useragent = request.META['HTTP_USER_AGENT']
|
|
||||||
if not profile.timesseen:
|
|
||||||
profile.timesseen = 0
|
|
||||||
profile.timesseen += 1
|
|
||||||
profile.save()
|
|
||||||
result = {}
|
|
||||||
for key in ('username', ):
|
|
||||||
result[key] = getattr(user, key)
|
|
||||||
result['level'] = profile.get_level()
|
|
||||||
result['groups'] = [g.name for g in user.groups.all()]
|
|
||||||
result['email'] = user.email
|
|
||||||
result['ui'] = profile.get_ui()
|
|
||||||
result['volumes'] = [v.json() for v in user.volumes.all()]
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
|
@ -340,7 +340,7 @@ def editUser(request):
|
||||||
user.username = data['username']
|
user.username = data['username']
|
||||||
user.save()
|
user.save()
|
||||||
profile.save()
|
profile.save()
|
||||||
response['data'] = models.user_json(user)
|
response['data'] = user.data.get().json()
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
actions.register(editUser, cache=False)
|
actions.register(editUser, cache=False)
|
||||||
|
|
||||||
|
@ -403,7 +403,7 @@ def parse_query(data, user):
|
||||||
for key in ('keys', 'range', 'sort', 'query'):
|
for key in ('keys', 'range', 'sort', 'query'):
|
||||||
if key in data:
|
if key in data:
|
||||||
query[key] = data[key]
|
query[key] = data[key]
|
||||||
query['qs'] = managers.find_user(query, user)
|
query['qs'] = models.SessionData.objects.find(query, user)
|
||||||
return query
|
return query
|
||||||
|
|
||||||
def order_query(qs, sort):
|
def order_query(qs, sort):
|
||||||
|
@ -413,21 +413,23 @@ def order_query(qs, sort):
|
||||||
if operator != '-':
|
if operator != '-':
|
||||||
operator = ''
|
operator = ''
|
||||||
key = {
|
key = {
|
||||||
'email': 'email',
|
'email': 'user__email',
|
||||||
'firstseen': 'date_joined',
|
'firstseen': 'firstseen',
|
||||||
'lastseen': 'last_login',
|
'ip': 'ip',
|
||||||
|
'lastseen': 'lastseen',
|
||||||
|
'screensize': 'screensize',
|
||||||
|
'timesseen': 'timesseen',
|
||||||
|
'useragent': 'useragent',
|
||||||
'username': 'username',
|
'username': 'username',
|
||||||
'name': 'username',
|
'windowsize': 'windowsize',
|
||||||
}.get(e['key'], 'profile__%s'%e['key'])
|
}.get(e['key'], 'user__profile__%s'%e['key'])
|
||||||
if key == 'profile__numberoflists':
|
if key == 'user__profile__numberoflists':
|
||||||
qs = qs.annotate(numberoflists=Sum('lists'))
|
qs = qs.annotate(numberoflists=Sum('user__lists'))
|
||||||
key = 'numberoflists'
|
key = 'numberoflists'
|
||||||
order = '%s%s' % (operator, key)
|
order = '%s%s' % (operator, key)
|
||||||
order_by.append(order)
|
order_by.append(order)
|
||||||
if order_by:
|
if order_by:
|
||||||
#user table does not support this
|
qs = qs.order_by(*order_by, nulls_last=True)
|
||||||
#qs = qs.order_by(*order_by, nulls_last=True)
|
|
||||||
qs = qs.order_by(*order_by)
|
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
@admin_required_json
|
@admin_required_json
|
||||||
|
@ -499,7 +501,7 @@ Positions
|
||||||
qs = order_query(query['qs'], query['sort'])
|
qs = order_query(query['qs'], query['sort'])
|
||||||
if 'keys' in data:
|
if 'keys' in data:
|
||||||
qs = qs[query['range'][0]:query['range'][1]]
|
qs = qs[query['range'][0]:query['range'][1]]
|
||||||
response['data']['items'] = [models.user_json(p, data['keys'], request.user) for p in qs]
|
response['data']['items'] = [p.json(data['keys'], request.user) for p in qs]
|
||||||
elif 'position' in query:
|
elif 'position' in query:
|
||||||
ids = [i.get_id() for i in qs]
|
ids = [i.get_id() for i in qs]
|
||||||
data['conditions'] = data['conditions'] + {
|
data['conditions'] = data['conditions'] + {
|
||||||
|
|
|
@ -77,9 +77,6 @@ pandora.ui.usersDialog = function() {
|
||||||
title: $('<img>').attr({
|
title: $('<img>').attr({
|
||||||
src: Ox.UI.getImageURL('symbolCheck')
|
src: Ox.UI.getImageURL('symbolCheck')
|
||||||
}),
|
}),
|
||||||
tooltip: function(data) {
|
|
||||||
return data.disabled ? 'Enable User' : 'Disable User';
|
|
||||||
},
|
|
||||||
visible: true,
|
visible: true,
|
||||||
width: 16
|
width: 16
|
||||||
},
|
},
|
||||||
|
@ -221,10 +218,14 @@ pandora.ui.usersDialog = function() {
|
||||||
$user.empty();
|
$user.empty();
|
||||||
if (data.ids.length) {
|
if (data.ids.length) {
|
||||||
values = $list.value(data.ids[0]);
|
values = $list.value(data.ids[0]);
|
||||||
$userLabel.options({
|
if(values.level != 'guest') {
|
||||||
title: values.username + ' <' + values.email + '>'
|
$userLabel.options({
|
||||||
});
|
title: values.username + ' <' + values.email + '>'
|
||||||
$user.append(renderUserForm(values))
|
});
|
||||||
|
$user.append(renderUserForm(values));
|
||||||
|
} else {
|
||||||
|
$userLabel.options({title: 'Guest'});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$userLabel.options({title: 'No user selected'});
|
$userLabel.options({title: 'No user selected'});
|
||||||
}
|
}
|
||||||
|
@ -269,8 +270,10 @@ pandora.ui.usersDialog = function() {
|
||||||
.addClass('OxSelectable')
|
.addClass('OxSelectable')
|
||||||
.css({margin: '16px'})
|
.css({margin: '16px'})
|
||||||
.html(
|
.html(
|
||||||
result.data.items.map(function(item) {
|
result.data.items.filter(function(item) {
|
||||||
return item.username + ' <' + item.email + '>'
|
return item.email;
|
||||||
|
}).map(function(item) {
|
||||||
|
return item.username + ' <' + item.email + '>';
|
||||||
}).join(', ')
|
}).join(', ')
|
||||||
),
|
),
|
||||||
title: 'E-Mail Addresses'
|
title: 'E-Mail Addresses'
|
||||||
|
|
Loading…
Reference in a new issue