baswenneker / pimatic-ifttt

A pimatic plugin enabling IFTTT to trigger pimatic domotica.
http://baswenneker.github.io
GNU General Public License v2.0
2 stars 3 forks source link

Integrate node-ifttt #2

Open baswenneker opened 10 years ago

baswenneker commented 10 years ago

Dear all,

I need help with the pimatic-ifttt plugin. node-ifttt should be integrated so that the pimatic API does not have to be exposed to the internet. Please read https://github.com/baswenneker/pimatic-ifttt#todo-integrate-node-ifttt for more information.

It will take me to much time to integrate the ifttt server. So if someone is interested, please fork the code and create a pull request :)

https://github.com/baswenneker/pimatic-ifttt#todo-integrate-node-ifttt

david-kracht commented 9 years ago

dear all,

i spent one hour to implement a quick'n'dirty workaround in python to adress the "expose"-issue. its a kind of proxy, that is running on py / the pi. it filters/forwards requests to localhost, for which the credentials (username and password) has to be specified. the request are just forwarded, so its just a one-way-channel and therefore relatively safe. it's not the best solution, but i works for now ...

below there is the code. you have to set username, password and the in-port to run the proxy. you can also specify a filter-keyword, which controls, which requests are forwarded. the out-port is set to the standard port 80 on localhost.

use, e.g. the following command to run it as service:

sudo nohup python pimatic-proxy.py -user admin -pass 1234 -pI 8080 -keyword 'api' &

you can download pimatic-proxy.py here.

cheers, dave

btw: just run one instance of this service !!! and you have to kill the service by hand.

import argparse
import urllib2
import SocketServer

if __name__ == "__main__":

    parser = argparse.ArgumentParser(prog='PIMATIC-PASSWORD-BYPASS-PROXY' )

    parser.add_argument('-user',help='Pimatic Username',required=True, dest='username', type=str)
    parser.add_argument('-pass',help='Pimatic Password',required=True, dest='password', type=str)
    parser.add_argument('-keyword',help='Only requests with <keyword> string included will be forwarded', default='', dest='keyword', type=str)
    parser.add_argument('-pI',help='Input Port', required=True, dest='in_port', type=int) 
    parser.add_argument('-pO',help='Output Port', default=80, dest='out_port', type=int) 

    parser.add_argument('-v', action='version', version='%(prog)s 1.0')    
    args = parser.parse_args()

    #install credentials on opener
    handle = urllib2.HTTPPasswordMgrWithDefaultRealm()
    handle.add_password(None, 'http://localhost', args.username, args.password)

    handler = urllib2.HTTPBasicAuthHandler(handle)
    opener = urllib2.build_opener(handler)
    urllib2.install_opener(opener)

    #init the server
    class myHandler(SocketServer.BaseRequestHandler):

        def handle(self):
            self.path = self.request.recv(8192).split()[1]           
            self.ip = self.client_address

            print 'connection from  :\t%s:%s' % self.ip
            print ' | --> incoming  :\t%s'% self.path      

            data = 'HTTP/1.1 200 OK\r\n'
            if self.path !='/' and args.keyword in self.path : 

                try:
                    url = 'http://localhost:%d%s' % (args.out_port,self.path) 
                    res = urllib2.urlopen( url )                  
                    data += ''.join( res.info().headers ) +'\r\n'+ res.read()

                    print ' | forwarded --> :\t%s'% url  

                except URLError:
                    print 'URLError: %s' %url 

            self.request.sendall( data +'\r\n' )                    
            print

    #serve forever            
    SocketServer.TCPServer(("", args.in_port), myHandler).serve_forever()