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

Source Code for Module zephir.backend.users_rpc

  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  # users_rpc.py 
  9  #   
 10  # fonctions xmlrpc pour la gestion des utilisateurs et permissions 
 11  #        
 12  ########################################################################### 
 13  """module de gestion des utilisateurs de l'application 
 14  """ 
 15  from zephir.backend import config 
 16  from zephir.backend.config import u 
 17  from zephir.backend.db_utils import * 
 18  from zephir.backend.entid import IdPoolManager 
 19  from zephir.backend.lib_backend import serveur_pool 
 20  from zephir.backend.schedule import TaskScheduler 
 21  from zephir.backend.xmlrpceole import XMLRPCEole as XMLRPC 
 22   
 23  import sys,base64,ldap,os 
 24  import traceback 
 25   
26 -class RPCUsers(XMLRPC):
27 """serveur XMLRPC zephir pour la gestion des utilisateurs de l'application 28 """ 29
30 - def __init__(self):
31 self.dbpool = db_connect() 32 self.dbpool.noisy = 0 33 # pool de représentation des serveurs 34 self.s_pool = serveur_pool() 35 self.scheduler = TaskScheduler(self.s_pool) 36 XMLRPC.__init__(self) 37 self.reload_perms=0
38
39 - def xmlrpc_get_stats(self, cred_user):
40 """renvoie des statistiques générales sur les serveurs""" 41 return 1, u(self.s_pool.get_stats())
42
43 - def xmlrpc_get_rights(self,cred_user):
44 """liste des groupes de droits""" 45 # on précharge les groupes de droits 46 query = """select * from groupes_droits""" 47 return self.dbpool.runQuery(query).addCallbacks(self._load_rights,db_client_failed)
48
49 - def _load_rights(self,data):
50 """formattage des groupes de droits 51 """ 52 # on crée en mémoire un dictionnaire des groupes de droits 53 droits=[] 54 for groupe in data: 55 # dictionnaire du type : {id:[droits,libelle]} 56 droits.append([groupe[0],groupe[1],eval(groupe[2])]) 57 return 1, u(droits)
58
59 - def xmlrpc_get_permissions(self,cred_user,username):
60 """liste des permissions de l'application pour un utilisateur précis""" 61 # on récupère la liste des groupes de permissions pour l'utilisateur 62 query = """select login, droits from users where login = %s""" 63 64 return self.dbpool.runQuery(query, (username,)).addCallbacks(self._get_permissions,db_client_failed)
65
66 - def _get_permissions(self,data):
67 try: 68 # si l'utilisateur existe, on récupère ses groupes de droits 69 username = data[0][0] 70 groupes = eval(data[0][1]) 71 except: 72 # aucun groupe autorisé pour cet utilisateur 73 return 1, [] 74 75 return 1, u(groupes)
76
77 - def xmlrpc_save_permissions(self,cred_user,username,user_auths):
78 """sauvegarde les autorisations de l'utilisateur""" 79 80 # on regarde si l'utilisateur existe dans la base de données 81 query = """select login,nom,prenom,mail from users where login = %s""" 82 return self.dbpool.runQuery(query, (username,)).addCallbacks(self._save_permissions,db_client_failed,callbackArgs=[username,user_auths])
83
84 - def _save_permissions(self,data,username,user_auths):
85 # on tente de récupèrer certaines valeurs dans l'annuaire (mail, nom, prenom) 86 if data!=[]: 87 nom=data[0][1] 88 prenom=data[0][2] 89 mail=data[0][3] 90 else: 91 nom="" 92 prenom="" 93 mail="" 94 try: 95 l=ldap.open(config.ADRESSE_LDAP) 96 # on récupère le dn complet de l'utilisateur 97 result=l.search_s(config.BASE_LDAP, ldap.SCOPE_SUBTREE, "(uid="+username+")") 98 res_ldap = result[0][1] 99 l.unbind() 100 if nom == "": 101 try: 102 nom=res_ldap['sn'][0] 103 except KeyError: 104 pass 105 if prenom == "": 106 try: 107 prenom=res_ldap['givenName'][0] 108 except KeyError: 109 pass 110 if mail == "": 111 try: 112 mail=res_ldap['mail'][0] 113 except KeyError: 114 pass 115 except: 116 pass 117 if data != []: 118 # si utilisateur existant, on le met à jour 119 query = """update users set droits=E%s,nom=E%s,prenom=E%s,mail=E%s where login=E%s""" 120 params = (str(user_auths), nom, prenom, mail, username) 121 else: 122 # sinon on le crée avec des valeurs par défaut 123 query = """insert into users (login,mail_actif,sms_actif,droits,nom,prenom,mail) \ 124 values (E%s,%s,%s,%s,E%s,E%s,E%s)""" 125 params = (username, 0, 0, str(user_auths), nom, prenom, mail) 126 127 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,'ok'],db_client_failed)
128
129 - def xmlrpc_get_restrictions(self, cred_user, login, type_res=None):
130 """ajoute des restrictions sur les serveurs accessibles à un utilisateur 131 """ 132 try: 133 res = self.s_pool.get_restrictions(login, type_res) 134 except KeyError: 135 return 0, u("utilisateur ou type de contrainte non valides") 136 return 1, u(res)
137
138 - def xmlrpc_add_restriction(self, cred_user, login, type_res, id_res):
139 """ajoute des restrictions sur les serveurs accessibles à un utilisateur 140 """ 141 # on regarde si l'utilisateur existe 142 query = """select login,nom,prenom,mail from users where login = %s""" 143 return self.dbpool.runQuery(query, (login,)).addCallbacks(self._add_restriction,db_client_failed,callbackArgs=[login, type_res, id_res])
144
145 - def _add_restriction(self,data,login,type_res,id_res):
146 # on tente de récupèrer certaines valeurs dans l'annuaire (mail, nom, prenom) 147 if data!=[]: 148 nom=data[0][1] 149 prenom=data[0][2] 150 mail=data[0][3] 151 else: 152 nom="" 153 prenom="" 154 mail="" 155 try: 156 l=ldap.open(config.ADRESSE_LDAP) 157 # on récupère le dn complet de l'utilisateur 158 result=l.search_s(config.BASE_LDAP, ldap.SCOPE_SUBTREE, "(uid="+login+")") 159 res_ldap = result[0][1] 160 l.unbind() 161 if nom == "": 162 try: 163 nom=res_ldap['sn'][0] 164 except KeyError: 165 pass 166 if prenom == "": 167 try: 168 prenom=res_ldap['givenName'][0] 169 except KeyError: 170 pass 171 if mail == "": 172 try: 173 mail=res_ldap['mail'][0] 174 except KeyError: 175 pass 176 except: 177 pass 178 if data == []: 179 user_auths = [] 180 # si l'utilisateur n'existe pas encore, on le crée avec des valeurs par défaut 181 query = """insert into users (login,mail_actif,sms_actif,droits,nom,prenom,mail) \ 182 values (E%s,%s,%s,%s,E%s,E%s,E%s)""" 183 params = (login, 0, 0, user_auths, nom, prenom, mail) 184 return self.dbpool.runOperation(query, params).addCallbacks(self._add_restriction2,db_client_failed,callbackArgs=[login, type_res, id_res]) 185 else: 186 return self._add_restriction2(None, login, type_res, id_res)
187
188 - def _add_restriction2(self,retour,login,type_res,id_res):
189 # ajout réel de la restriction demandée 190 if self.s_pool.add_restriction(login, type_res, id_res): 191 return 1, "ok" 192 else: 193 return 0, u("erreur lors de l'ajout de la contrainte")
194
195 - def xmlrpc_del_restriction(self, cred_user, login, type_res, id_res):
196 """ajoute des restrictions sur les serveurs accessibles à un utilisateur 197 """ 198 if self.s_pool.del_restriction(login, type_res, id_res): 199 return 1, "ok" 200 else: 201 return 0, u("erreur, contrainte non retrouvée")
202
203 - def xmlrpc_user_group(self,cred_user,username,groupes):
204 """met à jour la liste des groupes surveillés par l'utilisateur""" 205 query = """update users set groupes = %s where login = %s""" 206 params = (str(groupes),username) 207 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,'ok'],db_client_failed)
208
209 - def xmlrpc_get_user(self,cred_user,username):
210 """renvoie les informations d'un utilisateur 211 """ 212 query = """select login,mail,nom,prenom,sms,mail_actif,sms_actif,droits,groupes,cle from users where login = %s""" 213 return self.dbpool.runQuery(query, (username,)).addCallbacks(self._get_user,db_client_failed)
214
215 - def xmlrpc_list_users(self,cred_user):
216 """retourne la liste des utilisateurs""" 217 query = """select login from users order by login asc""" 218 return self.dbpool.runQuery(query).addCallbacks(self._list_users,db_client_failed)
219
220 - def _list_users(self,data):
221 """formate la sortie de la base de données""" 222 logins=[] 223 for user in data: 224 logins.append(user[0]) 225 return 1,u(logins)
226
227 - def xmlrpc_del_user(self,cred_user,login):
228 """suppression d'un utilisateur""" 229 if login: 230 # on interdit la suppression si des variantes appartiennent à l'utilisateur 231 query = """select libelle from variantes where owner=%s""" 232 return self.dbpool.runQuery(query, (login,)).addCallbacks(self._del_user,db_client_failed,callbackArgs=[login]) 233 else: 234 return 0,u("""donnez un identifiant""")
235
236 - def _del_user(self, data, login):
237 if len(data) > 0: 238 return 0, u("""suppression impossible, des variantes appartiennent à %s: %s""" % (login, ", ".join([lib[0] for lib in data]))) 239 # suppression de l'utilisateur service dans la base de données 240 query = """delete from restrictions where login=%s""" 241 self.dbpool.runOperation(query, (login,)) 242 query = """delete from serveur_auth where login=%s""" 243 self.dbpool.runOperation(query, (login,)) 244 query = """delete from users where login=%s""" 245 return self.dbpool.runOperation(query, (login,)).addCallbacks(lambda x:(1,'ok'), db_client_failed)
246
247 - def xmlrpc_edit_user(self,cred_user,username,nom,prenom,mail,sms,mail_actif,sms_actif):
248 """édite les informations d'un utilisateur 249 """ 250 query = """select * from users where login=%s""" 251 return self.dbpool.runQuery(query, (username,)).addCallbacks(self._edit_user,db_client_failed,callbackArgs=[username,nom,prenom,mail,sms,mail_actif,sms_actif])
252
253 - def _edit_user(self,data,username,nom,prenom,mail,sms,mail_actif,sms_actif):
254 """ 255 """ 256 if data == []: 257 # utilisateur inexistant 258 query = """insert into users (login, nom, prenom, mail, sms, mail_actif, sms_actif, droits, \ 259 groupes, cle) values (E%s,E%s,E%s,E%s,E%s,%s,%s,'','','')""" 260 params = (username, nom, prenom, mail, sms, int(mail_actif), int(sms_actif)) 261 else: 262 query = """update users set nom=E%s, prenom=E%s, mail=E%s, sms=E%s, mail_actif=%s, sms_actif=%s where login=E%s""" 263 params = (nom, prenom, mail, sms, int(mail_actif), int(sms_actif), username) 264 265 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,'ok'],db_client_failed)
266 267 268
269 - def _get_user(self,data):
270 """formate la sortie de la base de données""" 271 user=[] 272 if data != []: 273 for field in data[0]: 274 if field in [None, 'None']: 275 user.append("") 276 else: 277 user.append(field) 278 279 if user[7] == "": 280 user[7] = "[]" 281 if user[8] == "": 282 user[8] = "[]" 283 if user[9] != "": 284 user[9] = 1 285 else: 286 user[9] = 0 287 288 return 1, u([user[0],user[1],user[2],user[3],user[4],int(user[5]),int(user[6]),eval(user[7]),eval(user[8]),user[9]]) 289 else: 290 return 1, []
291
292 - def xmlrpc_save_key(self,cred_user,cle):
293 """sauvegarde la cle ssh de l'utilisateur""" 294 query = """update users set cle=E%s where login=%s""" 295 params = (cle, cred_user) 296 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,'ok'], db_client_failed)
297
298 - def xmlrpc_update_client(self,cred_user,name,content=""):
299 """fonction de mise à jour du client disponible sur zephir""" 300 # on supprime l'ancienne version du fichier. 301 try: 302 rpm_dir = os.path.abspath(config.PATH_ZEPHIR)+"/sites/client/" 303 if not os.path.isdir(rpm_dir): 304 os.makedirs(rpm_dir) 305 b_name = os.path.basename(name) 306 rpms = os.listdir(rpm_dir) 307 for rpm in rpms: 308 # on enlève les rpm avec même version (majeure+mineure) 309 if rpm.startswith(b_name[:b_name.rindex('-')]) and rpm.endswith(os.path.splitext(b_name)[1]): 310 os.unlink(rpm_dir+rpm) 311 # on écrit le nouveau paquet 312 # si pas de contenu, on essaye de télécharger la version officielle sur le site ftp 313 if content == "": 314 import ftplib 315 conn = ftplib.FTP(config.CLIENT_UPDATE_HOST) 316 conn.login() 317 if name.endswith('.deb'): 318 conn.cwd(config.CLIENT_NG_URL) 319 else: 320 conn.cwd(config.CLIENT_UPDATE_URL) 321 if os.path.dirname(name) != '': 322 conn.cwd(os.path.dirname(name)) 323 conn.retrbinary('RETR %s' % b_name, open(rpm_dir + b_name, 'wb').write) 324 else: 325 content = base64.decodestring(content) 326 fic_rpm=file(rpm_dir + b_name,'w') 327 fic_rpm.write(content) 328 fic_rpm.close() 329 return 1, "OK" 330 except Exception, e: 331 traceback.print_exc() 332 return 0, u("Erreur de mise a jour du client")
333
334 - def xmlrpc_remove_client(self,cred_user,name):
335 """suppression d'un client disponible sur zephir""" 336 try: 337 rpm_dir = os.path.abspath(config.PATH_ZEPHIR)+"/sites/client/" 338 rpm = os.path.join(rpm_dir,name) 339 if not os.path.isfile(rpm): 340 return 0, u("Fichier non trouvé %s" % name) 341 os.unlink(rpm) 342 return 1, "OK" 343 except Exception, e: 344 return 0, u("Erreur de suppression du fichier")
345
346 - def xmlrpc_maj_client(self,cred_user,version):
347 """fonction de vérification de la version du client""" 348 # on regarde la version actuelle du client sur zephir 349 vers_majmin=version[:version.rindex('-')] 350 try: 351 version_locale = "" 352 if os.path.isdir(os.path.abspath(config.PATH_ZEPHIR)+"/sites/client"): 353 rpms=os.listdir(os.path.abspath(config.PATH_ZEPHIR)+"/sites/client") 354 for rpm in rpms: 355 # on regarde si on a un paquet correspondant (mm version globale du client) 356 if rpm.startswith(vers_majmin): 357 version_locale=rpm 358 break 359 if version_locale == "": 360 # on a pas trouvé de rpm de mise à jour 361 return 1,"OK" 362 except Exception,e: 363 return 0,u('erreur lors de la lecture de la version sur zephir : %s' % str(e)) 364 # on compare avec la version envoyée par le client 365 vers_loc = version_locale.replace(vers_majmin,"") 366 vers_dist = version.replace(vers_majmin,"") 367 if version.split('zephir-client')[1][1:].startswith('2'): 368 # cas de eole2 : revision avec X ou Xeol ? 369 vers_loc = vers_loc[1:vers_loc.index('_')].replace('eole','') 370 vers_dist = vers_dist[1:].replace('eole','') 371 else: 372 vers_loc = vers_loc[1:vers_loc.index('eol')] 373 vers_dist = vers_dist[1:vers_dist.index('eol')] 374 # comparaison de la révision 375 maj=0 376 if int(vers_loc) > int(vers_dist): 377 maj=1 378 if maj == 1: 379 return 1,u(version_locale.strip()) 380 else: 381 return 1,"OK"
382
383 - def xmlrpc_list_client(self,cred_user):
384 """liste les clients disponibles sur zephir""" 385 try: 386 rpms = [] 387 rpm_dir = os.path.abspath(config.PATH_ZEPHIR)+"/sites/client/" 388 if os.path.isdir(rpm_dir): 389 for rpm in os.listdir(rpm_dir): 390 if rpm.startswith('zephir-client'): 391 rpms.append(rpm) 392 return 1, u(rpms) 393 except Exception, e: 394 return 0, u("Erreur de lecture du répertoire")
395