Mostrando entradas con la etiqueta unb. Mostrar todas las entradas
Mostrando entradas con la etiqueta unb. Mostrar todas las entradas

23 noviembre 2007

Mysql con python (migración de UNB a phpBB)

Esta entrada está relacionada con ésta otra cómo migrar los usuarios de UNB forms a phpBB.

Para terminar con la migración del foro de UNB a phpBB aprovechamos para recordar cómo se puede acceder desde Pyhon a MySQL.

En nuestro caso el usuario solicitaba darse de alta, pero no utilizábamos el sistema del foro, por lo cual del usuario sólo sabíamos la dirección de correo electrónico.

Lo que tenemos que migrar es el nombre de usuario y la dirección de correo electrónico de registro, pero tenemos que hacer tres comprobaciones de datos que no existen en la base de datos nueva; la dirección de correo como nombre de usuario, la dirección de correo como dirección de email como email
registrado, el nombre de usuario como nombre de usuario.

Lo primero que hacemos es exportar los datos que necesitamos de la base de datos de UNB, para ello ejecutamos esta sentencia en MySQL:


mysql> SELECT  Name, RegEmail, Password  INTO outfile 'lista' FIELDS TERMINATED BY ';'from unb1_Users ;


Una vez que tenemos la lista de nombres la copiamos al directorio de trabajo donde tengamos el script migracion.py que es el script que vamos a utilizar para migrar los datos.

El script es el siguiente:

#!/usr/bin/env python

# importamos el modulo MySQLdb
import MySQLdb
# importamos el modulo string poder pasar a minusculas los strings
import string


# Definimos una funcion en la que definimos una consulta simple a la base de datos


def ConsultaSql(consulta, dato):
cursor.execute("SELECT "+consulta+" FROM phpbb_users WHERE "+consulta+"=\""+string.lower(dato)+"\"")
result=cursor.fetchone()
if (result):
return True
else:
return False

# Definimos la funcion en con la que relizaremos las inserciones pertinentes en la base de datos

def InsercionSql(nombre, correo, contras):
cursor.execute("SELECT user_id from phpbb_users")
numcolumnas=int(cursor.rowcount)
numid=int(numcolumnas)+1
print numid
cursor.execute("INSERT INTO phpbb_users(user_id, user_active, username, user_password, user_regdate, user_level, user_style, user_email) VALUES (%s,1,%s,%s,1194441299,0,8,%s)", (numid, nombre, contras, correo))
cursor.execute("INSERT INTO phpbb_user_group(group_id, user_id, user_pending) VALUES (5,%s,0)", (numid))
cursor.execute("INSERT INTO phpbb_user_group(group_id, user_id, user_pending) VALUES (6,%s,0)", (numid))


# Conexion a la base de datos
db = MySQLdb.connect(host="localhost", user="jose",passwd="pruebas",db="pruebas")

# Creamos un cursor
cursor=db.cursor()

# Abrimos el fichero donde tenemos los valores exportados de la base de datos
fichero=open("lista")

# Creamos una lista con las lineas del fichero
leerfichero=fichero.readlines()

# iteramos sobre la lista
for linea in leerfichero:
# Ponemos lo que extraemos en minusculas para tenerlo todo igual y suprimimos el salto de linea del final
# Ademas creamos una lista por linea que contiene los tres valores
lineasinfin=string.lower(linea.rstrip('\n')).split(";")

# Iteramos para ver que ninguno de los valores esta insertado en la base de datos, si no estan llamamos a la funcion de ejecucion
for elemento in lineasinfin:
if(ConsultaSql("user_email", elemento)):
break
elif (ConsultaSql("username", elemento)):
break
else:
InsercionSql(lineasinfin[0],lineasinfin[1],lineasinfin[2])



Para poder ejecutarlo necesitamos el módulo MySQLdb de Python que no viene por defecto en la distribución.

Vamos a explicar paso a paso el script:

 1 #!/usr/bin/env python
2
3 # importamos el modulo MySQLdb
4 import MySQLdb
5 # importamos el modulo string poder pasar a minusculas los strings
6 import string
7
8
9 # Definimos una funcion en la que definimos una consulta simple a la base de datos
10
11
12 def ConsultaSql(consulta, dato):
13 cursor.execute("SELECT "+consulta+" FROM phpbb_users WHERE "+consulta+"=\""+string.lower(dato)+"\"")
14 result=cursor.fetchone()
15 if (result):
16 return True
17 else:
18 return False



Obviamente en la primera línea llamamos al intérprete de Python y después en la línea 4 y 6 importamos los módulos que vamos a necesitar.

En la línea 12 definimos un función que va a necesitar que se le pasen dos valores. Esta función va a comprobar si el dato que hemos extraido del fichero está en la base de datos, en caso positivo devuelve verdadero, en caso negativo devuelve falso. La consulta la hemos realizado escapando las comillas para variable, en la siguiente función veremos que se puede incluir las variables en las sentencias SQL de la otra manera que permite Python.


 # Definimos la funcion en con la que relizaremos las inserciones pertinentes en la base de datos
21
22 def InsercionSql(nombre, correo, contras):
23 cursor.execute("SELECT user_id from phpbb_users")
24 numcolumnas=int(cursor.rowcount)
25 numid=int(numcolumnas)+1
26 print numid
27 cursor.execute("INSERT INTO phpbb_users(user_id, user_active, username, user_password, user_regdate, user_level, user_style, user_email) VALUES (%s,1,%s,% s,1194441299,0,8,%s)", (numid, nombre, contras, correo))
28 cursor.execute("INSERT INTO phpbb_user_group(group_id, user_id, user_pending) VALUES (5,%s,0)", (numid))
29 cursor.execute("INSERT INTO phpbb_user_group(group_id, user_id, user_pending) VALUES (6,%s,0)", (numid))



Definimos una función para insertar los datos necesarios. Una vez comparados los datos, insertamos los valores que necesitamos en los campos correspondientes. Aquí tenemos que pasar a la función los valores que vamos a insertar.

En la línea 24 contamos el número de columnas y luego en la 25 sumamos una, para poder poner el id correspondiente.
En la línea 27 podemos ver la otra manera de incluir las variables en las sentencias SQL, aunque tenemos que tener en cuenta una cosa, y es que aunque numid sea un entero, hay que llamarlo como si fuera un string, luego supongo que internamente se hace el cambio a la hora de insertar.


 # Conexion a la base de datos
33 db = MySQLdb.connect(host="localhost", user="jose", passwd= "pruebas" db="pruebas")
34 # creamos un cursor
35 cursor=db.cursor()
36
37 # Abrimos el fichero donde tenemos los valores exportados de la base de datos
38 fichero=open("lista")
39
40 # Creamos una lista con las lineas del fichero
41 leerfichero=fichero.readlines()



Creamos el cursor de MySQL, abrimos el fichero y metemos cada línea del fichero en una lista.

 # iteramos sobre  la lista
44 for linea in leerfichero:
45 # Ponemos lo que extraemos en minusculas para tenerlo todo igual y suprimimos el salto de linea del final
46 # Ademas creamos una lista por linea que contiene los tres valores
47 lineasinfin=string.lower(linea.rstrip('\n')).split(";")
48
49 # Iteramos para ver que ninguno de los valores esta insertado en la base de datos, si no estan llamamos a la funcion de ejecucion
50 for elemento in lineasinfin:
51 if(ConsultaSql("user_email", elemento)):
52 break
53 elif (ConsultaSql("username", elemento)):
54 break
55 else:
56 InsercionSql(lineasinfin[0],lineasinfin[1],lineasinfin[2])




Esta es la última parte, lo primero que hacemos es iterar sobre la lista para extraer cada línea.
Una vez extraida podemos ver en la línea 47 que ponemos todas los caracteres en minúscula, quitamos el fin de línea y creamos una nueva lista separando los datos que teníamos, pero eliminando el separador ";".

En la línea 50 volvemos a iterar, pero esta vez aplicamos las funciones con los datos obtenidos y de ese modo realizamos la inserción de datos.


Supongo que se puede hacer de otro modo, y seguramente más rápido, pero para mí ha sido una buena manera de familiarizarme un poco con el módulo MySQLdb.

08 noviembre 2007

Cómo migrar los usuarios de UNB forums a phpbb

(English Version)
Si tienes un UNB forum instalado con cantidad de usuarios y quieres cambiar el sistema a phpbb, te encontrarás con que la contraseña no funciona debido al sistema kmd5 en UNB.

Encontré este problema con nuestros foros, y estuve trabajando en ello, y finalmente creo que funciona, pero necesito probarlo, y probarlo...

Estos son los pasos que seguí para hacerlo

1.- Cambié el tamaño de la columna password en la tabla phpbb_users ejecutando la siguiente sentencia SQL:

 ALTER TABLE phpbb_users MODIFY user_password varchar(32);

2.- Cambié al directorio raíz de phpbb y abrí el fichero login.php. Ahí incluí la función unbCheckUserPassword del fichero session.lib.php de UNB forums. En login.php llamé a la función checkUserPassword.

function checkUserPassword($hashed, $stored)
{
// update old hashes
if (strlen($stored) == 34)
{
$stored = '{kmd5}' . $stored;
}

// compare passwords based on used hash method
if (substr($stored, 0, 6) == '{kmd5}')
{
// input password must be an MD5 hash
$stored = substr($stored, 6); // remove identifier
#$key = substr($stored, 0, 2);
#return $key . strtolower(md5($key . $hashed)) == $stored;

// retrieve key
$key = substr($stored, 16, 2);
// build keyed hash
$hash1 = strtolower(md5($key . $hashed));
$hash2 = substr($hash1, 0, 16) . $key . substr($hash1, 16);
return $hash2 == $stored;
}
return false;
}

3.- En la línea 124 cambié la condición. Antes del cambio la condición era:

if( (md5($password) == $row['user_password'] && $row['user_active'])


Ahora la condición es (la escribí en una línea):

if( (md5($password) == $row['user_password'] && $row['user_active']) || (checkUserPassword(md5($password),$row['user_password ']) && $row['user_active']))



4.-Cambié al directorio includes, ahí abrí usercp_register.php. He vuelto a incluir la función userCheckPassword. Aproximadamente en la línea 395 cambiamos la condición. La condición antigua era:

if ( $row['user_password'] == md5($password) ]



Ahora la condición es:

if ( ( checkUserPassword(md5($cur_password),$row['user_password'])!=1) xor ($row['user_password'] == md5($cur_password)))



Es un poco raro, pero tenemos que utilizar XOR porque si ambas condiciones son verdad, no es cierto para nosotros. Lo probé de esta manera, y aparentemente funciona.