[cpif] r187 - in trunk: . backend frontend-web frontend-web/skins/default
svn at argo.es
svn at argo.es
Fri Jun 22 20:47:04 CEST 2007
Author: jcea
Date: Fri Jun 22 20:47:00 2007
New Revision: 187
Log:
Los usuarios ya puede ver su propio perfil, cambiar
su clave y, lo más importante, especificar servidores OpenID!!.
Added:
trunk/frontend-web/url_perfil.py
- copied, changed from r180, /trunk/frontend-web/url_logout.py
trunk/frontend-web/url_perfil_POST.py
- copied, changed from r185, /trunk/frontend-web/url_nuevo_usuario_POST.py
Modified:
trunk/TODO
trunk/backend/database.py
trunk/frontend-web/skins.py
trunk/frontend-web/skins/default/link_logout.html
trunk/frontend-web/url_nuevo_usuario_POST.py
Modified: trunk/TODO
==============================================================================
--- trunk/TODO (original)
+++ trunk/TODO Fri Jun 22 20:47:00 2007
@@ -137,3 +137,10 @@
ejemplo, no se deberia poder abrir un hilo con un titulo
excesivamente largo o de mas de una linea.
+- 20070622: FRONTAL WEB: Hacer "sanity check" de los datos que
+ se acaban mostrando al usuario. Por ejemplo, su propio
+ nombre de usuario o sus servidores OpenID.
+
+ Esto es especialmente importante cuando el "master" visualiza
+ un perfil, ya que se puede provocar un XSS en la cuenta "master".
+
Modified: trunk/backend/database.py
==============================================================================
--- trunk/backend/database.py (original)
+++ trunk/backend/database.py Fri Jun 22 20:47:00 2007
@@ -88,7 +88,24 @@
return None
-def usuario_add(conn,nick,datos,clave=None,OpenIDs=None) :
+def usuario_update(conn,nick,clave=None,OpenIDs=None) :
+ root=conn.get_root()
+ usuarios=root["usuarios"]["usuarios"]
+
+ usuario=usuarios.get(normaliza_nick(nick))
+ assert usuario
+
+ if clave :
+ usuario["clave"]=clave
+
+ if OpenIDs!=None :
+ old_OpenIDs=usuario["OpenID"]
+ if old_OpenIDs!=OpenIDs : # Solo grabamos si ha habido cambios
+ old_OpenIDs.clear() # Este tipo es persistente, asi que lo reutilizamos
+ old_OpenIDs.update(OpenIDs)
+
+
+def usuario_add(conn,nick,datos,clave=None,OpenIDs=set()) :
from durus.btree import BTree
from durus.persistent_dict import PersistentDict
from durus.persistent_set import PersistentSet
Modified: trunk/frontend-web/skins.py
==============================================================================
--- trunk/frontend-web/skins.py (original)
+++ trunk/frontend-web/skins.py Fri Jun 22 20:47:00 2007
@@ -44,7 +44,8 @@
'/LOGIN': ['login'],
'/error': [],
'/stop': [],
- '/nuevo_usuario_POST': []
+ '/nuevo_usuario_POST': [],
+ '/perfil_POST': [],
}
import os
Modified: trunk/frontend-web/skins/default/link_logout.html
==============================================================================
--- trunk/frontend-web/skins/default/link_logout.html (original)
+++ trunk/frontend-web/skins/default/link_logout.html Fri Jun 22 20:47:00 2007
@@ -1 +1 @@
-<a href="%(link_auth)s">LOGOUT (%(user)s)</a>
+<a href="%(link_auth)s">LOGOUT</a> (<a href="/perfil">%(user)s</a>)
Modified: trunk/frontend-web/url_nuevo_usuario_POST.py
==============================================================================
--- trunk/frontend-web/url_nuevo_usuario_POST.py (original)
+++ trunk/frontend-web/url_nuevo_usuario_POST.py Fri Jun 22 20:47:00 2007
@@ -38,11 +38,21 @@
OpenID=cuerpo.getfirst("OpenID%d" %i)
if OpenID : # Comprobamos el caso de campos inexistentes
OpenID=OpenID.strip()
- if OpenID : OpenIDs.add(OpenID)
+ if OpenID :
+ if '"' in OpenID : # XSS
+ pagina.load_url(["error"])
+ pagina.load_dict({"generic_message": "<h1>Caracteres extraños en los servidores OpenID</h1>"})
+ return pagina.web()
+ OpenIDs.add(OpenID)
if not (nick and clave1 and clave2) :
pagina.load_url(["error"])
pagina.load_dict({"generic_message": "<h1>No puedes dejar ningun campo no opcional en blanco</h1>"})
+ return pagina.web()
+
+ if '"' in nick :
+ pagina.load_url(["error"])
+ pagina.load_dict({"generic_message": "<h1>Caracteres extraños en el nombre de usuario</h1>"})
return pagina.web()
if clave1!=clave2 :
Copied: trunk/frontend-web/url_perfil.py (from r180, /trunk/frontend-web/url_logout.py)
==============================================================================
--- /trunk/frontend-web/url_logout.py (original)
+++ trunk/frontend-web/url_perfil.py Fri Jun 22 20:47:00 2007
@@ -2,8 +2,48 @@
from globales import monitor
-def gestiona_url(handler,path,usuario) :
- if len(path)!=1 : return None
- # Para borrar una cookie hay que mandarla con una fecha en el pasado.
- return (302,{"Set-Cookie":"cpif_auth=X; path=/; expires=Thu, 01-01-1970 01:00:00 GMT","Location":"/"},"")
+ at monitor
+def gestiona_url(conn,handler,path,usuario) :
+ if not usuario : # Acceso anonimo
+ return None
+
+ l=len(path)
+ if l==1 :
+ usuario_pedido=usuario
+ elif l==2 :
+ usuario_pedido=path[1]
+ else :
+ return None
+
+ import database
+ usuario_pedido_normalizado=database.normaliza_nick(usuario_pedido)
+ if usuario!="master" :
+ if database.normaliza_nick(usuario)!=usuario_pedido_normalizado :
+ return None
+
+ root=conn.get_root()
+ u=root["usuarios"]["usuarios"].get(usuario_pedido_normalizado)
+ if not u :
+ return None
+
+ texto=["<tr><td>Usuario:</td><td>%s</td></tr>" %usuario_pedido]
+ texto.append('<tr><td>Clave nueva:</td><td><input type="password" name="clave1" size="25" value="" /></td></tr>')
+ texto.append('<tr><td>Confirma clave nueva:</td><td><input type="password" name="clave2" size="25" value="" /></td></tr>')
+ OpenIDs=list(u["OpenID"])+["","","","",""] # Padding
+ texto.append('<tr><td>Servidores OpenID:</td><td><input type="text" name="OpenID1" size=55 value="%s" /></td></tr>' %OpenIDs[0])
+ texto.append('<tr><td align=right>(opcionales)</td><td><input type="text" name="OpenID2" size=55 value="%s" /></td></tr>' %OpenIDs[1])
+ for i,j in zip([3,4,5],OpenIDs[2:]) :
+ texto.append('<tr><td> </td><td><input type="text" name="OpenID%d" size=55 value="%s" /></td></tr>' %(i,j))
+
+ return (200,{"Content-Type":"text/html; charset=utf-8"},"""
+<html>
+<head><title>Perfil - %s</title></head>
+<body>
+<form action="/perfil_POST/%s" method="post" enctype="multipart/form-data">
+<table>
+%s
+<tr><td colspan=2 align=right><input class="form-element" type="submit" name="submit" value="Cambia perfil"/></td></tr>
+</table>
+</body>
+</html>""" %(usuario_pedido,usuario_pedido,"\r\n".join(texto)))
Copied: trunk/frontend-web/url_perfil_POST.py (from r185, /trunk/frontend-web/url_nuevo_usuario_POST.py)
==============================================================================
--- /trunk/frontend-web/url_nuevo_usuario_POST.py (original)
+++ trunk/frontend-web/url_perfil_POST.py Fri Jun 22 20:47:00 2007
@@ -5,14 +5,20 @@
@monitor
def gestiona_url(conn,handler,path,usuario) :
if not usuario : # Acceso anonimo
- import url_LOGIN
- return url_LOGIN.gestiona_url(handler,path,usuario)
+ return None
- if len(path)!=1 : return None
+ if len(path)!=2 : return None
+
+ import database
+ usuario_pedido=path[1]
+ usuario_pedido_normalizado=database.normaliza_nick(usuario_pedido)
+
+ if (usuario!="master") and (usuario_pedido_normalizado!=database.normaliza_nick(usuario)) :
+ return None
import skins
pagina = skins.Skin(path,usuario)
- pagina.load_dict({"page_title": "cpif - Alta exitosa"})
+ pagina.load_dict({"page_title": "cpif - Cambio de perfil exitoso"})
if usuario!="master" :
pagina.load_url(["error"])
@@ -22,15 +28,11 @@
import cgi
ctype,pdict=cgi.parse_header(handler.headers.getheader('content-type'))
cuerpo=cgi.FieldStorage(fp=handler.rfile,headers=handler.headers,environ={'REQUEST_METHOD':'POST'},keep_blank_values=1)
- nick=cuerpo.getfirst("usuario")
clave1=cuerpo.getfirst("clave1")
clave2=cuerpo.getfirst("clave2")
- if not (nick and clave1 and clave2) : # Comprobamos el caso de campos inexistentes
- pagina.load_url(["error"])
- pagina.load_dict({"generic_message": "<h1>No puedes dejar ningun campo no opcional en blanco</h1>"})
- return pagina.web()
+ if clave1==None or clave2==None : # Comprobamos el caso de campos inexistentes
+ return None
- nick=nick.strip()
clave1=clave1.strip()
clave2=clave2.strip()
OpenIDs=set()
@@ -38,12 +40,12 @@
OpenID=cuerpo.getfirst("OpenID%d" %i)
if OpenID : # Comprobamos el caso de campos inexistentes
OpenID=OpenID.strip()
- if OpenID : OpenIDs.add(OpenID)
-
- if not (nick and clave1 and clave2) :
- pagina.load_url(["error"])
- pagina.load_dict({"generic_message": "<h1>No puedes dejar ningun campo no opcional en blanco</h1>"})
- return pagina.web()
+ if OpenID :
+ if '"' in OpenID : # XSS
+ pagina.load_url(["error"])
+ pagina.load_dict({"generic_message": "<h1>Caracteres extraños en los servidores OpenID</h1>"})
+ return pagina.web()
+ OpenIDs.add(OpenID)
if clave1!=clave2 :
pagina.load_url(["error"])
@@ -51,13 +53,13 @@
return (pagina.web())
import database
- if database.usuario_verifica(conn,nick=nick) :
+ if not database.usuario_verifica(conn,nick=usuario_pedido) :
pagina.load_url(["error"])
- pagina.load_dict({"generic_message": "<h1>El usuario ya existe</h1>"})
+ pagina.load_dict({"generic_message": "<h1>El usuario NO existe</h1>"})
return (pagina.web())
- database.usuario_add(conn,nick,None,clave=clave1,OpenIDs=OpenIDs)
+ database.usuario_update(conn,usuario_pedido,clave=clave1,OpenIDs=OpenIDs)
- pagina.load_dict({"generic_message": "<h1>Alta exitosa</h1>"})
- return (pagina.web())
+ pagina.load_dict({"generic_message": "<h1>Cambio de perfil exitoso</h1>"})
+ return pagina.web()
More information about the cpif
mailing list