From 92684276bee3975ff99cf392b7691fa9734b0309 Mon Sep 17 00:00:00 2001 From: Mark Huang Date: Fri, 15 Dec 2006 18:39:51 +0000 Subject: [PATCH] - make Peer a wrapper around xmlrpclib.ServerProxy, that also magically signs each call and checks the SSL certificate --- PLC/Peers.py | 72 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/PLC/Peers.py b/PLC/Peers.py index a80d87f..ba9029d 100644 --- a/PLC/Peers.py +++ b/PLC/Peers.py @@ -6,14 +6,19 @@ import re from types import StringTypes from PLC.Faults import * -from PLC.Parameter import Parameter +from PLC.Parameter import Parameter, Mixed from PLC.Filter import Filter from PLC.Table import Row, Table +import PLC.Auth from PLC.Nodes import Nodes,Node from PLC.Slices import Slices,Slice -class Peer (Row): +import xmlrpclib +from PLC.PyCurl import PyCurlTransport +from PLC.GPG import gpg_sign + +class Peer(Row): """ Stores the list of peering PLCs in the peers table. See the Row class for more details @@ -25,8 +30,8 @@ class Peer (Row): 'peer_id' : Parameter (int, "Peer identifier"), 'peername' : Parameter (str, "Peer name"), 'peer_url' : Parameter (str, "Peer API url"), - ### xxx this trick is temporary, for peer authentication - 'auth_person_id' : Parameter (int, "Person_id of the account storing credentials - temporary"), + 'key': Parameter(str, "Peer GPG public key"), + 'cacert': Parameter(str, "Peer SSL public certificate"), ### cross refs 'site_ids' : Parameter ([int], "This peer's sites ids"), 'person_ids' : Parameter ([int], "This peer's persons ids"), @@ -43,12 +48,6 @@ class Peer (Row): raise invalid_url return url - ### for use by RefreshPeer, *not* a method of the API - def update_name (self,peername): - if self['peername'] != peername: - self['peername']=peername - self.sync() - def delete (self, commit=True): """ Delete peer @@ -64,6 +63,59 @@ class Peer (Row): self['deleted'] = True self.sync(commit) + def connect(self, **kwds): + """ + Connect to this peer via XML-RPC. + """ + + self.server = xmlrpclib.ServerProxy(self['peer_url'], + PyCurlTransport(self['peer_url'], self['cacert']), + allow_none = 1, **kwds) + + def add_auth(self, function, methodname, **kwds): + """ + Sign the specified XML-RPC call and add an auth struct as the + first argument of the call. + """ + + def wrapper(*args, **kwds): + signature = gpg_sign(methodname, args, + self.api.config.PLC_ROOT_GPG_KEY, + self.api.config.PLC_ROOT_GPG_KEY_PUB) + + auth = {'AuthMethod': "gpg", + 'name': self.api.config.PLC_NAME, + 'signature': signature} + + # Automagically add auth struct to every call + args = (auth,) + args + + return function(*args) + + return wrapper + + def __getattr__(self, methodname): + """ + Fetch a callable for the specified method. + """ + + function = getattr(self.server, methodname) + + try: + # Figure out if the function is a PLCAPI function and + # requires an authentication structure as its first + # argument. + api_function = self.api.callable(methodname) + if api_function.accepts and \ + (isinstance(api_function.accepts[0], PLC.Auth.Auth) or \ + (isinstance(api_function.accepts[0], Mixed) and \ + filter(lambda param: isinstance(param, Auth), func.accepts[0]))): + function = self.add_auth(function, methodname) + except Exception, err: + pass + + return function + class Peers (Table): """ Maps to the peers table in the database -- 2.43.0