mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add basic user management to the server
This code is mostly just a stub, will need to be fleshed out later.
This commit is contained in:
parent
08fa7a72c1
commit
424a430d15
@ -6,7 +6,7 @@
|
||||
<meta name="robots" content="noindex">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/png" href="favicon.png">
|
||||
<script>window.calibre_entry_point = 'ENTRY_POINT'; window.calibre_username = USERNAME;</script>
|
||||
<script>window.calibre_entry_point = 'ENTRY_POINT';</script>
|
||||
<script type="text/javascript" src="static/main.js"></script>
|
||||
<link rel="stylesheet" href="static/reset.css"></link>
|
||||
<link rel="stylesheet" href="static/font-awesome/fa.css"></link>
|
||||
|
@ -593,7 +593,19 @@ def interface_data(ctx, rd):
|
||||
'''
|
||||
ans = {'username':rd.username}
|
||||
ans['library_map'], ans['default_library'] = ctx.library_map
|
||||
ud = {}
|
||||
if rd.username:
|
||||
# Override session data with stored values for the authenticated user,
|
||||
# if any
|
||||
ud = ctx.user_manager.get_session_data(rd.username)
|
||||
lid = ud.get('library_id')
|
||||
if lid and lid in ans['library_map']:
|
||||
rd.query.set('library_id', lid)
|
||||
usort = ud.get('sort')
|
||||
if usort:
|
||||
rd.query.set('sort', usort)
|
||||
ans['library_id'], db, sorts, orders = get_basic_query_data(ctx, rd.query)
|
||||
ans['user_session_data'] = ud
|
||||
try:
|
||||
num = int(rd.query.get('num', 50))
|
||||
except Exception:
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
import re, json
|
||||
import re
|
||||
from functools import partial
|
||||
from threading import Lock
|
||||
|
||||
@ -44,5 +44,4 @@ def get_html(name, auto_reload_port, **replacements):
|
||||
def index(ctx, rd):
|
||||
return rd.generate_static_output('/', partial(
|
||||
get_html, 'content-server/index.html', getattr(rd.opts, 'auto_reload_port', 0),
|
||||
USERNAME=json.dumps(rd.username), ENTRY_POINT='book list',
|
||||
LOADING_MSG=prepare_string_for_xml(_('Loading library, please wait'))))
|
||||
ENTRY_POINT='book list', LOADING_MSG=prepare_string_for_xml(_('Loading library, please wait'))))
|
||||
|
@ -15,6 +15,7 @@ from threading import Lock
|
||||
from calibre.db.cache import Cache
|
||||
from calibre.db.legacy import create_backend, LibraryDatabase
|
||||
from calibre.srv.routes import Router
|
||||
from calibre.srv.users import UserManager
|
||||
from calibre.utils.date import utcnow
|
||||
|
||||
def init_library(library_path):
|
||||
@ -85,6 +86,7 @@ class Context(object):
|
||||
self.library_broker = LibraryBroker(libraries)
|
||||
self.testing = testing
|
||||
self.lock = Lock()
|
||||
self.user_manager = UserManager()
|
||||
|
||||
def init_session(self, endpoint, data):
|
||||
pass
|
||||
|
66
src/calibre/srv/users.py
Normal file
66
src/calibre/srv/users.py
Normal file
@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python2
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
import os, json
|
||||
|
||||
import apsw
|
||||
|
||||
from calibre.constants import config_dir
|
||||
from calibre.utils.config import to_json, from_json
|
||||
|
||||
class UserManager(object):
|
||||
|
||||
@property
|
||||
def conn(self):
|
||||
if self._conn is None:
|
||||
self._conn = apsw.Connection(self.path)
|
||||
c = self._conn.cursor()
|
||||
uv = next(c.execute('PRAGMA foreign_keys = ON; PRAGMA user_version'))[0]
|
||||
if uv == 0:
|
||||
c.execute('''
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
salt TEXT NOT NULL,
|
||||
hashed_pw TEXT NOT NULL,
|
||||
hash_type TEXT NOT NULL,
|
||||
creation_date INTEGER NOT NULL,
|
||||
UNIQUE(name)
|
||||
);
|
||||
|
||||
CREATE TABLE session_data (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user INTEGER NOT NULL,
|
||||
data TEXT NOT NULL,
|
||||
UNIQUE(user),
|
||||
FOREIGN KEY user REFERENCES users.id
|
||||
);
|
||||
|
||||
PRAGMA user_version=1;
|
||||
''')
|
||||
c.close()
|
||||
|
||||
def __init__(self):
|
||||
self.path = os.path.join(config_dir, 'server-users.sqlite')
|
||||
self._conn = None
|
||||
|
||||
def get_session_data(self, username):
|
||||
for data, in self.conn.cursor().execute(
|
||||
'SELECT data FROM session_data INNER JOIN users ON (session_data.user = users.id) WHERE users.name=?', (username,)):
|
||||
try:
|
||||
return json.loads(data, object_hook=from_json)
|
||||
except Exception:
|
||||
pass
|
||||
return {}
|
||||
|
||||
def set_session_data(self, username, data):
|
||||
conn = self.conn
|
||||
c = conn.cursor()
|
||||
for user_id, in c.execute('SELECT id FROM users WHERE name=?', (username,)):
|
||||
data = json.dumps(data, ensure_ascii=False, default=to_json)
|
||||
c.execute('UPDATE session_data SET data=? WHERE user=?', (data, user_id))
|
||||
if not conn.changes():
|
||||
c.execute('INSERT INTO session_data (data,user) VALUES (?,?)', (data, user_id))
|
@ -4,7 +4,7 @@
|
||||
from ajax import ajax
|
||||
from elementmaker import E
|
||||
from gettext import gettext as _
|
||||
from session import UserSessionData
|
||||
from session import UserSessionData, SessionData
|
||||
from book_list.boss import Boss
|
||||
from book_list.globals import set_boss, set_session_data
|
||||
|
||||
@ -13,6 +13,7 @@ def on_library_loaded(end_type, xhr, ev):
|
||||
p.parentNode.removeChild(p)
|
||||
if end_type == 'load':
|
||||
interface_data = JSON.parse(xhr.responseText)
|
||||
set_session_data(UserSessionData(interface_data['username']))
|
||||
# TODO: Copy any user specific session data from the server to
|
||||
# the local session data object, overriding local data
|
||||
boss = Boss(interface_data)
|
||||
@ -28,11 +29,8 @@ def on_library_load_progress(loaded, total):
|
||||
p.value = loaded
|
||||
|
||||
def load_book_list():
|
||||
sd = set_session_data(UserSessionData(window.calibre_username))
|
||||
query = {}
|
||||
if not sd.has_user:
|
||||
# For authenticated users use the session data cached on the server
|
||||
query = {'library_id':sd.get('library_id'), 'sort':sd.get('sort')}
|
||||
temp = SessionData() # So that settings for anonymous users are preserved
|
||||
query = {'library_id':temp.get('library_id'), 'sort':temp.get('sort')}
|
||||
ajax('ajax/interface-data', on_library_loaded, on_library_load_progress, query=query).send()
|
||||
|
||||
def on_load():
|
||||
|
Loading…
x
Reference in New Issue
Block a user