Monday, July 7, 2014

First Android Application


This application connects to TestTrack (defect tracker) via a SOAP to REST bridge I created in order to pull the teams current Defects.  TestTrack only supports SOAP and Android does not play very well with SOAP... hence the need for a converter.

Users with the highest number of defects are listed first.    I used "Spring for Android" for the REST components.  The view shown is using an ExpandableListAdapter.  The two tabs on top were done using a TabHost.  

I am using Jackson for all JSON processing.  REST requests are done by using an AsyncTask in order to keep Android happy since it will crash with network latency issues that are not in the background. 

Having already done many Swing applications, I am amused (and quite happy) at how similar an Android application (generally speaking) is to create as a Swing app.  



Saturday, January 19, 2013

Using Django's auth user data from a client.


I currently have a project where I want to re-use the Django auth mechanism with a Java client application.  This will prevent duplicating data and will allow individuals to add users via the Django admin while also utilizing the same authentication data with the Java client.

The idea is for the client software and Django to interoperate on the same table data that will also be updated or added too by the Java client application.  The changes to the Django database need to be cross compatible when changes are made by either Django or the Java/client application.

While exploring this task I came to the realization that Django 4+ has changed the SHA encryption level.  In short, do not use the code example in this post for anything other than Django 1.3.x.

Django stores a random salt and hash of a users password in the auth_user table password column.

Here is an example from the password column of auth_user:
sha1$983483$25e5ec9766fc5c48661aeec78085012166c9be8d

We simply need to feed the random salt (the value after first $) and hashed password (value after second $) in the exact same order as Django expects to determine whether or not the supplied password and salt match the hash kept in the Django database.   With my client being written in Java, so is the hash checking code.

The example below will return the hash in hex which can be used to match against the stored hash value in the Django database.  Hashes are typically represented in hex because the raw value is binary.

Two arguments are passed.  The first is password, the second is the random salt. After substituting these values into the example the output will match the hash kept in the Django auth_user table of your database.

The client operating on this data needs to select the user ID in the auth_table, retrieve the salt and hash, and pass these into the code below to determine whether or not the password is valid by comparing the original hash to the returned hash.
 



import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHAHash {
    public static String getHexHash(String password, String salt){

        StringBuilder saltPass = new StringBuilder();
        saltPass.append(salt);
        saltPass.append(password);

        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        if (md != null) {
            md.update(saltPass.toString().getBytes());
        }

        byte byteData[] = new byte[0];
        if (md != null) {
            byteData = md.digest();
        }

        StringBuilder hexString = new StringBuilder();
        for (byte aByteData : byteData) {
            String hex = Integer.toHexString(0xff & aByteData);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }

    // Test
    public static void main(String[] args) {
        String hexHash = getHexHash("password", "983483");
        System.out.println(hexHash)
    }
}

Output:
25e5ec9766fc5c48661aeec78085012166c9be8d