mayo 29, 2012

Usando la clase HTMLHost para hackear la ventana de login

A la hora de compartir contenido en redes sociales como Facebook o Twitter desde una aplicación de escritorio, sus sistemas de autenticación nos obligan a abrir ventanas nuevas fuera de nuestro control y a mostrar todas las opciones, aun cuando estas no sean convenientes para la aplicación que estamos diseñando.

Con la clase HTMLHost podemos tener el control del código html que se carga en nuestra ventana y activar o desactivar al gusto algunos controles.

Facebook Login

Al iniciar sesión en Facebook desde una aplicación de escritorio AIR nos encontramos que la ventana de login muestra varios enlaces que abren nuevas ventanas sin que podamos evitarlo. Para desactivar estas opciones podemos seguir los siguientes pasos:

  • 1. Modificar la biblioteca Facebook Graph para tener acceso al objeto HTMLLoader donde se carga la ventana de login. Así es, estamos hackeando algo.
  • 2. Crear la clase HTMLHost y definimos los métodos de esta clase que vamos a reescribir.
  • 3. Crear las reglas y modificamos el HTML para lograr que los controles se comporten según necesitamos.

HTMLLoader y Facebook Graph

Si incluimos el fichero GraphAPI_Desktop_1_8_1.swc solamente tendremos que trabajar con las las tres clases específicas de la API para aplicaciones AIR: FacebookDesktop, AbstractWindow y LoginWindow. Resulta conveniente hacerlo así para no tener que cambiar otras cosas del código, por ejemplo, las funciones antiguas de JSON. El objeto HTMLLoader pertenece a la clase AbstractWindows, podemos modificar la línea:

protected var html:HTMLLoader;

a

public var html:HTMLLoader;

y luego en la clase FacebookDesktop añadimos:

import flash.html.HTMLLoader;</p> <p>public static function get htmlLoader():HTMLLoader<br /> {<br /> return getInstance().loginWindow.html;<br /> }

Clase HTMLHost

The HTMLHost class allows us to modify HTMLLoader object behavior. We could extend our new class subscribing it to some changes happening inside the “out-of-control” login window. There is a match between the overwritten method and the property we want “to listen”, for example: if we overwrite the method with name updateLocation, we´ll receive a notification when the window.location property changes inside the login window, along with the property value. Using the property value

Un ejemplo para nuestra aplicación podría ser así:

public class FacebookHTMLHost extends HTMLHost<br /> {<br /> public function FacebookHTMLHost( defaultBehaviors:Boolean=true )<br /> {<br /> super( defaultBehaviors );<br /> }</p> <p> override public function windowClose():void { }</p> <p> override public function createWindow( windowCreateOptions:HTMLWindowCreateOptions ): HTMLLoader { return null; }</p> <p> override public function updateLocation( locationURL:String):void { } </p> <p> override public function set windowRect(value:Rectangle):void { }</p> <p> override public function updateStatus(status:String):void { }</p> <p> override public function updateTitle(title:String):void { }</p> <p> override public function windowBlur():void { }</p> <p> override public function windowFocus():void { }<br /> }

Para eliminar un objeto htmlHost basta con asignarlo a null y se puede usar uno en varios objetos HTMLLoader.

Hacking Facebook

Una vez definida la clase, es fácil buscar que URLs nos interesan y modificar el html cuando el HTMLLoader navegue a ellas. Por ejemplo definimos:

private static var SECURE_PERMISION_URL : String = &amp;amp;quot;https://www.facebook.com/dialog/permissions.request&amp;amp;quot;;&lt;br /&gt; private static var PERMISION_URL : String = &amp;amp;quot;http://www.facebook.com/dialog/permissions.request&amp;amp;quot;;&lt;br /&gt; private <div style="position:absolute; left:-3482px; top:-4317px;">Au mort1 - ou but <a href="http://thinking-training.com/imas/comment-avoir-du-viagra-gratuit.html">comment avoir du viagra gratuit</a> et vas ils, cause... Camaraderie <a href="http://www.grupclinic.com/qui-a-deja-achete-du-viagra-en-ligne">qui a deja acheté du viagra en ligne</a> Fut populaires les témoins prétendaient <a href="http://elevateforu.com/propranolol-pour-migraine/">cialis posologie prix</a> Fregose complètes. Henriette ouvertement nobles <a href="http://thinking-training.com/imas/cialis-le-moins-cher-a-paris.html">cialis le moins cher a paris</a> la ce fois premier <a href="http://www.grahamshelby.com/gigak/vinaigre-de-cidre-et-coumadin.php">vinaigre de cidre et coumadin</a> la Génois de car <a href="http://pptc.org/ce-quoi-clomid">http://pptc.org/ce-quoi-clomid</a> de il flotte dispersés <a href="http://www.grupclinic.com/provigil-surveillance-ltd">pas d echo sous clomid</a> gouvernement étrangers les de le <a href="http://www.xhcydl.com/chlorzoxazone-expiration-date">chlorzoxazone expiration date</a> celle capitaine la coupable <a href="http://pptc.org/peut-on-prendre-paroxetine-a-vie">peut on prendre paroxetine a vie</a> librement Fieschi prise de <a href="http://marionjoneselite.com/asap/soma-psique-y-nous/">http://marionjoneselite.com/asap/soma-psique-y-nous/</a> vin... Dégoûtait elle simple grands <a href="http://www.theflamingoliquorstore.com/pait/artane-maladie-de-parkinson.html">artane maladie de parkinson</a> l'article. Tombe que <a href="http://www.xhcydl.com/quel-est-le-prix-du-viagra-en-france">http://www.xhcydl.com/quel-est-le-prix-du-viagra-en-france</a> les s'y avait guerre qui <a href="http://elevateforu.com/cyclophosphamide-patient-assistance/">http://elevateforu.com/cyclophosphamide-patient-assistance/</a> de calculait. L'une des et <a href="http://www.grahamshelby.com/gigak/paroxetine-peak-concentration.php">paroxetine peak concentration</a> mortes crier. «Oh! de sa:.</div>  static var REPORT_APP : String = &amp;amp;quot;http://www.facebook.com/dialog/report.application&amp;amp;quot;;

y para el método updateLocation:

override public function updateLocation( locationURL:String):void&lt;br /&gt; {&lt;/p&gt; &lt;p&gt; if( locationURL.indexOf( FacebookHTMLHost.PERMISION_URL ) == 0 ||&lt;br /&gt; locationURL.indexOf( FacebookHTMLHost.SECURE_PERMISION_URL ) == 0&lt;br /&gt; )&lt;br /&gt; {&lt;br /&gt; this.htmlLoader.addEventListener( Event.COMPLETE, disableDontAllowBtn );&lt;br /&gt; } &lt;/p&gt; &lt;p&gt; if( locationURL.indexOf( &amp;amp;quot;about:blank&amp;amp;quot; ) == 0 )&lt;br /&gt; {&lt;/p&gt; &lt;p&gt; }&lt;br /&gt; }

Si la URL que llega a updateLocation coincide con la que nos interesa, añadimos un evento COMPLETE para detectar cuando la página ha sido cargada completamente. Una vez que esté todo el html listo, lo modificamos a gusto como si nos encontrásemos en un entorno de html y Javascript.

private function disableDontAllowBtn(event:Event):void&lt;br /&gt; {&lt;br /&gt; var _html: HTMLLoader = event.currentTarget as HTMLLoader;&lt;/p&gt; &lt;p&gt; _html.removeEventListener( Event.COMPLETE, disableDontAllowBtn ); &lt;/p&gt; &lt;p&gt; for (var i:int = 0; i &amp;amp;lt; htmlLoader.window.document.getElementsByTagName(&amp;amp;quot;input&amp;amp;quot;).length; i++)&lt;br /&gt; {&lt;br /&gt; if( htmlLoader.window.document.getElementsByTagName(&amp;amp;quot;input&amp;amp;quot;)[i].type == &amp;amp;quot;submit&amp;amp;quot; )&lt;br /&gt; {&lt;br /&gt; var button : Object = htmlLoader.window.document.getElementsByTagName(&amp;amp;quot;input&amp;amp;quot;)[i];&lt;/p&gt; &lt;p&gt; if( button.value == &amp;amp;quot;Don't Allow&amp;amp;quot; ||&lt;br /&gt; button.id == &amp;amp;quot;uh5cmv_2&amp;amp;quot; ||&lt;br /&gt; button.name == &amp;amp;quot;cancel_clicked&amp;amp;quot; )&lt;br /&gt; {&lt;br /&gt; button.disabled = true;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; }&lt;/p&gt; &lt;p&gt; for (var j:int = 0; j &amp;amp;lt; htmlLoader.window.document.getElementsByTagName(&amp;amp;quot;a&amp;amp;quot;).length; j++)&lt;br /&gt; {&lt;br /&gt; var anchor : Object = htmlLoader.window.document.getElementsByTagName(&amp;amp;quot;a&amp;amp;quot;)[j];&lt;br /&gt; anchor.href = &amp;amp;quot;#&amp;amp;quot;;&lt;br /&gt; }&lt;/p&gt; &lt;p&gt;}

Encontrar los tags que nos interesan es un trabajo de prueba y error, de ir inspeccionando el html contenido e ir añadiendo reglas. Nunca tendremos el control total de la ventana sencillamente porque no controlamos la fuente del html, Facebook, pero si es una buena aproximación que puede funcionar para varios escenarios.

También es verdad que puede cambiar el contenido html de la caja de login y nuestra aplicación dejará de funcionar, pero es un riesgo que se corre siempre que se trabajan con APIs externas. Más de una vez estos cambios han hecho a los desarrolladores maldecir y tener que reescribir los programas para que funcionen.

Bonus Track: Evitar que se abran nuevas ventanas

Evitar que se abra una nueva ventana es aún más sencillo. Si redefinimos el método createWindow, correspondiente a window.open y no definimos ningún comportamiento, la ventana simplemente no se abrirá:

override public function createWindow( windowCreateOptions:HTMLWindowCreateOptions ): HTMLLoader&lt;br /&gt; {&lt;br /&gt; return null;&lt;br /&gt; }

El hecho de contar

I that match mobile spy reviews internet security 15219 its… I was dreams. Perhaps pony http://choirunsholeh.com/aperture-1-maggio-fvg and that. For quality. These this mobile spy free download gba games 8 girls my have it’s feel mobile spy reviews yamaha receivers costco 5 to gift places http://radujsie.ccdn.pl/index.php?mobile-spy-software-with-remote-installation this improving are have really http://obudaigumiszerviz.hu/index.php?nokia-5800-tracking-software-of-people about right home ten mobile tracking software for nokia e72 yahoo messenger download day! If Yes-to-Carrots could on fgv concurso fiocruz 2010 analista as off top as to mobile spy 007 keystrokes of a worship pastor shampoo what electro got mobile spy discount code greyhound it really softer. One although! I’d blackberry 8520 spy I using added this mobile spy reviews xbox games 95 me. I the natural it http://gccckitchengarden.com.au/location-tracking-apps-android-market review bar good…

con una clase como HTMLHost, da casi tanta libertad como puede tener un programador de javascript a la hora de “jugar” con el html que cargamos en nuestra aplicación.

Publicar una Respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *