Kata: Authentication Filter in Java EE

This is an exercise I’ve used to demonstrate how awkward unit testing can be if you can’t use a mocking framework. It’s an almost real work life situation (disclaimer: you should perhaps use container based authentication and JAAS) where we’re using API:s in a Java EE Server, adding two collaborators and then writing the logic combining it all.

No group has (yet) completed the entire task within 90 minutes – you might want to start/focus on using one collaborator only (I suggest the LDAP collaborator).

Originally posted on codingdojo.org.

When cleaning up a folder at work, I found this old document – it’s some form of a logical flow chart of the filter to write.

Here we go …

Background

In this Kata, your a programmer at ABC Corp and you’re making a new web app from scratch. After the head architect started working on this, it’s now up to you to make sure these tasks are completed:

  • allow authentication using request parameters
  • all authentication/login attempts should be verified agains LDAP
  • successful logins should be recorded in the single sign on registry

However, you’re not the only programmer (team) adressing this web app, so the LDAP is written by another team and what you have right now is this interface:

 public interface LdapAuthenticationGateway {
   boolean credentialsAreValid(String userName, String password);
 }

and the single sign on registry is also written by another team, leaving you with this interface:

 public interface SingleSignOnRegistry {
   boolean tokenIsValid(String token);
   String registerNewSession(String userName);
   void endSession(String token);
 }

Your job basically is to write one or more javax.servlet.Filter that handles incoming requests and act according to whether there’s a cookie with a SSO token, username+password parameters etc.

It’s assumed that there’s some form of DependencyInjection framework in place – to get a handle to the SingleSignOnRegistry or the LdapAuthenticationGateway, you’ll simply have to provide something like:

 public void setSingleSignOnRegistry(SingleSignOnRegistry registry) {
   ...
 }

About this kata

This “real life” scenario has been used to demonstrate how mocking (using Mockito) can be useful. We’ve combined it with BDD and JDojo@Gbg will try to practice TDD using this kata (without mocking) next time around.

(“Real life” is quoted – proper JEE authentication should be tied into the container etc etc … The point with this exercise is that it’s fairly easy to explain how it should work and what needs to be done here with “real” Java EE API:s, and then focus on the “How to develop” aspect (TDD), but also to show/talk about the difference between mocking and stubbing.)

JavaForum 2011Q2

Igår var det JavaForum 2011Q2 som denna gång hölls på Ullevi Konferenscenter – en lokal jag tyckte funkade mycket bra. Jag hade anmält mig som talare på ämnet Clean Code med förhoppning om att få till lite diskussion – det är ändå inget jättenytt eller kontroversiellt ämne.

Jag hade 30 minuter och använde 21 av dem till att agitera med presentationen nedan. Övriga 9 minuter höll jag tyst bäst jag kunde för att få lite diskussion och det gick – det var olika deltagare som ställde frågor och svarade. Ett par småskratt och målet med kvällen nåddes.

Kanske kommer någon in och betygar min prestation på Speakerrate?

Finns också som PDF.

VNC-studsare

Jag hade för fem år sedan en egenskriven blogg. Sedan åt jag upp databasen. På den fanns iaf instruktioner för hur man lätt kunde sätta upp VNC på windows så att man kan hjälpa en människa i nöd.

Eftersom både jag och t ex min far befinner oss bakom en NAT/router så är det inte helt rättframt. För att lösa detta satte jag upp en VNC-studsare – en bit Java som knöt ihop två TCP-koppel. Idag skulle vi behövt detta. Eftersom jag inte hittade det så skrev jag ihop det på nytt.

De övergripande instruktionerna är att servern (den som behöver hjälp) ansluter med “reverse” (x11vnc -connect host:port) och klient (den som ger hjälp) till samma port på studsservern.

Mer detaljerade Windows-instruktioner får vänta tills nästa gång.

Studsserver

Kör VncBouncern. Den skriver ut porten som används.

Linux

Lite kommandon:

x11vnc -connect localhost:`netstat -lnp | grep java |tr ':' ' ' | tr -s ' ' | cut -d ' ' -f 4`
vncviewer 192.168.1.157:`netstat -lnp | grep java |tr ':' ' ' | tr -s ' ' | cut -d ' ' -f 4`-encodings "copyrect hextile corre rre"

Bakgrunden till -encodings är att när man ansluter till sin egen maskin för att testa så säger vncviewern “Same machine: preferring raw encoding”, och det går apslött.

Ämnen för Java-TDD

Tittar på att gå ett steg längre med TDD-workshops och lämna de grundläggande ämnena. Följande har efterfrågats:

  • testning med/av legacy code
  • vad är bra respektive dåliga test
  • funktionell eller acceptansdriven testning (ATDD)
  • beteende driven utveckling (BDD)

Egna saker jag själv skulle vilja gräva lite mer i och ägna ett par timmar åt:

  • hamcrest (matchers)
  • dotmesh (methods)
  • making EasyMock suck less
  • making Mockito suck
  • easyB
  • Fitnesse

I allmänhet så saknar jag en diskussion om hur lättredigerade test (wiki?) versionshanteras ihop med koden de testar eller är skrivna mot. Detta är ju högst intressant när man går in och gör en hot-fix för en produkt som rört sig mycket under ett år, och en kund som har produkten i drift sedan ett drygt år tillbaka vill sin fix. Hur kör man samma testsvit som man hade för ett år sedan på ett enkelt sätt? Hur är egentligen inte svårt. Jag har bara inte sett många bra lösningar, ännu. TextTest, xUseCase och liknande plain text-ramverk är en bra lösning. Frågan är bara om testen är tillräckligt tillgängliga för ATDD – hur får man kunden att känna att det är hans/hennes test?

Klassletning

Om man någon gång vill leta efter, eller bland, klasser så verkar http://svn.apache.org/repos/asf/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ ha allt man kan tänkas vilja ha. :)

Build.version

Med hjälp av MANIFEST

<build><plugins><plugin>
				<groupid>org.codehaus.mojo</groupid>
				<artifactid>maven-buildnumber-plugin</artifactid>
				<version>0.9.6</version>
				<executions>
					<execution>
						<phase>validate</phase>
						<goals>
							<goal>create</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
</plugins></build>

Denna plugin kräver att man satt upp SCM ordentligt så att versionnummer kan hämtas därifrån!

<build><plugins><plugin>
				<groupid>org.apache.maven.plugins</groupid>
				<artifactid>maven-war-plugin</artifactid>
				<version>2.0</version>
				<configuration>
					<archive>
						<manifestentries>
							<implementation -Build>${buildNumber}</implementation>
						</manifestentries>
					</archive>
				</configuration>
			</plugin>
</plugins></build>
	private String readBuildNumber(ServletContext servletContext) {
		try {
			URL resource = servletContext.getResource("/META-INF/MANIFEST.MF");
			InputStream manifestStream = resource.openStream();
			Manifest mf = new Manifest(manifestStream);
			Attributes atts = mf.getMainAttributes();
			String value = atts.getValue("Implementation-Build");
			if (value == null) {
				throw new IllegalArgumentException("Implementation-Build attribute is not set in MANIFEST " + resource.toExternalForm());
			}
			manifestStream.close();
			return value;
		} catch (Exception e) {
			throw new IllegalStateException("Failed to read Implementation-Build attribute from MANIFEST.MF");
		}
	}

Eller som vanlig resource (properties)

<build>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
			</resource>
		</resources>
</build>

assertThat(Hamcrest).looksNice();

I väntan på David Saff’s alternative assertThat(x).y() så nöjer jag mig med:

public class EmptyMatcher extends TypeSafeMatcher&lt;Collection < ?>> {
 
    @Override
    public boolean matchesSafely(Collection< ?> c) {
        return c.isEmpty();
    }
 
    public void describeTo(Description desc) {
        desc.appendText("empty");
    }
 
    @Factory
    public static lt;T> Matcher< ? super Collection<?>> isEmpty() {
        return new EmptyMatcher();
    }
}

som gör att man kan skriva trevlig enkelt läsbar kod, t ex:

@Test
public void filteringAnEmptyListReturnsAnEmptyList() {
    List anEmptyList = new ArrayList();
    List result = testee.filter(emptyList());
    assertThat(result, isEmpty());
    // men helst: assertThat(result).isEmpty();
}

Javautvecklare sökes

Jag jobbar på Iptor Konsult AB och mer specifikt på avdelningen som går under namnet JavaSolutions. Jag trivs väldigt bra och bytte till denna arbetsgivare bara pga dess “interna politik”: lågt i tak, platt organisation, många teamaktiviteter samt kompetenta medarbetare som ger mig bra med- och mothugg i diskussioner av alla dess slag.

Vi söker fler personer som kan berika vår trupp och annonser på nätet på olika platser och jag tänkte föreviga den beskrivning som oftast kan ses, mest för att det kan vara kul att se tillbaka på om 15-20 år.

I huvudsak är beskrivningen bra: jag hade hoppat bindestrecken efter Java, flyttat Webservices från rubriken “webb” och ev lagt till något om lättviktig/rörlig/agil utvecklingsmetodik.

Skulle du som läser detta (mot förmodan – det här är mina anteckningar!) bli intresserad går det bra att höra av dig till mig eller Tomas Trolltoft t ex via mail.


Erfarna javautvecklare till Iptor

Presentation
Iptor expanderar och behöver utöka sitt team av Java-specialister. Därför söker vi dig med stor erfarenhet av Java-utveckling.

Arbetsuppgifter
Dina arbetsuppgifter anpassas efter dina egna erfarenheter.

Iptor tillhandahåller tjänster som:

– systemutveckling och arkitektur
– uppbyggnad av kundens utvecklingsmiljö
– teknisk konsultation, till exempel vid val av utvecklingsplattform
– granskning av system- och kodstruktur
– optimering av befintlig kod
– optimering av kunds utvecklingscykel
– mentorskap
– utbildning.

Utbildning/erfarenhet
För att passa in i teamet måste du brinna för Java och de möjligheter det skapar, samt ha förmåga att vidareförmedla dina kunskaper. Vanliga forum för detta är olika typer av utbildningar hos kunder.

Vi tror att du har en högskoleexamen och minst 5 års erfarenhet som Java-utvecklare. Du är van vid konsultrollen och har tidigare arbetat med några av nedanstående tekniker:

– JSE, JEE, JME
– applikationsservrar: JBoss, Glassfish, Weblogic, WebSphere m.fl.
– ramverk: JPA, Hibernate, Spring m.fl.
– utvecklingsverktyg: Eclipse, Ant, Maven m.fl.
– meddelandehantering
– webb: HTML, XML, JSP, WebServices m.fl.
– OS: Linux, Windows, Unix, iSeries m.fl.
– databaser: Oracle, DB2, MySQL, MS SQLServer.

Har du arbetat med JSF, SEAM eller testdriven utveckling är det meriterande.

Du är engagerad till din natur. Du brinner för kundnyttan i dina projekt och du har förståelse för hur man vidareutvecklar en affär.

Företagspresentation
Iptor är ett svenskt IT-konsultbolag inom IBS koncernen, med kontor i Göteborg, Stockholm och Malmö.

Sedan våren 2006 är vi till exempel arrangör av Javaforum i Göteborg, ett förtroende vi fått från SUN Microsystems där vi åtar oss att hålla kontinuerliga Javaforum med intressant innehåll. Via vår Javaportal www.JSolutions.se presenterar vi artiklar, nyheter och tankar kring systemutveckling med Java.

Vår specialitet är systemutveckling och systemintegration med Java. Vi har haft majoriteten av våra uppdrag hos större företag där vi levererat både rena produktionsplattformar, affärsstöd samt integrationslösningar. Flertalet av våra konsulter har arbetat med realtidsapplikationer där kraven på prestanda och svarstider är mycket viktiga. Vi har jobbat med de flesta hårdvaru- och mjukvaruplattformar som IBM, BEA, Oracle, Microsoft, SUN, Linux m.fl. Vi vågar säga att vi är i framkanten på Javautvecklingen i Sverige.

Utvecklingsstack – för Java

Jag har funderat lite på vilken stack jag föredrar och nu såhär sent på kvällen skriver jag ihop:

  • JIRA
  • DokuWiki
  • Hudson
  • Sonar
  • Nexus / Archiva
  • Git

Egentligen behövs två kategorier: en fri (gratis) och en betalvariant. Tanken väcktes av att jag såg Markus M. May paketera sin favoritstack för ArchLinux (tidigare Ubuntu, men gav upp detta). Det händer ju ett par gånger om året att just detta behöver sättas upp för ett projekt – att ha en färdig “blob” att bara slänga igång hade ju inte varit fel. Kanske en Xen image (Gandi hosting om man inte vill köra AMI/Amazon) eller bara en stor zip klar att sparkas igång med ett bash-script, …

Projekt- och ärendehantering

JIRA – en klassiker som fungerar även i större sammanhang. Kan knytas in till confluence. Projekt, komponenter, milstolpar, olika flöden, watchers, voters, rapporter, ärende-relationer, … Icke-gratis och icke-fri.

Mingle är en vacker produkt som jag inte är övertygad vara värd sin kostnad. Mest web 2.0-ig av alla och mest planeringsvänlig (dra-och-släpp med bäst översikt av tillgängligt material). Icke-gratis och icke-fri.

VersionOne – otestad.

BugZilla – klassiker som är för enkel för min smak.

RedMine – tyvärr otestad ruby-historia som ser kompetent ut på pappret. Verkar sakna ärende-relationer såsom liknar, ersätter, beror på, …

Trac – ärendehanteringen i trac är kass och för enkel.

Wiki

DokuWiki – enklast, snabbast, smidigast, rättframmast. Gör jobbet och det är trevligt att jobba med.

Trac – wikin i Trac fungerar ok. Trevligt när man kan länka till kod så lätt.

MediaWiki – no no.

Confluence – hat-kärlek. Ingen redigering av stycken, editorn buggig och saknar en hel del av TinyMCE:s “kraft”.

Källkodrepositorie

Git – har inte varit fri från strul, och strulet har inte varit helt idiotsäkert att fixa till. Men distribuerat, snabbt och enkelt att komma igång.

Mercurial (hg) – otestat, skall kunna mäta sig med git och till och med vara “finare” i vissa avseenden, t ex hur lång livslängden på en branch är.

SVN, CVS – klassiker som trots allt fungerar ganska långt för mindre team.

Mavenbibliotek

Archiva – trotjänare som trots allt fungerat stabilt under långa perioder. En aning gammalmodig med lösenordspenalism t ex.

Nexus – otestad, men vacker i publika installationer och på pappret. Mindre minnesavtryck (memory footprint) är ju inte fel.

Bygg- och CI-motor

Hudson – en klar favorit.

Continuum, Cruise Control – är lite samma sak för mig: en hög XML och inget som inte Hudson har. (Var länge sedan jag körde dessa dock.)

Övriga verktyg

Sonar – alla rapporter som kan genereras automatiskt bör genereras. När man får upp farten gäller det att hålla kurs så man inte hamnar i dolda teknisk skuld-fällor.