09 December 2009

Mohana- the witch of bring-a-thing

No comments:
This week we were asked something to bring a thing for "Bring A Thing", a kind of charity activity at work.
I brought a kind of jack in the box witch. Then I was asked to write a  story about it.
I thing it got out pretty well and I wanted to share it with you
To fully understand the story you should watch South Park , listen to some Manowar and live in Romania. It is still funny if you haven't done any of this, but...

Here it is:

Once upon a time in the land of far away yet so close you could feel it lived little Timmy.
He was a handicapped kid walking around in his wheel chair and singing Abba all day.
Timmy’s life was quite boring and ordinary, except when playing tanki online. He was a true champion then.
One day his parents wanted to surprise Timmy. So they sent little Timmy to leave with aunt whom he had never seen or heard of, Florgonzola.
Oh boy, finally an adventure, thought the child.
And finally he arrived. The weather was not so nice. It was autumn and raining, but hey, the tickets were cheaper because it was off-season.
So T is now with his ugly, quite stupid aunt. No adventure here, disappointed.
But wait, there is a forest near by. So, putting his off-road tires on his wheel chair the boy sets up for a quest.
In the middle of the forest there was an old house, seemed quite deserted.
The boy rushed in. After an hour he finally made it in to find an empty poor house.
“I’ll come at night, there must be a ghost here, or at least a spider, or a possessed squirrel, or maybe the wind will blow through the window to make buhuhu”. So the boy went every night, but still nothing special.
So the sixth night he arrived at his aunt home yet again disappointed, with his off-road tires torn apart by the sharp rocks of reality.
He entered the house to find what?
Florgonzola had transformed into an uglier, stupider witch, making soup out of weed and a bleeding deer leg.
“Come in, welcome desert”, she said. The boy understood that it made sense, it was also the sixth hour and the sixth minute, almost as much as some presidency lasted in some countries.
The boy was now terrified. He started to cry and swirl around until his tires caught fire. Then he decided to call his friends.
So he started his mp3 player and the “kings of metal” appeared from their kingdom of steel.
Using their sharp minds and their powerful guitars they enslaved the witch. Their music was not so good, but at least they were loud.
With her last words she promised that if she were to live she will only do good and change her name and looks to more nicer things.
The kings accepted with their kind minds.
Florgonzola was baptized under the sign of Odin all-powerful. Now she is named “MOHANA”. The kings of metal were pleased with yet another successful mission and the boy was given a steel horse called Pegus (because Pegas was a bike).
But she was still punished to live in a box.

From time to time she appears from the box to scare the bad thoughts and the bad enchantments around people, bringing luck and fortune.

BTW
Did you hear about the witch who was ashamed of her long black hair?
She always wore long gloves to cover it up.


18 November 2009

Ways to map and query many-to-many in GORM

3 comments:
I played with many-to-many relations in grails and found some interesting ways to work with them.
First the domain definitions.
For the purpose of this demo I chose the classic example with books and authors. A book may have many authors and an author may have many books.

class Author {
String name
}

class Book {
String name
}

What I consider the silliest way to define your domains I found here http://www.grails.org/Many-to-Many+Mapping+without+Hibernate+XML
They suggest mapping the join table using a domain object and creating the links by hand.
On 'books and authors' it would look like

class Book {
String name
static hasMany = [ memberships: Membership]

List authors() {
return memberships.collect {it.author}
}

List addToAuthors(Author author) {
Membership.link(this, author)
return authors()
}

List removeFromAuthors(Author author) {
Membership.unlink(this, author)
return authors()
}
}

class Author {
String name
static hasMany = [memberships: Membership]

List books() {
return memberships.collect {it.book}
}

List addToBooks(Book book) {
Membership.link(book, this)
return books()
}

List removeFromBooks(Book book) {
Membership.unlink(book, this)
return books()
}
}

class Membership {
Book book
Author author
static Membership link(book, author) {
def m = Membership.findByBookAndAuthor(book, author)
if (!m) {
m = new Membership()
book?.addToMemberships(m)
author?.addToMemberships(m)
m.save()
}
return m
}

static void unlink(book, author) {
def m = Membership.findByBookAndAuthor(book, author)
if (m) {
book?.removeFromMemberships(m)
author?.removeFromMemberships(m)
m.delete()
}
}
}

While this works it doesn't seam very elegant to me.
So, moving on, I found a better way to do it.

class Author {
String name

static hasMany = [books:Book]
}

class Book {
String name

static belongsTo = Author
static hasMany = [authors: Author]
}

This seems the best way. Or you could use hibernate annotations, but I won't treat that.
Now let's see how we can query these.
Let's say I want to get all the books written by an author.
First dynamic finders. This is done in 2 steps:

def author = Author.findByName(a_Name)
def books = author ? Book.findAllByAuthor(author) : []

With Hql it would look something like:

Book.executeQuery("from Book as b join b.authors a where a.name = :name order by b.name", [name: a_Name, max: max, offset: offset])
Book.findAll("from Book as b join b.authors a where a.name = :name order by b.name desc", [name: a_Name, max: max, offset: offset]);

This returns a list of arrays containing book and author
To get only the books use:

Book.executeQuery("select b from Book as b join b.authors a where a.name = :name order by b.name", [name: a_Name, max: max, offset: offset])

Finally, using criteria:

def criteria = Book.createCriteria()
def books = criteria.list {
authors {
eq('name', a_Name)
}
maxResults(max)
firstResult(offset)
order("name", "asc")
}

So these are some ways to query many-to-many relations with gorm, also using paging.
Hope it was helpful.

10 November 2009

JSecurity and active directory in grails

No comments:
This was done as a way to force domain users to log in before using the applications.
The old implementation used the jcifs library with jetty, but after upgrading to glashfish, jcifs started to fail randomly, especially when the application was accessed using IE.
And, after reading on their web site that the httpfilter is no longer supported, I started looking for free alternatives to Jcifs.
On the JSecurity plugin home it said it works with ldap, but the configuration they gave seemed complicated and I didn't really get it.
On the other hand I found this nice blog entry of how to use java/jndi and active directory.
http://mhimu.wordpress.com/2009/03/18/active-directory-authentication-using-javajndi/

This is how o put them together:

1. install the jsecurity plugin in your grails app

grails install-plugin jsecurity


2. generate the ldap realm and the auth controller. This comes default with jsecurity.

grails create-ldap-realm
grails create-auth-controller


3. Create a filter to redirect all the anonymous request to the login.
It might look like this and should be placed in your-app/grails-app/conf

public class SecurityADFilters {

def filters = {
loginCheck(controller: '*', action: '*') {
before = {
if (controllerName == "auth") return true
accessControl { true }
}

}
}
}


4. Modify the generated JsecLdapRealm based on the example above. It could look like this. This is a mock, some lines of code can be removed, if you don't need to get info about the user.


class JsecLdapRealm {
static authTokenClass = org.jsecurity.authc.UsernamePasswordToken

def grailsApplication

def authenticate(authToken) {
log.info "Attempting to authenticate ${authToken.username} in LDAP realm..."
def username = authToken.username
def password = new String(authToken.password)

// Get LDAP config for application. Use defaults when no config
// is provided.
def appConfig = grailsApplication.config
def ldapHost = appConfig.ldap.ldapHost ?: ["ldap://localhost:389/"]
def searchBase = appConfig.ldap.searchBase ?: ""
def domain = appConfig.ldap.domain ?: ""
def usernameAttribute = appConfig.ldap.username.attribute ?: "uid"
def skipAuthc = appConfig.ldap.skip.authentication ?: false
def skipCredChk = appConfig.ldap.skip.credentialsCheck ?: false
def allowEmptyPass = appConfig.ldap.allowEmptyPasswords != [:] ? appConfig.ldap.allowEmptyPasswords : true

// Skip authentication ?
if (skipAuthc) {
log.info "Skipping authentication in development mode."
return username
}

// Null username is invalid
if (username == null) {
throw new AccountException("Null usernames are not allowed by this realm.")
}

// Empty username is invalid
if (username == "") {
throw new AccountException("Empty usernames are not allowed by this realm.")
}

// Allow empty passwords ?
if (!allowEmptyPass) {
// Null password is invalid
if (password == null) {
throw new CredentialsException("Null password are not allowed by this realm.")
}

// empty password is invalid
if (password == "") {
throw new CredentialsException("Empty passwords are not allowed by this realm.")
}
}

String[] returnedAtts = ["sn", "givenName", "mail"];
String searchFilter = "(&(objectClass=user)(sAMAccountName=" + username + "))";

//Create the search controls
SearchControls searchCtls = new SearchControls();
searchCtls.setReturningAttributes(returnedAtts);

//Specify the search scope
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapHost);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, username + "@" + domain);
env.put(Context.SECURITY_CREDENTIALS, password);

LdapContext ctxGC = null;
try {
ctxGC = new InitialLdapContext(env, null);
//Search objects in GC using filters
NamingEnumeration answer = ctxGC.search(searchBase, searchFilter, searchCtls);
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
Attributes attrs = sr.getAttributes();
Map amap = null;
if (attrs != null) {
amap = new HashMap();
NamingEnumeration ne = attrs.getAll();
while (ne.hasMore()) {
Attribute attr = (Attribute) ne.next();
amap.put(attr.getID(), attr.get());
}
ne.close();
}
if (amap != null) return username
else return false
}
}
catch (NamingException ex) {
ex.printStackTrace();
}
}
}


5. Notice that above we are using some properties from appConfig so we shall add them. In grails-app/conf/Config.groovy add

// configure the ldap realm

ldap.domain = 'domain'
ldap.ldapHost = 'ldap://ldaphost'
ldap.searchBase = 'DC=***,DC=***' //or whatever is suitable for you

ldap.skip.authentication = false
ldap.skip.credentialsCheck = false
ldap.allowEmptyPasswords = false

//consult your LDAP admin

jsecurity.authentication.strategy = new org.jsecurity.authc.pam.AtLeastOneSuccessfulModularAuthenticationStrategy()


That is about it. I hope I did not forget anything.
Now every time you access the application you will have to log in using your domain account.

09 November 2009

Alternate way to run/debug Griffon applications from an IDE

No comments:
This is a way I use to to debug my griffon apps since before ide support. I am using this with idea 8, but I think it can be used with every ide. I think Eclipse can run griffon apps like this.
I was looking at the new support from IntelliJ and Netbeans and it looks great. But I think the way I am going to describe also has benefits.

Let's begin from scratch.
So these are the steps:
1. Create an empty project in Idea.

2. Create your griffon application somewhere on the hard drive.

griffon create-app demo1

Ok, now we have an empty project and an empty app.

3. We will add the app in idea as a java module.

On the next screen we choose not to create a source directory. Click next, do not add any facets and finish.

4.Next we set up the sources folders for our project. It should look like in the picture. The blue folders are sources. The green one are test sources.



5. Let's add the griffon libraries to our module. Basically what I do here is add all the jars from the folders containing jars from %GRIFFON_HOME%. These one are the ones highlighted below
Also add the groovy facet will add the groovy libraries.

In the end it should look like this:


6. Now you should be able to compile your code. The code will be compiled somewhere on the drive, probably in the global path for that project. Find that place and copy application.properties from the module root (application folder) there. In griffon 1.x this was not necessary.

7. Now we create a run configuration
Create a Run/Debug Configuration of type application.
It should look similar to the one below


The main thing here is to set griffon.application.SwingApplication as "Main Class". In griffon 1.x this was griffon.application.SingleFrameApplication. I guess you can use that too.

You are done. Now you can run the app from the run button in Idea. Debug works also. And You can also use the wonderful hot swap to recompile your controllers or classes. I think it doesn't work for views.

If you use the basic idea behind this steps, I guess you can run/debug griffon using any IDE.

Simple, right ?