Mo Firouz
25Jan/122

Guice, Shiro 1.2 and Vaadin/GWT

Hello all.

Now you might - by now - know that I've started working on small new project. It's being secretively worked on in quiet corners, maybe the idea will die down, or maybe it'll grow to the energy of one of those raging jungle fires. Who knows right now, only time will tell... This step is the next piece of the puzzle, fueling the idea's "fire". Given that the work is for the development of commercial project, I can only reveal some of the code that ties the application together.

For the past month or so, I've been fighting to get Google Guice and Apache Shiro to work together. Now within this time, Shiro has been transitioning from 1.1 (without native Guice support) to 1.2 that allows for simpler and more convenient dependency injection with Guice. I could get Shiro to work through manually inject dependencies, but that was too much work. On top of all, my efforts would have been wasted given that 1.2 was just round the corner.

So, I gave in to the hard shoulder of the road and started working with 1.2-SNAPSHOTS - Yes, it wasn't one of my best decisions! However, now we have a 1.2 release and we can PARTAY! (sorry, just slightly happy!).

So for the sake of helping the community, and the thought of 'anyone out there?', I'm gonna share you some of the more straight forward code than the advice currently out there on the web (as on Stackoverflow for example). For a bit of background, this link is me trying desperately to get some answers.


So less talking, more coding.... Starting with the web.xml:

[web.xml]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
 
	<display-name>My App</display-name>
 
	<context-param>
		<description>Vaadin production mode</description>
		<param-name>productionMode</param-name>
		<param-value>false</param-value>
	</context-param>
 
	<filter>
		<filter-name>guiceFilter</filter-name>
		<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>guiceFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<listener>
		<listener-class>com.app.GuiceServletInjector</listener-class>
	</listener>
</web-app>

Now, your web.xml states that all requests should be answered through the 'GuiceServletInjector', and has to be filtered through the 'GuiceFilter'. So how does your 'GuiceServletInjector' look a like:

[GuiceServletInjector.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class GuiceServletInjector extends GuiceServletContextListener {
	private ServletContext servletContext;
 
	@Override
	public void contextInitialized(ServletContextEvent servletContextEvent) {
		servletContext = servletContextEvent.getServletContext();
		super.contextInitialized(servletContextEvent);
	}
 
	@Override
	protected Injector getInjector() {
		return Guice.createInjector(new ShiroConfigurationModule(servletContext), new GuiceServletModule());
	}
}

Now, be aware that any other injectors that you might want need to be initiated before your servlet module. In my case, it is the Shiro Configuration module that I have created:

[ShiroConfigurationModule.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ShiroConfigurationModule extends ShiroWebModule {
 
	@Inject
	public ShiroConfigurationModule(ServletContext servletContext) {
		super(servletContext);
	}
 
	@Override
	protected void configureShiroWeb() {
		try {
			bindRealm().to(ShiroBaseRealm.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
 
                addFilterChain("/**", ANON);
                addFilterChain("/lock/**", AUTHC_BASIC, config(PERMS, "no"));
	}
}

This configuration file basically acts as if you have a 'shiro.ini' file. The reason why I didn't like the '.ini' configuration is that I want to have the code-flexibility. Also, I want my database details to be stored in the classes in the '.jar' files rather than a configuration file in the '.jar' file.

Also something you might have noticed is the use of a custom realm, I called 'ShiroBaseRealm'. This acts as the main connector my database, although right now doesn't have much code in it. For the sake of clarity, here is the code:

[ShiroBaseRealm.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class ShiroBaseRealm extends AuthorizingRealm {
 
	HashedCredentialsMatcher matcher;
 
	public ShiroBaseRealm() {
		matcher = new HashedCredentialsMatcher();
		matcher.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
	}
 
	@Override
	public CredentialsMatcher getCredentialsMatcher() {
		return matcher;
	}
 
	@Override
	public boolean supports(AuthenticationToken token) {
		return true; // super.supports(token);
	}
 
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
 
		String username = upToken.getUsername();
 
		if (username == null) {
			throw new AccountException("Null usernames are not allowed by this realm.");
		}
		String password = "password";
		return new SimpleAuthenticationInfo(username, password, this.getName());
	}
 
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		if (principals == null) {
			throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
		}
		String username = (String) principals.fromRealm(getName()).iterator().next();
		Set roleNames = ImmutableSet.of();
		if (username != null) {
			roleNames = ImmutableSet.of("foo", "goo");
		}
		return new SimpleAuthorizationInfo(roleNames);
	}
 
}

And finally, the actual servlet module:

[GuiceServletModule.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class GuiceServletModule extends ServletModule {
	@Override
	protected void configureServlets() {
		super.configureServlets();
		filter("/*").through(GuiceShiroFilter.class);
 
		// bind to database....
 
		// once per session...
		bind(UIControllerService.class).to(GenericUIControllerServiceImpl.class).in(ServletScopes.SESSION);
		bind(Application.class).to(VaadinMainWindow.class).in(ServletScopes.SESSION);
 
		serve("/*").with(MyApp.class);
 
	}
}

 

Well, obviously this is just a starter to the Shiro world. I am personally planning to use AOP to 'lock-down' method calls within the code, since I am using Vaadin to create the website. Therefore I don't really want to check whether a user is authenticated to call this method or not, and therefore the '@RequiresAuthentication' comes very handy.

If you have any questions, let me know. But do also know that I am NOT an expert in this (yet!).

Good luck,

Mo.

Filed under: Mo Firouz 2 Comments
12Dec/110

iTunes Music Syncer For Android / USB

Hello.

A few days ago, I was in need of an app that could copy some music files from one location to another given a playlist. It also happened that those playlists where managed by iTunes. And before you judge me, my music player on mac is iTunes (on Windows is Winamp, on Linux is RhythmBox).

However, I somewhat hit head-on with a problem. There was no such app that would simply copy files given a playlist. So I thought, I should do the noble thing and write my own iTunes Music Syncer. Then a friend of mine (Karl, here I mention you!), suggest that more and more people would find this useful as they have android phones and manage their music through iTunes.

So here we are. Just for the sake of clarity, let me give a set of bullet points as what this app does and does not (currently) do:

  • It copies a set of files defined by a plain-text playlist.
  • Given the information available in the playlist file, it will generate Artist/Album/Song structure for your music.
  • You can define whatever folder you would like to copy music too.
  • It will skip duplicates and find missing songs.
  • It has a very minimalistic user interface which most probably won't change in the future. I like things that do minimal stuff.
  • You can either give it a true playlist, or a dummy playlist to copy all your iTunes music library.
  • If you want syncing to happen, always point the output to the same folder.
  • It does not rename the files themselves.
  • It will not do a two-way sync. This function is not possible due to the nature of the application. Don't ask for it!

Set of requirements:

  • Mentioned playlist MUST be generated through iTunes export function.
  • You need to have at least Java 1.6 Runtime Environment installed. Most sane people have this pre-installed anyways.
  • Enough disk space
  • Microsoft Windows or Apple Mac OS X 10.6+ (No Linux support, sorry!)
  • And most importantly, a little common sense.

How to use:

  • Generate your playlist. This needs to be a 'Plain Text' playlist generated through the iTunes export function (right-click on the playlist in iTunes).
  • Run the app.
  • Upon running, you are prompted with a window to select the playlist. Select the playlist!
  • Then another window to select your output folder. Recommended to use an empty folder.
  • You shall see a progress window. Wait until it finishes. If you cannot wait, press Quit and relaunch the app at a later time to continue the syncing process (point to the same output folder).
  • At the end, you shall see a summery window. Read it. Press OK to quit!
  • That's it!

Warnings:

  • This app is tested on Mac OS X. Not yet tested on Windows. Please be wary of this fact.
  • I am the sole developer of this app. However, I will not take any responsibility shall this app utterly mess up your computer, phone, both, or your life. You are responsible!
  • I will give this app the GPL license, but this may change in the future without notice.
  • Libraries used will have their very own licenses which I obviously accept, so should you!
  • By you downloading or linking this app, you will automatically accept the above terms.

Download:

If you found this application useful, just simply leave a comment!

Thanks,

Mo.

 

Filed under: Mo Firouz No Comments
Page 1 of 2112345...1020...Last »