Package zephir :: Package backend :: Module xmlrpceole
[frames] | no frames]

Source Code for Module zephir.backend.xmlrpceole

  1  # -*- coding: UTF-8 -*- 
  2  ########################################################################### 
  3  # Eole NG - 2007   
  4  # Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon) 
  5  # Licence CeCill  cf /root/LicenceEole.txt 
  6  # eole@ac-dijon.fr  
  7  #   
  8  # xmlrpceole.py 
  9  #   
 10  # Version modifiée du serveur XMLRPC twisted pour gérer 
 11  # l'authentification et la gestion des droits 
 12  #        
 13  ########################################################################### 
 14  import twisted 
 15  try: 
 16      assert twisted.__version__[0] >= '2' 
 17      from twisted.web import http 
 18  except: 
 19      from twisted.protocols import http 
 20  from twisted.web import error 
 21  from zephir.backend import config 
 22  from zephir.backend.lib_backend import ResourceAuthError 
 23   
 24  from twisted.internet import defer 
 25  from twisted.web import xmlrpc,server 
 26  from zephir.eolerpclib import xmlrpclib 
 27  import psycopg2 as PgSQL 
 28  import time 
 29   
 30  try: 
 31      import ldap 
 32  except: 
 33      pass 
 34       
 35   
36 -def convert(objet):
37 """Transforme les objets unicode contenus dans un objet en chaines 38 """ 39 if type(objet) == tuple: 40 l = [] 41 for item in objet: 42 l.append(convert(item)) 43 return l 44 if type(objet) == list: 45 l = [] 46 for item in objet: 47 l.append(convert(item)) 48 return l 49 if type(objet) == dict: 50 dico={} 51 for cle in objet.keys(): 52 dico[cle] = convert(objet[cle]) 53 return dico 54 if type(objet) == unicode: 55 string = objet.encode(config.charset) 56 return string 57 return objet
58 59 60 # serveur sécurisé XMLPRC
61 -class XMLRPCEole(xmlrpc.XMLRPC):
62 63
64 - def __init__(self):
65 xmlrpc.XMLRPC.__init__(self) 66 # définition des autorisations pour chaque utilisateur 67 self.serveur_ldap = config.ADRESSE_LDAP 68 # reload_perms : indique que les permissions ont changé 69 # et qu'il faut les recharger 70 self.reload_perms = 0 71 self.load_groupes()
72
73 - def load_groupes(self):
74 # chargement des groupes de droits 75 cx = PgSQL.connect(database='zephir',user='zephir',password=config.DB_PASSWD) 76 db_cursor = cx.cursor() 77 db_cursor.execute("""select id,libelle,droits from groupes_droits""") 78 res = db_cursor.fetchall() 79 db_cursor.close() 80 cx.close() 81 self.groupes={} 82 for groupe in res: 83 self.groupes[int(groupe[0])]=[str(res[1]),eval(str(groupe[2]))]
84
85 - def render(self,request):
86 """examine la requête transmise par le client et apelle la procédure 87 correspondante si ses autorisations sont suffisantes""" 88 # test de l'authentification 89 cred_user = request.getUser() 90 cred_password = request.getPassword() 91 # dans le cas de l'utilisateur zephir, on ne fait pas de vérification sur ldap 92 if cred_user != 'zephir' or cred_password != 'zephir': 93 # on tente une connexion au serveur ldap avec ce login et mot de passe 94 retry_auth = 0 95 while retry_auth < 2: 96 try: 97 if cred_password == "": 98 cred_password = None 99 query=ldap.open(self.serveur_ldap) 100 # on récupère le dn complet de l'utilisateur 101 result=query.search_s(config.BASE_LDAP, ldap.SCOPE_SUBTREE, "(uid="+cred_user+")") 102 cred_dn = result[0][0] 103 query.simple_bind_s(cred_dn,cred_password) 104 query.unbind() 105 except ldap.SERVER_DOWN: 106 print "ldap server not responding, retrying authentification" 107 time.sleep(0.3) 108 retry_auth += 1 109 except: 110 # erreur d'authentification 111 # on retourne un message d'erreur 112 print "\nauthentification incorrecte : ",request.host.host 113 errpage = error.ErrorPage(http.UNAUTHORIZED,"Unauthorized","401 Authentication required") 114 return errpage.render(request) 115 retry_auth = 2 116 else: 117 retry_auth = 2 118 pass 119 # print "\nclient authentifié : ",request.getHost()[1] 120 121 request.content.seek(0, 0) 122 args, functionPath = xmlrpclib.loads(request.content.read()) 123 # Récupération de l'ip de connexion du serveur 124 ip_publique = None 125 if functionPath == 'uucp.maj_site': 126 ip_publique = request.getClientIP() 127 args_list=[] 128 if ip_publique is not None: 129 args_list.append(ip_publique) 130 for arg in args: 131 arg_conv=convert(arg) 132 args_list.append(arg_conv) 133 args = tuple(args_list) 134 135 # on vérifie si l'utilisateur a le droit d'utiliser cette fonction 136 # on récupère les groupes de droits de l'utilisateur 137 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD) 138 cursor=cx.cursor() 139 cursor.execute("""select droits from users where login=%s""", (cred_user,)) 140 rs = cursor.fetchone() 141 cursor.close() 142 cx.close() 143 droits = [] 144 # on rassemble toutes les fonctions auxquelles on a droit 145 if rs == [] or rs is None: 146 groupe = [] 147 else: 148 for groupe in eval(rs[0]): 149 droits.extend(self.groupes[groupe][1]) 150 try: 151 # on regarde si on a le droit d'executer la fonction 152 if functionPath not in droits: 153 # fonction interdite 154 if request.host.host not in ["localhost", "127.0.0.1"]: 155 host_addr = " (%s)" % request.host.host 156 else: 157 host_addr = "" 158 print "\nutilisation de la fonction %s interdite pour %s%s" % (functionPath,cred_user,host_addr) 159 errpage = error.ErrorPage(http.UNAUTHORIZED,"Unauthorized","erreur, ressource %s non autorisée !" % (request.uri)) 160 return errpage.render(request) 161 except: 162 print "\n pas d'autorisations pour " + cred_user + " !" 163 errpage = error.ErrorPage(http.UNAUTHORIZED,"Unauthorized","erreur, ressource %s non autorisée !" % (request.uri)) 164 return errpage.render(request) 165 # fonction autorisée 166 try: 167 function = self._getFunction(functionPath) 168 except xmlrpc.NoSuchFunction: 169 self._cbRender( 170 xmlrpclib.Fault(self.NOT_FOUND, "no such function %s" % functionPath), 171 request 172 ) 173 else: 174 request.setHeader("content-type", "text/xml") 175 if config.LOG_ACTIONS and cred_user not in ('zephir','', None): 176 try: 177 print "ZEPHIR_BACKEND : %s -> %s" % (cred_user, functionPath), args 178 except Exception, e: 179 print "Erreur lors du log d'une action : ", str(e) 180 defer.maybeDeferred(function, cred_user, *args).addErrback( 181 self.ebRender, request 182 ).addCallback( 183 self._cbRender, request 184 ) 185 return server.NOT_DONE_YET
186
187 - def ebRender(self, ex, request):
188 """errback intermédiaire pour catcher les ressources non autorisées""" 189 if ex.type == ResourceAuthError: 190 errpage = error.ErrorPage(http.UNAUTHORIZED,"Unauthorized","erreur, autorisations insuffisantes (%s) !" % (str(ex.value))) 191 print "\ntentative d'accès à une ressource interdite pour %s : %s" % (request.getUser(),str(ex.value)) 192 return errpage.render(request) 193 else: 194 self._ebRender(ex)
195