def login(self, request): """Login via XMLRPC, getting an authentication token. Replies with a result dict for success or failure, or None to indicate connection failure. """ user = request.args.get("u") if user is None: raise AJAXException, "No username specified." password = request.args.get("p") if password is None: raise AJAXException, "No password specified." self.__total_hit() response = None try: result = { "success": True, "output": None } result["output"] = self.do_xmlrpc(self.conn.atheme.login, (user[0], password[0])) if result["output"] is not None: response = json.dumps(result) else: response = json.dumps(None) except xmlrpclib.Fault, e: result = { "success": False, "output": e.faultString } response = json.dumps(result)
def logout(self, request): """Log out, invalidating the request's authentication token. Replies with a result dict for success or failure, which normally means these details are already invalid and thus "logged out", and None for connection failure. """ user = request.args.get("u") if user is None: raise AJAXException, "No username specified." token = request.args.get("t") if token is None: raise AJAXException, "No token specified." self.__total_hit() response = None try: result = { "success": True, "output": None } result["output"] = self.do_xmlrpc(self.conn.atheme.logout, (user[0], token[0])) if result["output"] is not None: response = json.dumps(result) else: response = json.dumps(None) except xmlrpclib.Fault, e: result = { "success": False, "output": e.faultString } response = json.dumps(result)
def logout(self, request): """Log out, invalidating the request's authentication token. Replies with a result dict for success or failure, which normally means these details are already invalid and thus "logged out", and None for connection failure. """ user = request.args.get("u") if user is None: raise AJAXException, "No username specified." token = request.args.get("t") if token is None: raise AJAXException, "No token specified." self.__total_hit() response = None try: result = { "success": True, "output": None } result["output"] = self.do_xmlrpc(self.conn.atheme.logout, (token[0], user[0])) if result["output"] is not None: response = json.dumps(result) else: response = json.dumps(None) except xmlrpclib.Fault, e: result = { "success": False, "output": e.faultString } response = json.dumps(result)
def getLocale(self, request): """ Request a localization and respond with json object of appropriate locale """ requested = request.args.get("locale") #?locale=fr setLocales = request.getCookie("locale") #preferred locale (todo implement)? locales = [] if requested: locales = requested elif setLocales: locales = json.loads(setLocales) else: lang_header = request.headers.get("Accept-Language", "en") # for example en-US,en;q=0.8,es;q=0.6 locales = [locale.split(';')[0] for locale in lang_header.split(',')] basePath = self.localePath + (request.args.get("path", [""])[0]) if not basePath.endswith("/"): basePath += "/" if not os.path.exists(basePath): raise http_error.NoResource().render(request) lang = getJSON(basePath + "base.json") # reverse so specificity overrides for locale in reversed(locales): path = basePath + locale + ".json" if os.path.exists(path): lang.update(getJSON(path)) cache(request) # apply_gzip(request) request.write(json.dumps(lang)) request.finish() return True
def flush(self, scheduled=False): if scheduled: self.schedule = None if not self.buffer or not self.subscriptions: return t = time.time() if t < self.throttle: if not self.schedule: self.schedule = reactor.callLater(self.throttle - t, self.flush, True) return else: # process the rest of the packet if not scheduled: if not self.schedule: self.schedule = reactor.callLater(0, self.flush, True) return self.throttle = t + config.UPDATE_FREQ encdata = json.dumps(self.buffer) self.buffer = [] self.buflen = 0 newsubs = [] for x in self.subscriptions: if x.write(encdata): newsubs.append(x) self.subscriptions = newsubs if self.closed and not self.subscriptions: cleanupSession(self.id)
def push(self, request): command = request.args.get(b"c") if command is None: raise AJAXException("No command specified.") self.__total_hit() seq_no = request.args.get(b"n") try: if seq_no is not None: seq_no = int(seq_no[0]) if seq_no < 0 or seq_no > MAX_SEQNO: raise ValueError except ValueError: raise AJAXEngine("Bad sequence number %r" % seq_no) session = self.getSession(request) try: session.push(ircclient.irc_decode(command[0]), seq_no) except AttributeError: # occurs when we haven't noticed an error session.disconnect() raise AJAXException( "Connection closed by server; try reconnecting by reloading the page." ) except Exception as e: # catch all session.disconnect() traceback.print_exc(file=sys.stderr) raise AJAXException("Unknown error.") return json.dumps((True, True))
def js_config(): options = { 'atheme': atheme, 'frontend': frontend, 'ui': ui, } return json.dumps(options)
def get_options(): options = dict( networkName=config.NETWORK_NAME, networkServices=[config.AUTH_SERVICE], loginRegex=config.AUTH_OK_REGEX, appTitle=config.APP_TITLE, baseURL=config.BASE_URL, staticBaseURL=config.STATIC_BASE_URL, dynamicBaseURL=config.DYNAMIC_BASE_URL, validateNickname=False, customMenuItems=[] ) if hasattr(config, "NICKNAME_VALIDATE") and config.NICKNAME_VALIDATE: options["nickValidation"] = dict( minLen=config.NICKNAME_MINIMUM_LENGTH, maxLen=config.NICKNAME_MAXIMUM_LENGTH, validFirstChar=config.NICKNAME_VALID_FIRST_CHAR, validSubChars=config.NICKNAME_VALID_SUBSEQUENT_CHARS ) if hasattr(config, "HELP_URL") and config.HELP_URL: options["helpURL"] = config.HELP_URL if hasattr(config, "LOGO_URL"): options["logoURL"] = config.LOGO_URL if hasattr(config, "CUSTOM_MENU_ITEMS"): options["customMenuItems"] = config.CUSTOM_MENU_ITEMS if hasattr(config, "ACCOUNT_WHOIS_COMMAND") and config.ACCOUNT_WHOIS_COMMAND: options["accountWhoisCommand"] = config.ACCOUNT_WHOIS_COMMAND return json.dumps(options)
def get_options(): options = dict(networkName=config.NETWORK_NAME, appTitle=config.APP_TITLE, baseURL=config.BASE_URL, staticBaseURL=config.STATIC_BASE_URL, dynamicBaseURL=config.DYNAMIC_BASE_URL) return json.dumps(options)
def get_options(): options = dict( networkName=config.NETWORK_NAME, networkServices=[config.AUTH_SERVICE] if config.AUTH_SERVICE else [], loginRegex=config.AUTH_OK_REGEX, appTitle=config.APP_TITLE, baseURL=config.BASE_URL, staticBaseURL=config.STATIC_BASE_URL, dynamicBaseURL=config.DYNAMIC_BASE_URL, validateNickname=False ) if hasattr(config, "SUGGESTED_CHANNELS"): options['suggestedChannels'] = config.SUGGESTED_CHANNELS else: options['suggestedChannels'] = dict() if hasattr(config, "NICKNAME_VALIDATE") and config.NICKNAME_VALIDATE: options["nickValidation"] = dict( minLen=config.NICKNAME_MINIMUM_LENGTH, maxLen=config.NICKNAME_MAXIMUM_LENGTH, validFirstChar=config.NICKNAME_VALID_FIRST_CHAR, validSubChars=config.NICKNAME_VALID_SUBSEQUENT_CHARS ) return json.dumps(options)
def get_options(): options = dict( networkName=config.NETWORK_NAME, appTitle=config.APP_TITLE, baseURL=config.BASE_URL, staticBaseURL=config.STATIC_BASE_URL, dynamicBaseURL=config.DYNAMIC_BASE_URL) return json.dumps(options)
def render_POST(self, request): path = request.path[len(self.prefix):] if path[0] == "/": handler = self.COMMANDS.get(path[1:]) if handler is not None: try: return handler(self, request) except AJAXException, e: return json.dumps((False, e[0]))
def js_config(): f = frontend.copy() del f["extra_html"] # already injected by pagegen. options = { 'atheme': atheme, 'frontend': f, 'ui': ui, } return json.dumps(options)
def command(self, request): """Run an arbitrary command, with an optional user and authentication token. Replies with a result dict for success or failure, and None to indicate connection failure. """ user = request.args.get("u") if user is None: user = ["*"] token = request.args.get("t") if token is None: token = ["*"] service = request.args.get("s") if service is None: raise AJAXException("No command specified.") command = request.args.get("c") if command is None: raise AJAXException("No command specified.") params = request.args.get("p") if params is None: params = [] self.__total_hit() response = None try: result = {"success": True, "output": None} result["output"] = self.do_xmlrpc(self.conn.atheme.command, (token[0], user[ 0], "0.0.0.0", service[0], command[0]) + tuple(params)) if result["output"] is not None: response = json.dumps(result) else: response = json.dumps(None) except xmlrpclib.Fault as e: result = {"success": False, "output": e.faultString} response = json.dumps(result) request.write(response) request.finish() return True
def history(self, request): session = self.getSession(request) channel = request.args.get("channel") records = database.client.readMsg(channel[0]) messages = [] for r in records: print r msg = ["c"] + ["HISTORY"] + [r[1]] msg.append([r[2], r[4], r[3]]) messages.append(msg) return json.dumps(messages)
def render_POST(self, request): path = request.path[len(self.prefix):].decode('utf-8') if path[0] == "/": handler = self.COMMANDS.get(path[1:]) if handler is not None: try: return bytes(handler(self, request), 'utf-8') except AJAXException as e: return bytes(json.dumps((False, str(e))), 'utf-8') return b"404" # TODO: tidy up
def command(self, request): """Run an arbitrary command, with an optional user and authentication token. Replies with a result dict for success or failure, and None to indicate connection failure. """ user = request.args.get("u") if user is None: user = ["*"] token = request.args.get("t") if token is None: token = ["*"] service = request.args.get("s") if service is None: raise AJAXException, "No command specified." command = request.args.get("c") if command is None: raise AJAXException, "No command specified." params = request.args.get("p") if params is None: params = [] self.__total_hit() response = None try: result = {"success": True, "output": None} result["output"] = self.do_xmlrpc( self.conn.atheme.command, (token[0], user[0], "0.0.0.0", service[0], command[0]) + tuple(params)) if result["output"] is not None: response = json.dumps(result) else: response = json.dumps(None) except xmlrpclib.Fault, e: result = {"success": False, "output": e.faultString} response = json.dumps(result)
def get_options(): options = dict(networkName=config.NETWORK_NAME, networkServices=[config.AUTH_SERVICE], loginRegex=config.AUTH_OK_REGEX, appTitle=config.APP_TITLE, baseURL=config.BASE_URL, staticBaseURL=config.STATIC_BASE_URL, dynamicBaseURL=config.DYNAMIC_BASE_URL, validateNickname=False) if hasattr(config, "NICKNAME_VALIDATE") and config.NICKNAME_VALIDATE: options["nickValidation"] = dict( minLen=config.NICKNAME_MINIMUM_LENGTH, maxLen=config.NICKNAME_MAXIMUM_LENGTH, validFirstChar=config.NICKNAME_VALID_FIRST_CHAR, validSubChars=config.NICKNAME_VALID_SUBSEQUENT_CHARS) return json.dumps(options)
def subscribe(self, channel, seqNo=None): if len(self.subscriptions) >= config.MAXSUBSCRIPTIONS: self.subscriptions.pop(0).close() if seqNo is not None and seqNo < self.subSeqNo: if self.old_buffer is None or seqNo != self.old_buffer[0]: channel.write( json.dumps([ False, "Unable to reconnect -- sequence number too old." ]), seqNo + 1) return if not channel.write(self.old_buffer[1], self.old_buffer[0] + 1): return self.subscriptions.append(channel) self.flush(seqNo)
def getLocale(self, request): """ Request a localization and respond with json object of appropriate locale """ requested = request.args.get("locale") #?locale=fr setLocales = request.getCookie( "locale") #preferred locale (todo implement)? locales = [] if requested: locales = requested elif setLocales: locales = json.loads(setLocales) else: lang_header = request.headers.get( "Accept-Language", "en") # for example en-US,en;q=0.8,es;q=0.6 locales = [ locale.split(';')[0] for locale in lang_header.split(',') ] basePath = self.localePath + (request.args.get("path", [""])[0]) if not basePath.endswith("/"): basePath += "/" if not os.path.exists(basePath): raise http_error.NoResource().render(request) lang = getJSON(basePath + "base.json") # reverse so specificity overrides for locale in reversed(locales): path = basePath + locale + ".json" if os.path.exists(path): lang.update(getJSON(path)) cache(request) # apply_gzip(request) request.write(json.dumps(lang)) request.finish() return True
def get_options(): options = dict( networkName=config.NETWORK_NAME, networkServices=[config.AUTH_SERVICE], loginRegex=config.AUTH_OK_REGEX, appTitle=config.APP_TITLE, baseURL=config.BASE_URL, staticBaseURL=config.STATIC_BASE_URL, dynamicBaseURL=config.DYNAMIC_BASE_URL, validateNickname=False, ) if hasattr(config, "NICKNAME_VALIDATE") and config.NICKNAME_VALIDATE: options["nickValidation"] = dict( minLen=config.NICKNAME_MINIMUM_LENGTH, maxLen=config.NICKNAME_MAXIMUM_LENGTH, validFirstChar=config.NICKNAME_VALID_FIRST_CHAR, validSubChars=config.NICKNAME_VALID_SUBSEQUENT_CHARS, ) if hasattr(config, "HELP_URL") and config.HELP_URL: options["helpURL"] = config.HELP_URL return json.dumps(options)
def render_GET(self, request): a = database.client.read() return json.dumps(a)
pass class AJAXException(Exception): pass class IDGenerationException(Exception): pass class LineTooLongException(Exception): pass EMPTY_JSON_LIST = json.dumps([]) def cleanupSession(id): try: del Sessions[id] except KeyError: pass class IRCSession: def __init__(self, id): self.id = id self.subscriptions = [] self.buffer = [] self.old_buffer = None
def newConnection(self, request): ticket = login_optional(request) ip = request.getClientIP() nick = request.args.get("nick") if not nick: raise AJAXException, "Nickname not supplied." nick = ircclient.irc_decode(nick[0]) password = request.args.get("password") if password is not None: password = ircclient.irc_decode(password[0]) for i in range(10): id = get_session_id() if not Sessions.get(id): break else: raise IDGenerationException() session = IRCSession(id) qticket = getSessionData(request).get("qticket") if qticket is None: perform = None else: service_mask = config.AUTH_SERVICE msg_mask = service_mask.split("!")[0] + "@" + service_mask.split( "@", 1)[1] perform = ["PRIVMSG %s :TICKETAUTH %s" % (msg_mask, qticket)] ident, realname = config.IDENT, config.REALNAME if ident is config_options.IDENT_HEX or ident is None: # latter is legacy ident = socket.inet_aton(ip).encode("hex") elif ident is config_options.IDENT_NICKNAME: ident = nick self.__connect_hit() def proceed(hostname): kwargs = dict(nick=nick, ident=ident, ip=ip, realname=realname, perform=perform, hostname=hostname) if password is not None: kwargs["password"] = password client = ircclient.createIRC(session, **kwargs) session.client = client if not hasattr(config, "WEBIRC_MODE") or config.WEBIRC_MODE == "hmac": proceed(None) elif config.WEBIRC_MODE != "hmac": notice = lambda x: session.event(connect_notice(x)) notice("Looking up your hostname...") def callback(hostname): notice("Found your hostname.") proceed(hostname) def errback(failure): notice("Couldn't look up your hostname!") proceed(ip) qdns.lookupAndVerifyPTR(ip, timeout=[config.DNS_TIMEOUT]).addCallbacks( callback, errback) Sessions[id] = session return json.dumps((True, id, TRANSPORTS))
def render_GET(self, request): if request.args.get("logout"): self.deleteCookie(request, "user") a = authgate(request, config.AUTHGATEDOMAIN) try: ticket = a.login_required(accepting=lambda x: True) except a.redirect_exception as e: pass else: # only used for informational purposes, the backend stores this seperately # so if the user changes it just their front end will be messed up! request.addCookie("user", ticket.username, path="/") qt = ticket.get("qticket") if qt is not None: getSessionData(request)["qticket"] = decodeQTicket(qt) self.__hit() if request.getCookie("jslogin"): self.deleteCookie(request, "jslogin") return """<html><head><script>window.opener.__qwebircAuthCallback(%s);</script></head></html>""" % json.dumps( ticket.username) location = request.getCookie("redirect") if location is None: location = "/" else: self.deleteCookie(request, "redirect") _, _, path, params, query, _ = urlparse.urlparse( urllib.unquote(location)) location = urlparse.urlunparse( ("", "", path, params, query, "")) request.redirect(location) request.finish() return server.NOT_DONE_YET
class AJAXException(Exception): pass class IDGenerationException(Exception): pass class PassthruException(Exception): pass NOT_DONE_YET = None EMPTY_JSON_LIST = json.dumps([]) def jsondump(fn): def decorator(*args, **kwargs): try: x = fn(*args, **kwargs) if x is None: return server.NOT_DONE_YET x = (True, x) except AJAXException, e: x = (False, e[0]) except PassthruException, e: return str(e) return json.dumps(x)
return md5.md5(os.urandom(16)).hexdigest() class BufferOverflowException(Exception): pass class AJAXException(Exception): pass class IDGenerationException(Exception): pass class PassthruException(Exception): pass NOT_DONE_YET = None EMPTY_JSON_LIST = json.dumps([]) def jsondump(fn): def decorator(*args, **kwargs): try: x = fn(*args, **kwargs) if x is None: return server.NOT_DONE_YET x = (True, x) except AJAXException, e: x = (False, e[0]) except PassthruException, e: return str(e) return json.dumps(x) return decorator
def list(self, request): """Request a channel list, with a start point, length, masks, and ts. Optionally permits a timestamp to be provided. Replies with a dict containing channel info for success, a result dict for failure, and None to indicate connection failure. """ if not config.athemeengine["chan_list_enabled"]: response = json.dumps(None) request.write(response) request.finish() return True start = request.args.get("s") if start is None: raise AJAXException, "No start point specified." start = int(start[0]) if start < 0: start = 0 length = request.args.get("l") if length is None: raise AJAXException, "No length specified." length = int(length[0]) chanmask = request.args.get("cm") if chanmask is not None: chanmask = chanmask[0].lower() else: chanmask = "*" topicmask = request.args.get("tm") if topicmask is not None: topicmask = topicmask[0].lower() else: topicmask = "*" listtime = request.args.get("t") if listtime is not None: listtime = int(listtime[0]) else: listtime = 0 self.__total_hit() result = { "success": True, "list": None, "total": 0, "ts": 0 } if listtime != 0 and listtime in self.chanlists: chanlist = self.chanlists[listtime] else: most_recent = None if (len(self.chanlists) > 0): most_recent = max(self.chanlists.keys()) now = int(time.time()) if (most_recent is not None and now - most_recent <= config.athemeengine["chan_list_max_age"]): chanlist = self.chanlists[most_recent] listtime = most_recent else: if (len(self.chanlists) >= config.athemeengine["chan_list_count"]): del self.chanlists[min(self.chanlists.keys())] chanlist = self.do_list() if chanlist is not None: listtime = int(time.time()) self.chanlists[listtime] = chanlist else: if most_recent in self.chanlists: chanlist = self.chanlists[most_recent] listtime = most_recent else: response = json.dumps(None) request.write(response) request.finish() return True if chanmask == "*" and topicmask == "*": if start > len(chanlist): start = len(chanlist) if start+length > len(chanlist): length = len(chanlist) - start if length > 0: result["list"] = chanlist[start:start+length] else: result["list"] = [] result["total"] = len(chanlist) else: chanmask = "*" + chanmask + "*" topicmask = "*" + topicmask + "*" skipped = 0 total = 0 filtered_chanlist = [] for channel in chanlist: if not fnmatch.fnmatchcase(channel["name"].lower(), chanmask): continue if not fnmatch.fnmatchcase(channel["topic"].lower(), topicmask): continue total += 1 if (skipped < start): skipped += 1 continue if (total - skipped < length): filtered_chanlist.append(channel) result["list"] = filtered_chanlist result["total"] = total result["ts"] = listtime response = json.dumps(result) request.write(response) request.finish() return True
def js_config(): options = { 'atheme': atheme } return json.dumps(options)
ticket = a.login_required(accepting=lambda x: True) except a.redirect_exception, e: pass else: # only used for informational purposes, the backend stores this seperately # so if the user changes it just their front end will be messed up! request.addCookie("user", ticket.username, path="/") qt = ticket.get("qticket") if not qt is None: getSessionData(request)["qticket"] = decodeQTicket(qt) self.__hit() if request.getCookie("jslogin"): self.deleteCookie(request, "jslogin") return """<html><head><script>window.opener.__qwebircAuthCallback(%s);</script></head></html>""" % json.dumps( ticket.username) location = request.getCookie("redirect") if location is None: location = "/" else: self.deleteCookie(request, "redirect") _, _, path, params, query, _ = urlparse.urlparse( urllib.unquote(location)) location = urlparse.urlunparse( ("", "", path, params, query, "")) request.redirect(location) request.finish() return server.NOT_DONE_YET