Mostly complete but untested API

api
Simon 2 years ago
parent c086ff60fe
commit 4f7cd970b5

131
API.py

@ -1,62 +1,85 @@
from xmlrpc.client import Fault
from twisted.web import xmlrpc
from hashlib import blake2b
class FD_API_HELPERS():
def __init__(self,CONFIG,APIQUEUE):
self._CONFIG = CONFIG
self._APIQUEUE = APIQUEUE
def connected(self,_id):
for system in self._CONFIG['SYSTEMS']:
for peerid in self._CONFIG['SYSTEMS'][self._system]['PEERS']:
if peerid == _id:
return(system)
return(False)
def validateHMAC(_hmac,_system):
self._config = self._CONFIG['SYSTEMS'][_system]
_h = blake2b(key=self._config['_opt_key'], digest_size=16)
_h.update('validate')
_hash = _h.digest()
if _hash == _hmac:
return(True)
from spyne import ServiceBase, rpc, Integer, Decimal, UnsignedInteger32, Unicode, Iterable, error
from dmr_utils3.utils import bytes_3
class FD_APIUserDefinedContext(object):
def __init__(self,CONFIG,APIQUEUE,BRIDGES):
self.CONFIG = CONFIG
self.APIQUEUE = APIQUEUE
self.BRIDGES = BRIDGES
def getconfig(self):
return self.CONFIG
def getapiqueue(self):
return self.APIQUEUE
def getbridges(self):
return self.BRIDGES
def validateKey(self,dmrid,key):
systems = self.CONFIG['SYSTEMS']
dmrid = bytes_3(dmrid)
for system in systems:
for peerid in systems[system]['PEERS']:
if peerid == dmrid:
if key == _hash:
return(systems[system]['_opt_key'])
else:
return(False)
def reset(self,system):
self.CONFIG['SYSTEMS'][system]['_reset'] = True
def queue(self,system,options):
self.APIQUEUE.append((system,options))
class FD_API(ServiceBase):
_version = 0.1
#def validateHMAC(_hmac,_system):
# self._config = self._CONFIG['SYSTEMS'][_system]
# _h = blake2b(key=self._config['_opt_key'], digest_size=16)
# _h.update('validate')
# _hash = _h.digest()
# if _hash == _hmac:
# return(True)
# else:
# return(False)
#return API version
@rpc(Unicode, _returns=Decimal())
def version(ctx, sessionid):
return(FD_API._version)
@rpc(Unicode,Unicode, _returns=Unicode())
def reset(ctx,dmrid,key):
system = ctx.udc.validateKey(dmrid,key)
if system:
ctx.udc.reset(system)
else:
return(False)
class FD_API(xmlrpc.XMLRPC(allow_none=True)):
raise error.InvalidCredentialsError()
def __init__(self,CONFIG,APIQUEUE):
self._CONFIG = CONFIG
self._APIQUEUE = APIQUEUE
self.helpers = FD_API_HELPERS(self._CONFIG,self._APIQUEUE)
def reset(self,_id,_hmac):
return('<xml></xml>')
system = self.helpers.connected(_id)
if result:
if self.helpers.validateHMAC(_hmac,_system):
self._CONFIG['SYSTEMS'][system]['_reset'] = True
else:
return Fault(2, "Authentication failed")
@rpc(UnsignedInteger32,UnsignedInteger32,Unicode,_returns=Unicode())
def setoptions(ctx,dmrid,key,options):
system = ctx.udc.validateKey(dmrid,key)
if system:
ctx.udc.queue(system,options)
else:
return Fault(1, "ID not connected to this server")
return('Z')
def main():
from twisted.internet import reactor
from twisted.web import server
raise error.InvalidCredentialsError()
r = FD_API({},{})
reactor.listenTCP(7080, server.Site(r))
reactor.run()
@rpc(UnsignedInteger32,_returns=(Unicode()))
def killserver(ctx,killkey):
pass
@rpc(_returns=Unicode())
def getconfig(ctx):
return ctx.udc.getconfig()
if __name__ == "__main__":
main()
@rpc(_returns=Unicode())
def getbridges(ctx):
return ctx.udc.getbridges()

@ -50,7 +50,15 @@ from hashlib import blake2b
from twisted.internet.protocol import Factory, Protocol
from twisted.protocols.basic import NetstringReceiver
from twisted.internet import reactor, task
from twisted.web import server
from twisted.web.server import Site
from spyne import Application
from spyne.server.twisted import TwistedWebResource
from spyne.protocol.http import HttpRpc
from spyne.protocol.json import JsonDocument
# Things we import from the main hblink module
from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, mk_aliases, acl_check
@ -81,8 +89,7 @@ import re
from binascii import b2a_hex as ahex
from AMI import AMI
from API import FD_API
from API import FD_API, FD_APIUserDefinedContext
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
__author__ = 'Cortney T. Buffington, N0MJS, Forked by Simon Adlem - G7RZU'
@ -137,12 +144,25 @@ def config_reports(_config, _factory):
return report_server
# Start API server
def config_API(_config, _apiqueue):
def config_API(_config, _apiqueu, _bridges):
r = FD_API(_config,_apiqueue)
reactor.listenTCP(7080, server.Site(r))
application = Application([FD_API],
tns='freedmr.api',
in_protocol=HttpRpc(validator='soft'),
out_protocol=JsonDocument()
)
return r
def _on_method_call(ctx):
ctx.udc = FD_APIUserDefinedContext(CONFIG,APIQUEUE,_bridges)
application.event_manager.add_listener('method_call', _on_method_call)
resource = TwistedWebResource(application)
site = Site(resource)
r = reactor.listenTCP(8000, site, interface='0.0.0.0')
return(r)
# Import Bridging rules
@ -821,6 +841,13 @@ def options_config():
prohibitedTGs = [0,1,2,3,4,5,9,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999]
try:
for (system,options) in APIQUEUE.pop(1):
if not CONFIG['SYSTEMS'][_system]['_reset']:
CONFIG['SYSTEMS'][system][OPTIONS] = options
except IndexError:
pass
for _system in CONFIG['SYSTEMS']:
try:
if CONFIG['SYSTEMS'][_system]['MODE'] != 'MASTER':
@ -2613,6 +2640,9 @@ if __name__ == '__main__':
import sys
import os
import signal
global CONFIG
global APIQUEUE
# Higheset peer ID permitted by HBP
PEER_MAX = 4294967295
@ -2856,8 +2886,8 @@ if __name__ == '__main__':
#Initialize API
APIQUEUE = {}
api = config_API(CONFIG,APIQUEUE)
APIQUEUE = []
api = config_API(CONFIG,APIQUEUE,BRIDGES)
if api:
logger.info('(API) API running')
else:

@ -6,3 +6,4 @@ configparser>=3.0.0
resettabletimer>=0.7.0
setproctitle
Pyro5
spyne

Loading…
Cancel
Save

Powered by TurnKey Linux.