Initial messenger bot commit

parent a720da39
from nevow import rend, inevow
from corepost import Response, NotFoundException, AlreadyExistsException
from corepost.web import RESTResource, route, Http
from corepost.convert import convertForSerialization, generateXml, convertToJson
from corepost.enums import MediaType, HttpHeader
from rest import RestCore as BotCore
from rest import ResponseConversion
import hashlib
import hmac
import six
import logging
log = logging.getLogger( 'Webgui' )
BOTResource = RESTResource
class BaseBot(BotCore):
@route("/")
def welcome(self, request, *a, **kw):
return 'Domotika BOTs API interface V1.0'
def messengerWrapResponse(f=None, uri=False, res_filter=None, *a, **kw):
if f and not callable(f):
uri=f
f=None
if f is None:
return partial(wrapResponse, uri=uri, *a, **kw)
def okResponse(res, u):
if isinstance(res, ResponseConversion):
entity=res.entity
if res_filter and callable(res_filter):
entity=res_filter(entity)
elif res_filter and hasattr(res_filter, '__iter__'):
for fil in res_filter:
if callable(fil):
entity=fil(entity)
entity={'result': 'succeed', 'data': entity, 'ts': time.time()}
if int(res.code) >= 400:
entity['result']='fail'
if uri:
entity['uri']=uri
elif u:
entity['uri']=u
r = ResponseConversion(res.request, res.code, entity, res.headers, res.ctype).getResponse()
else:
if res_filter and callable(res_filter):
res=res_filter(res)
elif res_filter and hasattr(res_filter, '__iter__'):
for fil in res_filter:
if callable(fil):
res=fil(res)
r={'result': 'succeed', 'data': res, 'ts': time.time()}
if uri:
r['uri']=uri
elif u:
r['uri']=u
return r
def errorResponse(res, u):
if isinstance(res, ResponseConversion):
entity={'result': 'fail', 'data': res.entity, 'ts': time.time()}
if uri:
entity['uri']=uri
elif u:
entity['uri']=u
r = ResponseConversion(res.request, res.code, entity, res.headers, res.ctype).getResponse()
else:
r={'result': 'fail', 'data': res, 'ts': time.time()}
if uri:
r['uri']=uri
elif u:
r['uri']=u
return r
@wraps(f)
def decorate(*a, **kw):
ruri=False
if len(a) > 1 and isinstance(a[1], Request):
ruri=a[1].uri
ret=defer.maybeDeferred(f, *a, **kw)
ret.addCallback(okResponse, ruri)
ret.addErrback(errorResponse, ruri)
return ret
return decorate
class MessengerBot(BotCore):
path = "/messenger"
def _getCfg(self, keyword):
return self.core.configGet('messenger', keyword)
def _validateHubSig(self, request_payload, hub_signature_header):
try:
hash_method, hub_signature = hub_signature_header.split('=')
except:
pass
else:
digest_module = getattr(hashlib, hash_method)
hmac_object = hmac.new(str(self._cfgGet('app_secret')), unicode(request_payload), digest_module)
generated_hash = hmac_object.hexdigest()
if hub_signature == generated_hash:
return True
return False
def _generateAppSecProof(self):
if six.PY2:
hmac_object = hmac.new(str(self._cfgGet('app_key')), unicode(self._cfgGet('page_token')), hashlib.sha256)
else:
hmac_object = hmac.new(bytearray(self._cfgGet('app_key'), 'utf8'), str(self._cfgGet('page_token')).encode('utf8'), hashlib.sha256)
return hmac_object.hexdigest()
@route("/", Http.GET)
def rootGet(self, request, *a, **kw):
if 'hub.mode' in kw.keys() and kw['hub.mode'] == 'subscribe' and 'hub.challenge' in kw.keys():
if 'hub.verify_token' in kw.keys() and kw['hub.verify_token'] == self._cfgGet('verify_token'):
return kw['hub.challenge']
return Response(403, "Failed validation." )
BotApiList=(
BaseBot,
MessengerBot
)
class BotPages(rend.Page):
def child_(self, ctx):
request = inevow.IRequest(ctx)
self.session = inevow.ISession(ctx)
request.setHeader("pragma", "no-cache")
request.postpath=['/']
return BOTResource((BaseBot(self.core, self.session),))
def childFactory(self, ctx, name):
request = inevow.IRequest(ctx)
self.session = inevow.ISession(ctx)
request.setHeader("pragma", "no-cache")
request.postpath=['/',name]+request.postpath
return BOTResource([x(self.core, self.session) for x in BotApiList])
...@@ -47,7 +47,7 @@ from zope.interface import implements ...@@ -47,7 +47,7 @@ from zope.interface import implements
from twisted.cred import portal, checkers, credentials from twisted.cred import portal, checkers, credentials
from nevow import inevow, rend, tags, loaders, flat, stan, guard from nevow import inevow, rend, tags, loaders, flat, stan, guard
from nevow import static as nstatic from nevow import static as nstatic
import proxy, mediaproxy, rest import proxy, mediaproxy, rest, bot
import os, sys import os, sys
from twisted.python import reflect from twisted.python import reflect
from twisted import cred from twisted import cred
...@@ -597,7 +597,16 @@ class LoginPage(rend.Page): ...@@ -597,7 +597,16 @@ class LoginPage(rend.Page):
req.addCookie("Domotikad_rme", has, path="/", secure=True, expires=http.datetimeToString(time.time())) req.addCookie("Domotikad_rme", has, path="/", secure=True, expires=http.datetimeToString(time.time()))
return self.getStandardHTML(req.path) return self.getStandardHTML(req.path)
def child_bot(self, ctx):
log.debug("BOT callback received")
chatbot = bot.BotPages()
chatbot.core = self.core
return chatbot
def childFactory(self, ctx, name): def childFactory(self, ctx, name):
log.debug("Login childFactory")
request = inevow.IRequest(ctx)
return self return self
......
...@@ -54,6 +54,21 @@ loglevels = { ...@@ -54,6 +54,21 @@ loglevels = {
#LOGLEN=10485760 # 10 mega #LOGLEN=10485760 # 10 mega
LOGLEN=26214400 # 25 mega LOGLEN=26214400 # 25 mega
from OpenSSL import SSL
class DomoSSLContext(ssl.DefaultOpenSSLContextFactory):
def cacheContext(self):
if self._context is None:
ctx = self._contextFactory(self.sslmethod)
# Disallow SSLv2! It's insecure! SSLv3 has been around since
# 1996. It's time to move on.
ctx.set_options(SSL.OP_NO_SSLv2)
ctx.use_certificate_chain_file(self.certificateFileName)
ctx.use_privatekey_file(self.privateKeyFileName)
self._context = ctx
class domotikaDaemon(Daemonizer): class domotikaDaemon(Daemonizer):
def __init__(self): def __init__(self):
...@@ -86,7 +101,7 @@ class domotikaDaemon(Daemonizer): ...@@ -86,7 +101,7 @@ class domotikaDaemon(Daemonizer):
cacert = self.daemoncfg.get('web', 'cacert') cacert = self.daemoncfg.get('web', 'cacert')
if not privkey.startswith('/'): privkey="/".join([self.curdir, privkey]) if not privkey.startswith('/'): privkey="/".join([self.curdir, privkey])
if not cacert.startswith('/'): cacert="/".join([self.curdir, cacert]) if not cacert.startswith('/'): cacert="/".join([self.curdir, cacert])
sslContext = ssl.DefaultOpenSSLContextFactory(privkey, cacert) sslContext = DomoSSLContext(privkey, cacert)
if str(self.daemoncfg.get('web', 'enable')).lower() in ['yes', '1', 'y','true']: if str(self.daemoncfg.get('web', 'enable')).lower() in ['yes', '1', 'y','true']:
reactor.listenSSL(int(self.daemoncfg.get('web', 'sslport')), WebAuthServer, reactor.listenSSL(int(self.daemoncfg.get('web', 'sslport')), WebAuthServer,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment