diff --git a/server/WebHandler.py b/server/WebHandler.py deleted file mode 100644 index e08dd09..0000000 --- a/server/WebHandler.py +++ /dev/null @@ -1,76 +0,0 @@ -import BaseHTTPServer -#import Cheetah.Template -import SocketServer -#import cgi -import threading - -class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler): - server_version = "yadynHTTP/1.0" - - @classmethod - def setParams(cls, entries): - cls.entries = entries - -# def do_POST(self): -# self.log_message("Request: %s", self.path) -# sid = self.getSidFromCookie() -# self.log_message("Cookie: %s" % self.headers.get('Cookie')) -# -# d = HscWebApp(sid) -# -# l = int(self.headers.get('Content-Length', '0')) -# q = self.rfile.read(l) -# e = cgi.parse_qs(q) -# self.log_message("QUERY: %s" % str(e)) -# d.setParams(Params(e)) -# -# d.processAction() -# -# self.send_response(303, "See Other") -# self.setSidInCookie(d.sid) -# self.send_header("Location", "/") -# self.end_headers() -# -# d.finish() - - def do_GET(self): - self.log_message("Request: %s", self.path) - cmd = self.path.split('/')[1] - dynid = self.path.split('/')[2] - - d = '' - if cmd == 'status': - if dynid == 'all': - for entry in self.entries.values(): - d += str(entry) + '\n' - elif self.entries.has_key(dynid): - d = str(self.entries[dynid]) - else: - d = "unknown dynid" - else: - d = "unknown cmd" - - self.send_response(200, "OK") - - self.send_header("Content-Type", "text/plain") - self.end_headers() - self.wfile.write(str(d)) - - -class WebServer(SocketServer.ThreadingTCPServer): - def __init__(self, server_address, RequestHandlerClass): - self.allow_reuse_address = True - SocketServer.ThreadingTCPServer.__init__(self, server_address, RequestHandlerClass) - - -class WebHandler(threading.Thread): - def __init__(self, webAddr, entries): - threading.Thread.__init__(self) - self.webAddr = webAddr - MyHandler.setParams(entries) - self.setDaemon(True) - - def run(self): - WebServer(self.webAddr, MyHandler).serve_forever() - - diff --git a/server/WebReceiver.py b/server/WebReceiver.py new file mode 100644 index 0000000..f6e2cb6 --- /dev/null +++ b/server/WebReceiver.py @@ -0,0 +1,222 @@ +from params import Params +from session import Session, SessionContainer +import BaseHTTPServer +import Cheetah.Template +import Cookie +import SocketServer +import StringIO +import cgi +import sys +import uuid +import os +import threading +from logger import Logger + + +TEMPLATE_DIR='./templates' + + +class YaDynWebApp(object): + @classmethod + def setSessionContainer(cls, sessionContainer): + cls.sessionContainer = sessionContainer + + def __init__(self, sid): + self.buf = StringIO.StringIO() + self.params = None + self.session = YaDynWebApp.sessionContainer.get(sid) + self.error_msg = None + self.msg = None + self.sid = sid + + def finish(self): + pass + + def log(self, msg): + Logger.log(msg) + + def setParams(self, p): + self.params = p + + def showPage(self, forcePage=''): + if self.session: + if forcePage != '': + page = forcePage + else: + page = self.session.redirectTarget + else: + page = 'login' + + if page == 'logout': + YaDynWebApp.sessionContainer.delete(self.sid) + self.session = None + page = 'login' + + templateFile = page + '.tmpl' + + try: + if self.session: + self.log("showPage, session: %s" % str(self.session)) + self.log("showPage, params: %s" % str(self.session.params)) + self.session.setShownPage(page) + + try: + loaderObjectClass = eval("loader_" + page) + loaderObject = loaderObjectClass(self.session) + loaderObject.mergeAdditionalData() + except NameError, e: + self.log("loader class for %s not found: %s" % (page, str(e))) + except HscException, e: + s = "HSC Failure loading data: %s" % str(e) + self.log(s) + raise Exception(s) + + tmpl = Cheetah.Template.Template(file=TEMPLATE_DIR + '/' + templateFile, + searchList=[self]) + #self.log("OUTPUT: %s" % str(tmpl)) + self.buf.write(str(tmpl)) + + if self.session: + self.session.clearMsgs() + except Exception, e: + YaDynWebApp.sessionContainer.delete(self.sid) + self.buf.write("Problems to show this page: %s %s" % (e.__class__.__name__, str(e))) + finally: + pass + + + + def processAction(self): + if self.params.action == "Login": + authTuple = getAuthTuple(self.params.username, self.params.password) + if authTuple: + self.params = Params({}) + self.sid = str(uuid.uuid1()) + session = Session(self.sid, self.params) + + session.setAuthTuple(authTuple) + session.setGoodMsg("Welcome") + session.setRedirectTarget("menu") + YaDynWebApp.sessionContainer.add(session) + else: + self.sid = 0 + else: + if self.session == None: + self.sid = 0 + else: + shownPage = self.session.getShownPage() + self.session.setParams(self.params) + self.log("shownPage: %s" % shownPage) + try: + dataObjectClass = eval(shownPage) + dataObject = dataObjectClass(self.session) + dataObject.process() + self.session.setGoodMsg("Action on %s performed successfully" % shownPage) + self.session.setRedirectTarget(dataObject.getNextPage()) + except NameError, e: + self.log("processAction, NameError PARAMS: %s" % str(self.session.params)) + s = "Internal program error: %s" % str(e) + self.session.setBadMsg(s) + self.log(s) + self.session.setRedirectTarget("menu") + except HscException, e: + self.log("processAction, HscException PARAMS: %s" % str(self.session.params)) + s = "HSC Failure: %s" % str(e) + self.session.setBadMsg(s) + self.log(s) + self.session.setRedirectTarget(shownPage) + + + def __str__(self): + return self.buf.getvalue() + + +class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler): + server_version = "YaDynWebAppHTTP/1.0" + + @classmethod + def setParams(cls, entries): + cls.entries = entries + + def log_message(self, format, *args): + Logger.log(format%args) + + def getSidFromCookie(self): + try: + cookie = Cookie.SimpleCookie(self.headers.get('Cookie')) + sid = cookie['sid'].value + except KeyError: + sid = None + return sid + + def setSidInCookie(self, sid): + cookie = Cookie.SimpleCookie() + cookie['sid'] = sid + cookie['sid']['Max-Age'] = 10*60 + self.wfile.write(str(cookie) + '\r\n') + + + + def do_POST(self): + self.log_message("Request: %s", self.path) + sid = self.getSidFromCookie() + self.log_message("Cookie: %s" % self.headers.get('Cookie')) + + d = YaDynWebApp(sid) + + l = int(self.headers.get('Content-Length', '0')) + q = self.rfile.read(l) + e = cgi.parse_qs(q) + self.log_message("QUERY: %s" % str(e)) + d.setParams(Params(e)) + + d.processAction() + + self.send_response(303, "See Other") + self.setSidInCookie(d.sid) + self.send_header("Location", "/") + self.end_headers() + + d.finish() + + def do_GET(self): + self.log_message("Request: %s", self.path) + sid = self.getSidFromCookie() + self.log_message("SID: %s" % sid) + + d = YaDynWebApp(sid) + + d.showPage(self.path.split('/')[1]) + + self.send_response(200, "OK") + + self.send_header("Content-Type", "text/html") + self.end_headers() + self.wfile.write(str(d)) + + d.finish() + + + +class MyServer(SocketServer.ThreadingTCPServer): + def __init__(self, server_address, RequestHandlerClass): + self.allow_reuse_address = True + SocketServer.ThreadingTCPServer.__init__(self, server_address, RequestHandlerClass) + + + +class WebReceiver(threading.Thread): + def __init__(self, webAddr, entries): + threading.Thread.__init__(self) + self.webAddr = webAddr + MyHandler.setParams(entries) + self.setDaemon(True) + + def run(self): + self.sessionContainer = SessionContainer(60, 600) + self.sessionContainer.setDaemon(True) + self.sessionContainer.start() + YaDynWebApp.setSessionContainer(self.sessionContainer) + + MyServer(self.webAddr, MyHandler).serve_forever() + diff --git a/server/logger.py b/server/logger.py new file mode 100644 index 0000000..e035109 --- /dev/null +++ b/server/logger.py @@ -0,0 +1,26 @@ +import syslog + + +class Logger(object): + def log(data): + syslog.syslog(syslog.LOG_INFO, data) + if Logger.debugFlag: + print data + + def debug(data): + syslog.syslog(syslog.LOG_DEBUG, data) + if Logger.debugFlag: + print data + + def openlog(): + syslog.openlog('hsc', syslog.LOG_PID, syslog.LOG_LOCAL0) + + def debugEnable(): + Logger.debugFlag = True + + log = staticmethod(log) + debug = staticmethod(debug) + openlog = staticmethod(openlog) + debugEnable = staticmethod(debugEnable) + debugFlag = False + diff --git a/server/params.py b/server/params.py new file mode 100644 index 0000000..dc25bc0 --- /dev/null +++ b/server/params.py @@ -0,0 +1,30 @@ +from logger import Logger + +class Params(object): + def __init__(self, e): + Logger.log("Params: %s" % str(e)) + for k in e.keys(): + self.__dict__[k] = e[k][0] + + def __getattr__(self, a): + return '' + + def get(self, k): + if self.__dict__.has_key(k): + return self.__dict__[k] + else: + return '' + + def check_existance(self, l): + for i in l: + if not self.__dict__.has_key(i): + raise KeyError, i + + def items(self): + for k in self.__dict__.keys(): + yield (k, self.__dict__[k]) + return + + def __str__(self): + return str(self.__dict__) + diff --git a/server/session.py b/server/session.py new file mode 100644 index 0000000..319f811 --- /dev/null +++ b/server/session.py @@ -0,0 +1,110 @@ +import time +import threading +from logger import Logger + + + +class SessionContainer(threading.Thread): + def __init__(self, checkPeriod, expiryTime): + threading.Thread.__init__(self) + self.checkPeriod = checkPeriod + self.expiryTime = expiryTime + self.sessions = {} + self.sessionsLock = threading.Lock() + + def get(self, sid): + if not sid: + return None + try: + self.sessionsLock.acquire() + session = self.sessions[sid] + session.updateTimestamp() + return session + except KeyError: + return None + finally: + self.sessionsLock.release() + + def delete(self, sid): + if sid: + try: + self.sessionsLock.acquire() + del self.sessions[sid] + except KeyError: + pass + finally: + self.sessionsLock.release() + + def add(self, session): + try: + self.sessionsLock.acquire() + self.sessions[session.getId()] = session + finally: + self.sessionsLock.release() + + def run(self): + while True: + try: + self.sessionsLock.acquire() + + currentTime = int(time.time()) + for session in self.sessions.values(): + Logger.log("SessionContainer: checking session %s, expires in %d s" % (session.getId(), + (session.getTimestamp() + self.expiryTime) - currentTime)) + if (session.getTimestamp() + self.expiryTime) < currentTime: + Logger.log("SessionContainer: about to drop session %s" % session.getId()) + del self.sessions[session.getId()] + finally: + self.sessionsLock.release() + + time.sleep(self.checkPeriod) + + +class Session(object): + def __init__(self, id, params): + self.timestamp = int(time.time()) + self.id = id + self.params = params + self.badmsg = '' + self.goodmsg = '' + self.role = '' + + def updateTimestamp(self): + self.timestamp = int(time.time()) + + def getTimestamp(self): + return self.timestamp + + def getId(self): + return self.id + + def setParams(self, params): + self.params = params + + def getParams(self): + return self.params + + def setGoodMsg(self, msg): + self.goodmsg = msg + + def setBadMsg(self, msg): + self.badmsg = msg + + def setRedirectTarget(self, target): + self.redirectTarget = target + + def setShownPage(self, page): + self.page = page + + def getShownPage(self): + return self.page + + def setAuthTuple(self, authTuple): + self.authTuple = authTuple + self.username = authTuple['username'] + self.password = authTuple['password'] + self.role = authTuple['role'] + + def clearMsgs(self): + self.badmsg = '' + self.goodmsg = '' diff --git a/server/templates/admin_menu.inc b/server/templates/admin_menu.inc new file mode 100644 index 0000000..36e4b0f --- /dev/null +++ b/server/templates/admin_menu.inc @@ -0,0 +1,3 @@ + diff --git a/server/templates/any_menu.inc b/server/templates/any_menu.inc new file mode 100644 index 0000000..b521cdb --- /dev/null +++ b/server/templates/any_menu.inc @@ -0,0 +1,4 @@ + diff --git a/server/templates/footer.inc b/server/templates/footer.inc new file mode 100644 index 0000000..67dd8a0 --- /dev/null +++ b/server/templates/footer.inc @@ -0,0 +1,4 @@ +

+ + + \ No newline at end of file diff --git a/server/templates/header.inc b/server/templates/header.inc new file mode 100644 index 0000000..1103b79 --- /dev/null +++ b/server/templates/header.inc @@ -0,0 +1,42 @@ + + + YaDyn + + + + +
+ #if $session and $session.goodmsg +

+ $session.goodmsg +

+ #end if +
+ +
+ #if $session and $session.badmsg +

+ $session.badmsg +

+ #end if +
+ + + +
+

diff --git a/server/templates/login.tmpl b/server/templates/login.tmpl new file mode 100644 index 0000000..c1b79ff --- /dev/null +++ b/server/templates/login.tmpl @@ -0,0 +1,17 @@ +#include "templates/header.inc" + + +

+ + + + + + +
Username:
Password:
+
+ +
+ + +#include "templates/footer.inc" diff --git a/server/templates/logout.tmpl b/server/templates/logout.tmpl new file mode 100644 index 0000000..b023018 --- /dev/null +++ b/server/templates/logout.tmpl @@ -0,0 +1 @@ +bye diff --git a/server/templates/user_menu.inc b/server/templates/user_menu.inc new file mode 100644 index 0000000..8ce2ee6 --- /dev/null +++ b/server/templates/user_menu.inc @@ -0,0 +1,3 @@ + diff --git a/server/yadyn b/server/yadyn index 6da1354..2a7094a 100755 --- a/server/yadyn +++ b/server/yadyn @@ -8,7 +8,7 @@ import DynHandler # import DnsHandler import Expirer import DynReceiver -import WebHandler +import WebReceiver import Entry import Event @@ -44,8 +44,8 @@ try: expirer = Expirer.Expirer(entries, EVENT_LIFE_TIME, NULL_ADDRESS) expirer.start() - webHandler = WebHandler.WebHandler(("", 8080), entries) - webHandler.start() + webReceiver = WebReceiver.WebReceiver(("", 8080), entries) + webReceiver.start() while True: entries.sync()