gnuradionetwork/frn/manager/database.py

151 lines
6.3 KiB
Python
Raw Normal View History

2010-08-18 15:46:58 +00:00
# -*- coding: utf-8 -*-
#
# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
# See LICENSE.txt for copyright info
from zope.interface import implements
2010-08-18 15:46:58 +00:00
from frn.manager import IManager
from twisted.python import log
from twisted.python.failure import Failure
from twisted.mail.smtp import sendmail
import random, string, uuid
from frn.user import FRNUser
2010-08-18 15:46:58 +00:00
def rndpasswd():
return ''.join([random.choice(string.ascii_uppercase) for i in range(8)])
2010-08-18 15:46:58 +00:00
class DatabaseManager(object):
implements(IManager)
def __init__(self, pool):
self._pool = pool
self._pool.runOperation("""
CREATE TABLE IF NOT EXISTS frn_users (
_id VARCHAR(32) NOT NULL PRIMARY KEY,
_ea VARCHAR(30) UNIQUE NOT NULL,
_pw VARCHAR(20) NOT NULL,
_on VARCHAR(20) NOT NULL,
_bc VARCHAR(20) NOT NULL,
_nn VARCHAR(20) NOT NULL,
_ct VARCHAR(20) NOT NULL,
_nt VARCHAR(20),
_ds VARCHAR(20) NOT NULL,
_ip VARCHAR(20),
registration TIMESTAMP NOT NULL DEFAULT current_timestamp,
lastlogin TIMESTAMP,
server VARCHAR(20),
port INTEGER
);
""")
self._pool.runOperation("""
CREATE TABLE IF NOT EXISTS frn_servers (
_vx VARCHAR(7) NOT NULL,
_sn VARCHAR(20) NOT NULL,
_pt INTEGER NOT NULL,
_bn VARCHAR(20),
_bp integer,
_ow VARCHAR(30) NOT NULL,
registration TIMESTAMP NOT NULL DEFAULT current_timestamp,
PRIMARY KEY(_sn, _pt)
);
""")
2010-08-18 15:46:58 +00:00
def serverLogin(self, server):
def checkauth(res):
if not isinstance(res, Failure):
if res[0] > 0:
return self._pool.runOperation("""
INSERT INTO frn_servers
(_vx, _sn, _pt, _bn, _bp, _ow) VALUES
(?,?,?,?,?,?)
""", (server.VX, server.SN, server.PT,
server.BN, server.BP, server.OW)).addCallbacks(
lambda x: 0, lambda x: -1)
else:
return -1
return self._pool.runQuery("SELECT count(*) FROM frn_users WHERE _ea=? AND _pw=?",
(server.OW, server.PW)).addBoth(checkauth)
2010-08-18 15:46:58 +00:00
def serverLogout(self, server):
self._pool.runOperation("UPDATE frn_users SET server=NULL, port=NULL, _nt=NULL WHERE server=? AND port=?",
(server.SN, server.PT))
self._pool.runOperation("DELETE FROM frn_servers WHERE _sn=? AND _pt=?",
(server.SN, server.PT))
2010-08-18 15:46:58 +00:00
def clientLogin(self, server, user):
def userfound(data):
log.msg("Client login: %s" % repr(data))
if data:
u = dict(zip(
('ID', 'EA', 'PW', 'ON', 'BC', 'NN', 'CT', 'NT', 'DS', 'IP', 'registration', 'lastlogin', 'server', 'port'),
data[0]))
if u['server']:
log.msg("Duplicate client %s" % repr(user))
return "DUPL"
self._pool.runQuery("""
UPDATE frn_users SET
_bc=?, _nn=?, _ct=?, _nt=?, _ds=?, _ip=?, server=?, port=?,
lastlogin=current_timestamp
WHERE _id=?
""", (user.BC, user.NN, user.CT, user.NT, user.DS, user.IP, server.SN, server.PT, u['ID']))
log.msg("Authenticated client %s" % repr(user))
return str(u['ID'])
else:
log.msg("Wrong client %s" % repr(user))
return "WRONG"
return self._pool.runQuery("SELECT * FROM frn_users WHERE _ea=? AND _on=? AND _pw=?",
(user.EA, user.ON, user.PW)).addCallbacks(userfound, lambda x: "WRONG")
2010-08-18 15:46:58 +00:00
def clientLogout(self, server, user):
log.msg("Logging out client %s" % repr(user))
return self._pool.runOperation("UPDATE frn_users SET server=NULL, port=NULL, _nt=NULL WHERE _id=?",
(user.ID,)).addBoth(lambda x: "OK")
2010-08-18 15:46:58 +00:00
def getClientList(self):
def buildlist(tr):
tr.execute("SELECT _sn, _pt FROM frn_servers")
servers = tr.fetchall()
r = {}
for sn, sp in servers:
r[(sn,sp)] = {}
tr.execute("SELECT DISTINCT _nt FROM frn_users WHERE server=? AND port=?", (sn,sp))
networks = tr.fetchall()
for (n,) in networks:
r[(sn,sp)][n] = []
tr.execute("SELECT _id, _on, _bc, _ds, _nn, _ct FROM frn_users WHERE server=? AND port=? AND _nt=?",
(sn, sp, n))
clients = tr.fetchall()
for c in clients:
cu = FRNUser(**dict(zip(['EA','ON','BC','DS','NN','CT'],c)))
r[(sn,sp)][n].append(cu)
return r
return self._pool.runInteraction(buildlist)
2010-08-18 15:46:58 +00:00
def registerUser(self, user):
def fetchdata(is_new):
def maildata(data):
u = dict(zip(
('ID', 'EA', 'PW', 'ON', 'BC', 'NN', 'CT', 'NT', 'DS', 'IP', 'registration', 'lastlogin', 'server', 'port'),
data[0]))
log.msg("Mailing password to user %s" % str(u))
with open('mailtemplate.txt','r') as tplfile:
tpl = tplfile.read()
mailbody = string.Template(tpl).safe_substitute(u)
sendmail('127.0.0.1',
'admin@gnuradionetwork.org',
[u['EA']],
mailbody, port=2525)
return "OK"
return self._pool.runQuery(
"SELECT * FROM frn_users WHERE _ea=?", (user.EA,)
).addCallback(maildata).addErrback(lambda x: "ERROR")
return self._pool.runOperation("""
INSERT INTO frn_users (_id, _ea, _pw, _on, _bc, _ds, _nn, _ct)
VALUES (?,?,?,?,?,?,?,?)
""", (uuid.uuid4().get_hex()[:20], user.EA, rndpasswd(),
user.ON, user.BC, user.DS, user.NN, user.CT)
).addBoth(fetchdata)
2010-08-18 15:46:58 +00:00
# vim: set et ai sw=4 ts=4 sts=4: