Proyecto

General

Perfil

« Anterior | Siguiente » 

Revisión 179

Añadido por jredrejo hace casi 14 años

Código de rayuela-ldap (módulos)

Ver diferencias:

controlies/trunk/applications/controlies/modules/LdapConnection.py2
##############################################################################
# -*- coding: utf-8 -*-
# Project: ControlIES
# Module: LdapConnection.py
# Purpose: Connection with ldap server
# Language: Python 2.5
# Date: 7-Feb-2011.
# Ver: 7-Feb-2011.
# Author: Manuel Mora Gordillo
# Copyright: 2011 - Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlIES is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlAula. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
ldap_secure=True
ldap_cert='/etc/ldap/ssl/ldap-server-pubkey.pem'
ldapmode='uid'
def session_ldap(server,username,password):
import ldap
if ldap_secure:
ldap_port = 636
con = ldap.initialize("ldaps://" + server + ":" + str(ldap_port))
if ldap_cert:
con.set_option(ldap.OPT_X_TLS_CACERTDIR, ldap_cert)
else:
ldap_port = 389
con = ldap.initialize("ldap://" + server + ":" + str(ldap_port))
if username == 'admin':
dn = "cn=" + username + ",ou=People,dc=instituto,dc=extremadura,dc=es"
else:
dn = "uid=" + username + ",ou=People,dc=instituto,dc=extremadura,dc=es"
con.simple_bind_s(dn, password)
return con
controlies/trunk/applications/controlies/modules/Utils/LdapUtils.py
# Francisco Mendez Palma
# Copyright: 2011 - Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
# 2011 - Francisco Mendez Palma <fmendezpalma @no-spam@ gmail.com>
# 2011 - José L. Redrejo Rodríguez <jredrejo @no-spam@ debian.org>
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......
# Get the max ID of the groups and users
def getMaxID(ldap):
result = ldap.search("ou=Group","cn=*",["gidNumber"])
numbers = []
for i in result:
numbers.append(int(i[0][1]['gidNumber'][0]))
result = ldap.search("ou=Group","cn=*",["gidNumber"])
numbers1 = [int(i[0][1]['gidNumber'][0]) for i in result]
result = ldap.search("ou=People","uid=*",["gidNumber","uidNumber"])
numbers2=[int(i[0][1]['gidNumber'][0]) for i in result]
numbers3=[int(i[0][1]['uidNumber'][0]) for i in result]
numbers=numbers1 + numbers2 + numbers3
result = ldap.search("ou=People","uid=*",["gidNumber","uidNumber"])
for i in result:
numbers.append(int(i[0][1]['gidNumber'][0]))
numbers.append(int(i[0][1]['uidNumber'][0]))
numbers.sort()
numbers.sort()
maxID = 1
if len(numbers) > 0:
maxID = numbers[len(numbers)-1] + 1
maxID = 1
if len(numbers) > 0:
maxID = numbers[-1:][0] + 1
return maxID
return maxID
def whatHome(type):
......
return "/home/profesor/"
else:
return "/home/alumnos/"
def clean_teachers(ldap):
"""vaciado los grupos de profesores"""
cadena="(cn=teachers)"
clean_group(cadena,ldap_con)
cadena="(groupType=school_department)"
clean_group(cadena,ldap_con)
def clean_students(ldap_con):
cadena="(cn=students)"
clean_group(cadena,ldap_con)
cadena="(groupType=school_class)"
clean_group(cadena,ldap_con)
def clean_group(tipo_grupo,ldap_con):
"""vaciado de los grupos"""
import ldap
import ldap.modlist
result = ldap_con.search("ou=Group",tipo_grupo,["member","memberuid","cn"])
if result is not None:
for grupo in result:
dn="cn="+ grupo[0][1]['cn'][0] + ",ou=Group"
attr_viejo=grupo[0][1]
attr_nuevo={'member':[''],'memberUid':[''],'cn':grupo[0][1]['cn']}
modificacion=ldap.modlist.modifyModlist(attr_viejo,attr_nuevo)
ldap_con.modify(dn, modificacion)
controlies/trunk/applications/controlies/modules/Groups.py
self.type = type
self.name = Utils.parseToLdap(name)
self.users = users
def exists_group_name(self):
result = self.ldap.search("ou=Group","cn="+self.name,["cn"])
if len(result) > 0:
return True
return False
def validation(self,action):
if self.type == "none":
......
def add(self):
maxID = str(LdapUtils.getMaxID(self.ldap))
if self.exists_group_name(): return "OK"
maxID = str(LdapUtils.getMaxID(self.ldap))
members = []
for m in self.users.split(','):
members.append("uid=" + m + ",ou=People,dc=instituto,dc=extremadura,dc=es")
if len(self.users)>0:
members = []
for m in self.users.split(','):
members.append("uid=" + m + ",ou=People,dc=instituto,dc=extremadura,dc=es")
memberuids=self.users.split(',')
else:
members=['']
memberuids=['']
attr = [
('objectclass', ['top','posixGroup','lisGroup','lisAclGroup']),
('grouptype', [self.type] ),
('gidnumber', [maxID] ),
('cn', [self.name] ),
('description', [self.name+' department group']),
('memberuid', self.users.split(',')),
('member', members)
]
attr = [
('objectclass', ['top','posixGroup','lisGroup','lisAclGroup']),
('grouptype', [self.type] ),
('gidnumber', [maxID] ),
('cn', [self.name] ),
('description', [self.name+' department group']),
('memberuid', memberuids),
('member', members)
]
self.ldap.add("cn="+self.name+",ou=Group", attr)
return "OK"
self.ldap.add("cn="+self.name+",ou=Group", attr)
return "OK"
def modify(self):
controlies/trunk/applications/controlies/modules/LdapConnection.py
ldap_secure=True
ldap_cert='/etc/ldap/ssl/ldap-server-pubkey.pem'
ldapmode='uid'
def session_ldap(server,username,password):
import ldap
if ldap_secure:
ldap_port = 636
con = ldap.initialize("ldaps://" + server + ":" + str(ldap_port))
if ldap_cert:
con.set_option(ldap.OPT_X_TLS_CACERTDIR, ldap_cert)
else:
ldap_port = 389
con = ldap.initialize("ldap://" + server + ":" + str(ldap_port))
if username == 'admin':
dn = "cn=" + username + ",ou=People,dc=instituto,dc=extremadura,dc=es"
else:
dn = "uid=" + username + ",ou=People,dc=instituto,dc=extremadura,dc=es"
con.simple_bind_s(dn, password)
return con
class LdapConnection(object):
def __init__(self,session):
self.host = session.server
controlies/trunk/applications/controlies/modules/Users.py
def __init__(self):
pass
def __init__(self,ldap,type,name,surname,nif,user,password,password2,departments,classrooms):
def __init__(self,ldap,type,name,surname,nif,user,password,password2,departments,classrooms,foto=None):
self.ldap = ldap
self.type = type
self.name = name
......
self.password2 = password2
self.departments = departments
self.classrooms = classrooms
self.foto=foto
if self.departments.__class__.__name__ == 'str': self.departments=[departments]
if self.classrooms.__class__.__name__ == 'str': self.classrooms=[classrooms]
......
return filter
def add(self):
def add(self):
maxID = str(LdapUtils.getMaxID(self.ldap))
passwd = '{SSHA}' + Utils.encrypt(self.password)
......
#('jpegPhoto', ['jpegPhoto'] ),
('userpassword', [passwd])
]
if self.foto is not None:
attr.append(('jpegPhoto',[self.foto]))
self.ldap.add("uid="+self.user+",ou=People", attr)
......
(ldap.MOD_ADD, 'memberUid', [self.user] )
]
for n in self.departments:
self.ldap.modify('cn='+ n +',ou=Group', attr)
for n in self.classrooms:
self.ldap.modify('cn='+ n +',ou=Group', attr)
if self.departments != ['']:
for n in self.departments:
self.ldap.modify('cn='+ n +',ou=Group', attr)
if self.classrooms != ['']:
for n in self.classrooms:
self.ldap.modify('cn='+ n +',ou=Group', attr)
if self.type=='teacher':
self.ldap.modify('cn=teachers,ou=Group', attr)
controlies/trunk/applications/controlies/modules/Rayuela2Ldap.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
##############################################################################
# Project: ControlIES
# Module: Rayuela2Ldap.py
# Purpose: Populate corporative ldap with data from Rayuela
# Language: Python 2.5
# Date: 1-Jun-2011.
# Ver: 13-Jun-2011.
# Author: José L. Redrejo Rodríguez
# Copyright: 2011 - José L. Redrejo Rodŕiguez <jredrejo @no-spam@ debian.org>
#
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlIES is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlIES. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import os
import Image #añadi
from gluon.storage import Storage
import xml.dom.minidom
import StringIO
import ldap
from Users import Users
from Groups import Groups
borrando=False
esAlumnos=False
ldap_con=None
usuarios=[]
def unzip_alumnos(archivo_zip):
from zipfile import ZipFile
try:
myzip= ZipFile(archivo_zip, 'r')
myzip.extractall(path="/tmp/rayuela-ldap")
except Exception,e:
return e
if not os.path.exists("/tmp/rayuela-ldap/Alumnos.xml"):
return "No es un archivo de importación de alumnos"
return "" #todo ha ido bien
def asegura_codigos(cadena):
resultado = cadena.replace(u"á", u"a")
resultado = resultado.replace(u"Á", u"A")
resultado = resultado.replace(u"à", u"a")
resultado = resultado.replace(u"À", u"A")
resultado = resultado.replace(u"é", u"e")
resultado = resultado.replace(u"É", u"E")
resultado = resultado.replace(u"è", u"e")
resultado = resultado.replace(u"È", u"E")
resultado = resultado.replace(u"í", u"i")
resultado = resultado.replace(u"Í", u"I")
resultado = resultado.replace(u"ì", u"i")
resultado = resultado.replace(u"Ì", u"I")
resultado = resultado.replace(u"ó", u"o")
resultado = resultado.replace(u"Ó", u"O")
resultado = resultado.replace(u"ò", u"o")
resultado = resultado.replace(u"Ò", u"O")
resultado = resultado.replace(u"ú", u"u")
resultado = resultado.replace(u"Ú", u"U")
resultado = resultado.replace(u"ü", u"u")
resultado = resultado.replace(u"Ü", u"U")
resultado = resultado.replace(u"ù", u"u")
resultado = resultado.replace(u"Ù", u"U")
resultado = resultado.replace(u"ª", u"a")
resultado = resultado.replace(u"º", u"o")
resultado = resultado.replace(u"ñ", u"n")
resultado = resultado.replace(u"Ñ", u"N")
resultado = resultado.replace(u"ç", u"c")
resultado = resultado.replace(u"(", "")
resultado = resultado.replace(u")", u"")
resultado = resultado.replace(u".", u"")
return str(resultado)
def chk_username(login,keep=False):
result = ldap_con.search("ou=People","uid="+ login,["uid"])
if len(result)==0 :
if not keep:
login= login + "01"
return login
else:
i=2
while len(result)>0:
nuevo_login=login + "%02d" % (i)
result = ldap_con.search("ou=People","uid="+ nuevo_login,["uid"])
i += 1
return nuevo_login
def crea_logins():
global ldap_con
global usuarios
global esAlumnos
for usuario in usuarios:
usuario["nuevo"]=True
if "dni" in usuario.keys():
#contraseña del usuario:
if esAlumnos:
usuario["passwd"]=usuario["fecha-nacimiento"].replace("/","")
if usuario["passwd"]=="": usuario["passwd"]=usuario["dni"]
else:
usuario["passwd"]=usuario["dni"]
#login del usuario, primero vemos si ya está en ldap:
result = ldap_con.search("ou=People","employeeNumber="+ usuario["dni"],["uid"])
if len(result) > 0:
usuario["login"]=result[0][0][1]['uid'][0]
usuario["nuevo"]=False
else: #si el usuario no está en ldap y es nuevo, hay que crearle el login
if usuario["datos-usuario-rayuela"] != "false": #esta en rayuela su login
usuario["login"]=chk_username(usuario["datos-usuario-rayuela"],True)
else: #iniciales del nombre + primer apellido + inicial segundo apellido
login=''
for i in zip(*usuario["nombre"].lower().split(" "))[0]:
login += i
for i in usuario["primer-apellido"].lower().replace("-"," ").split(" "):
login += i
if "segundo-apellido" in usuario.keys():
login += usuario["segundo-apellido"][0].lower()
usuario["login"]=chk_username(login)
else: #sin nie ni dni, no podemos gestionarlo
usuarios.remove(usuario)
def encode(grafico):
archivo=os.path.join("/tmp/rayuela-ldap/",grafico)
im = Image.open(archivo)
im.thumbnail((60,80), Image.ANTIALIAS)
if im.mode != "RGB":
im = im.convert("RGB")
buf= StringIO.StringIO()
try:
im.save(buf, format= 'JPEG')
resultado=buf.getvalue()
except Exception,e:
return None
return resultado
def parse_nodo(nodo):
""" para cada nodo en el xml, obtiene sus datos y prepara sus grupos"""
global usuarios
usuario={}
for info in nodo.childNodes:
if info.nodeType!=info.TEXT_NODE:
if info.nodeName in ("datos-usuario-rayuela","foto","grupos"):
dato=info.childNodes[1].firstChild.nodeValue
if info.nodeName=="foto" and dato=="true":
dato=info.getElementsByTagName("nombre-fichero")[0].firstChild.nodeValue
if info.nodeName=="datos-usuario-rayuela" and dato=="true":
dato=info.getElementsByTagName("login")[0].firstChild.nodeValue
else:
try:
dato=info.firstChild.nodeValue
except : # no hay dato en este nodo, p. ej. segundo-apellido
dato=' '
if info.nodeName == 'nie':
usuario["dni"]=asegura_codigos(dato)
elif info.nodeName == 'foto': #no paso asegura_codigos para no quitar el "."
usuario['foto']=str(dato)
else:
usuario[info.nodeName]=asegura_codigos(dato)
usuarios.append(usuario)
def parsea_archivo(archivo_xml,tipo):
xml_usuarios=xml.dom.minidom.parse(archivo_xml)
lista= xml_usuarios.getElementsByTagName(tipo)
for nodo in lista:
parse_nodo(nodo)
crea_logins()
def lista_grupos(lista,clave,sin_grupo="SIN_AULA"):
grupos={}
for i in lista:
if clave not in i.keys():
grupo=sin_grupo
else:
grupo=i[clave]
if grupo not in grupos.keys():
grupos[grupo]=[i["login"]]
else:
grupos[grupo].append(i["login"])
return grupos
def crea_grupos(ldap_con,listado):
for grupo in listado:
nuevo=Groups(ldap_con,"school_class",str(grupo),"")
nuevo.add()
def existsUsername(ldap_con,login):
result = ldap_con.search("ou=People","uid="+ login,["uid"])
if len(result) > 0:
return True
else:
return False
def crea_usuarios(ldap_con,listado):
global esAlumnos
lista=[]
if esAlumnos:
tipo="student"
else:
tipo="teacher"
for usuario in listado:
if not existsUsername(ldap_con,usuario['login']):
if usuario['foto'] == 'false':
foto=None
else:
foto=encode(usuario['foto'])
nuevo=Users(ldap_con,tipo,usuario['nombre'],usuario['primer-apellido'] + ' ' + usuario['segundo-apellido'],
usuario['dni'],usuario['login'],usuario['passwd'],usuario['passwd'],'','',foto)
nuevo.add()
lista.append((usuario['login'],True,usuario['passwd']))
else:
lista.append((usuario['login'],False,''))
return lista
def rellena_students(ldap_con,listado):
if len(ldap_con.search("ou=Group","cn=students",["cn"]))==0:
attr = [
('objectclass', ['top','posixGroup','lisGroup','lisAclGroup']),
('grouptype', ["authority_group"] ),
('gidnumber', ["1100"] ),
('cn', ['students'] ),
('description', ['Lista de estudiantes del centro']),
('memberuid', ['']),
('member', [''])
]
ldap_con.add("cn=students,ou=Group", attr)
for usuario in listado:
attr=[(ldap.MOD_ADD, 'member', ['uid=' + usuario['login'] + ',ou=People,dc=instituto,dc=extremadura,dc=es'] ),
(ldap.MOD_ADD, 'memberUid', [usuario['login']] )]
try:
ldap_con.modify('cn=students,ou=Group', attr)
except Exception,e:
print e
def rellena_teachers(ldap_con,listado):
if len(ldap_con.search("ou=Group","cn=teachers",["cn"]))==0:
attr = [
('objectclass', ['top','posixGroup','lisGroup','lisAclGroup']),
('grouptype', ["authority_group"] ),
('gidnumber', ["3000"] ),
('cn', ['teachers'] ),
('description', ['Lista de profesores del centro']),
('memberuid', ['']),
('member', [''])
]
ldap_con.add("cn=teachers,ou=Group", attr)
for usuario in listado:
attr=[(ldap.MOD_ADD, 'member', ['uid=' + usuario['login'] + ',ou=People,dc=instituto,dc=extremadura,dc=es'] ),
(ldap.MOD_ADD, 'memberUid', [usuario['login']] )]
try:
ldap_con.modify('cn=students,ou=Group', attr)
except Exception,e:
print e
def usuarios_grupos(ldap_con,lista_grupos):
for grupo in lista_grupos:
for usuario in lista_grupos[grupo]:
attr=[(ldap.MOD_ADD, 'member', ['uid=' + usuario + ',ou=People,dc=instituto,dc=extremadura,dc=es'] ),
(ldap.MOD_ADD, 'memberUid', [usuario] ) ]
try:
ldap_con.modify('cn=' + grupo + ',ou=Group', attr)
except Exception,e:
print e
if __name__ == '__main__':
#El código siguiente es sólo para depuración y desarrollo
#No tiene sentido fuera de ese contexto
import LdapConnection
import Utils.LdapUtils as LdapUtils
aulas={}
dptos={}
session=Storage()
session.server="ldap"
session.username="admin"
session.password="linex2008"
ldap_con=LdapConnection.LdapConnection(session)
ldap_con.process()
try:
os.mkdir( "/tmp/rayuela-ldap")
os.remove( "/tmp/rayuela.log")
except:
pass #problema de permisos o directorio ya creado
archivo="/opt/instituto/santaeulalia/ExportacionDatosAlumnado.zip"
esAlumnos=(archivo[-4:].lower()==".zip")
if esAlumnos:
intento=unzip_alumnos(archivo)
if intento!="":
print "PROBLEMAS",intento
else:
parsea_archivo("/tmp/rayuela-ldap/Alumnos.xml","alumno")
aulas=lista_grupos(usuarios,"grupo")
else:
parsea_archivo(archivo,"profesor")
dptos=lista_grupos(usuarios,"departamento","SIN_DPTO")
crea_grupos(ldap_con,aulas)
crea_grupos(ldap_con,dptos)
total=crea_usuarios(ldap_con,usuarios)
print total
if esAlumnos:
LdapUtils.clean_students(ldap_con)
rellena_students(ldap_con,usuarios)
usuarios_grupos(ldap_con,aulas)
else:
LdapUtils.clean_teachers(ldap_con)
rellena_teachers(ldap_con,usuarios)
usuarios_grupos(ldap_con,dptos)
controlies/trunk/applications/controlies/models/db.py
auth.settings.login_methods=[ldap_auth( server='localhost', base_dn='ou=People,dc=instituto,dc=extremadura,dc=es',secure=LdapConnection.ldap_secure,cert_path=LdapConnection.ldap_cert,mode='cn')]
#auth.settings.login_onaccept=lambda form: session_ldap(form)
def conecta():
l=LdapConnection.LdapConnection(session)
l.process()
controlies/trunk/debian/control
Package: controlies
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, python-gluon, python-ldap, python-dev, libapache2-mod-wsgi, libapache2-mod-python, libapache2-mod-gnutls, openssl, ssl-cert
Depends: ${shlibs:Depends}, ${misc:Depends}, python-gluon, python-ldap, python-imaging, python-dev, libapache2-mod-wsgi, libapache2-mod-python, libapache2-mod-gnutls, openssl, ssl-cert
Description: Gestión de LDAP para un centro educativo
ControlIES gestiona cuentas de usuarios, grupos, aulas, departamentos,
distintos tipos de ordenadores, importación de Rayuela, etc.

Exportar a: Unified diff