Showing posts with label web programming. Show all posts
Showing posts with label web programming. Show all posts

Saturday, July 19, 2008

T-Mobile Address Manager export "Hack"

Edit: Thanks to yincrash for pointing out that they changed their namespace on this object to TMO.ABPORTAL.



My friend Candice got a 1st Gen iPhone on the cheap and needed to get her numbers from T-Mobile's new online Address Manager (TAB). It does syncing to and from a regular T-Mobile phone but the iPhone isn't a regular T-Mobile Phone. The app is new and they have a note about it not syncing changes made on the website to the phone yet and either by design or evil plotting there was no way to export the contacts.



My vocation to the rescue! They were using the prototype.js library to run the app and after some digging around I found the data store.
TMO.ABPORTAL.ABIHM.ContactManager is the object that manages the contacts' actions and the _datas property is an array of contact javascript objects. So in the firebug console I wrote some code to get the contacts and wrote a csv file to an empty div. I then took that div into Wordpad to get the lines to break correctly on Windows and did an import into Windows Address Book. The rest is history!



Here's the code I used:



var data = ["firstname,lastname,name,homeMobile,homePhone1,homePhone2,workMobile,workPhone1,workPhone2"];
TMO.ABPORTAL.ABIHM.contactManager._datas.each(function(person) {
var a = [];
a.push(person.firstname);
a.push(person.lastname);
a.push(person.name);
a.push(person.homeMobile);
a.push(person.homePhone1);
a.push(person.homePhone2);
a.push(person.workMobile);
a.push(person.workPhone1);
a.push(person.workPhone2);
data.push(a.join(","));
});
$('L_footer_pane').update(data.join('\r\n'));


Tuesday, May 13, 2008

Playing with the Struts 2 Dispatcher


Due to the nature of our permission handling on a project at work I am in need of a way to pass URLs in to the Struts dispatcher and get back the class name and method of the action to invoke (possibly the results as well...). See we have our classes implement a "SecurityAware" interface that returns an array of [OR'd] permission names required to view a page. We also have a permission based menu system that sometimes requires different permissions than the page the menu item points to. I had run into a problem in trying to find all those needed permissions between the database and the source code which was a lot of manual work. So you can see why I'd want to just pass in the URLs from the menu and get the action, call the security method and display the needed permissions for the resulting page.


What I did was start taking a trip through the Struts 2 source and the test classes for an idea of what was going on. I started at the FilterDispatcher since that's the one class that I define and is the starting point of my (any?) Struts2 applications.


The filterDispatcher creates a Dispatcher object. This seems to be the core configuration beast of the system. This has an ActionMapper injected into it. This is where my problems begin.


How are things injected into the FilterDispatcher since I'm "creating" it in the web.xml? There's a ConfigurationManager that is created inside that loads the struts config files and I've had luck printing out parameters that I've set in my struts.xml so I think it's loading correctly. What I'm now having trouble with is the ActionMapper. I'm playing with this in jRuby and I have no idea how to deal with Java5 Generics (I guess I could Google it...) so I took the route of just injecting my created actionMapper.


actionMapper = DefaultActionMapper.new
dispatcher.configurationManager.configuration.container.inject(actionMapper)


This does have an effect in that I can set struts.enable.SlashesInActionNames to true and then call actionMapper.slashesInActionNames? and have the result be true (it defaults to false, so there is a change).


I should mention that I'm running this code in the struts blank example app's WEB-INF/classes directory. I can create a MockServletRequest and pass in URLs that should and shouldn't work. It errors out appropriately when the URL doesn't end with ".action" and I can get it to parse the namespace portion correctly, but I'm having no luck with the Method. For example /example/Login_input.action should result in an ActionMapping with:

  • Name: Login_input

  • Namespace: /example

  • Method: input


Or at least that's what I'm expecting, but I never get anything for the method.


Here's my code so far.


require 'java'

import 'org.apache.struts2.dispatcher.Dispatcher'
import 'org.apache.struts2.dispatcher.FilterDispatcher'
import 'org.apache.struts2.dispatcher.mapper.DefaultActionMapper'

import 'org.springframework.mock.web.MockServletContext'
import 'org.springframework.mock.web.MockFilterConfig'
import 'org.springframework.mock.web.MockHttpServletRequest'
import 'org.springframework.mock.web.MockHttpServletResponse'


filterConfig = MockFilterConfig.new
servletContext = MockServletContext.new


dispatcher = Dispatcher.new(servletContext, {})
dispatcher.init
Dispatcher.instance = dispatcher

actionMapper = DefaultActionMapper.new
dispatcher.configurationManager.configuration.container.inject(actionMapper)


request = MockHttpServletRequest.new(servletContext, 'GET', '/example/other.action');
response = MockHttpServletResponse.new;

actionMapping = actionMapper.getMapping(request,dispatcher.configurationManager)
puts "Name: #{actionMapping.name}"
puts "Namespace: #{actionMapping.namespace}"
puts "Method: #{actionMapping.method}"
puts "Result: #{actionMapping.result}"