Friday, October 17, 2008

Wann kommt die nächste Bahn?

Mit einem kleinen Stückchen Javascript kann man dem Firefox die Verarbeitung von mehreren Argumenten bei der Keyword Search beibringen.

Die Bahn bietet ja jetzt so schreckliche personalisierte Services an, bei denen man seine häufigsten Fahrplansuchen hinterlegen kann. Das ganze wird als Cookie gespeichert. Da jeder, der ein wenig Wert auf Privatspäre im Netz legt, diese klugerweise nach Schliessen des Browsers wegwirft, sind auch diese Einstellungen weg.
Zumal man sich zum Fahrkartenkauf sowieso noch geschätzte 72mal einloggen muss.
Auf jeden Fall nicht benutzbar. Aber: Muss man ja auch nicht :)

In einem seltenen Moment der Erkenntnis, hat die Bahn ein geiles Feature in die Suche eingebaut: Man kann statt der vollen Ortsnamen auch deren KFZ-Kennzeichen eingeben.
HH=Hamburg. Mit dem u.g. Skript kann man dann im Browser einfach "bahn m hh" eingeben und bekommt direkt die nächste Verbindung von München nach Hamburg angezeigt.
Geht doch!

javascript:var%C2%A0s='%s';%20url='http://reiseauskunft.bahn.de/bin/query.exe/dn?datesel=custom&start=1&returnTimesel=depart&S=%s&Z=%s&timesel=depart&REQ0Tariff_TravellerType.1=E&REQ0Tariff_TravellerReductionClass.1=0&REQ0Tariff_Class=2';%20t='';%20qc=0;%20chunks=url.split('%s');%20for(i=0;%20i<s.length;%20i++){if(s.charAt(i)=='"')qc=qc^1;%20t+=((s.charAt(i)=='%20'&&qc)?'^':s.charAt(i));%20}args=t.split(/\s/);%20nurl='';%20for(i=0;%20i<chunks.length;%20i++){nurl+=chunks[i];%20if(args[i]!=undefined)%C2%A0{args[i]=args[i].replace(/\^/g,'%20');%20nurl+=args[i];%20}}location.replace(nurl,'<%20BR>');

Thursday, September 18, 2008

Yet to be seen...

... is a presentation on spring that does not contain the phrase "de-facto standard".

wow. that short, it could be on twitter.

Friday, August 22, 2008

Continuum 1.1 on Tomcat 6 with GMail notification

I "just" wanted to use my gmail account to send build errors to my real account until the integration server is in the right network that i can configure right the mailserver. Making this work took a bit longer. As you can see in the previous post, I skipped mailserver config in archiva. This time, I had to do it. First, you need activation-1.1.jar and mail.jar in your tomcat lib directory. ("folder" is windows-speak, isn't it?)

The jndi mail config in context.xml looks like this:

<Resource name="mail/Session"
           type="javax.mail.Session"
           mail.transport.protocol="smtp"
           mail.smtp.host="smtp.gmail.com"
           mail.smtp.auth="true"
           mail.smtp.port="465"
           mail.smtp.socketFactory.port="465"
           mail.smtp.socketFactory.class="javax.net.ssl.SSLSocketFactory"
           mail.smtp.user="something@gmail.com"
           password="makemyday"
           mail.smtp.starttls.enable="true"/>


Note the user is "mail.smtp.user" but the password is just "password". (For more on this, check here and here.

Great. But that's not all. There's a bug in the mailing system causing the password
not to be set right. Or something. With the patch provided, you'll have to recreate some jars.

Get the source:

svn co http://svn.codehaus.org/plexus/tags/plexus-mail-sender-1.0-alpha-7

find JndiJavamailMailSender.java and change the return line to return s; according to the patch (or just use the patch).
Run mvn package and copy the resulting jar files plexus-mail-sender-javamail-1.0-alpha-7.jar and plexus-mail-sender-api-1.0-alpha-7.jar to your continuum installations lib directory. (er, i extracted the .war file into my $CATALINA_HOME/webapps, if you're running the war itself, you need to repackage it).

Finally, tweak the sender in WEB-INF/classes/META-INF/plexus/application.xml, look
for the tags from-mailbox and from-name.
That's about it.

Wednesday, August 20, 2008

Installing archiva/continuum with tomcat+mysql on ubuntu

continuum documentation is kinda ... not finished yet. I'm in the process of installing the archiva/continuum double on an recent ubuntu server (hardy).
Database is a mysql 5.0 which I installed before.

Some trouble occurred when trying to connect the archiva webapp (which i installed first) to the database. For this, check /etc/my.cnf for the bind address as well as
the connect properties of the archiva database user (self-reminder). It can make a
difference if you connect at 127.0.0.1, localhost or the "real" IP.
Also, you may have to allow the port through the firewall (the "ufw allow" thing).

For archiva, I created the file /usr/local/tomcat/conf/Catalina/localhost/archiva.xml (with /usr/local/tomcat being my CATALINA_HOME):

<Context path="/archiva"quot;>
<Resource name="jdbc/users"
auth="Container"
type="javax.sql.DataSource"
username="archiva"
password="freetibet"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/archiva" />

<Resource name="jdbc/archiva"
auth="Container"
type="javax.sql.DataSource"
username="archiva"
password="freetibet"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/archiva" />

<Resource name="mail/Session"
auth="Container"
type="javax.mail.Session"
mail.smtp.host="localhost"/>
</Context>


For continuum, just copy the file, rename it to continuum.xml, change the username
accordingly and switch jdbc/archiva to jdbc/continuum.

If you are using Tomcat 6.0.18 beware. Due to these bugs (MRM-905 and CONTINUUM-1844) you will have to apply
two patches or just fire up some sed commands to replace "empty(" with "empty ("
and "not(" with "not (" in the jsp and tag directories.

I didn't put the webapps into the CATALINA_HOME like the documentation tell you to,
but into the standard CATALINA_HOME/webapps Folder.

Be sure to put the necessary libs into CATALINA_HOME/lib: mail.jar, activation.jar
and the mysql-connector.

Boy, this post is a mess.

Wednesday, July 30, 2008

The peach window

The peach window is the time interval where the peaches you bought are in an edible state. That is, the time between rock hard causing gum bleeding and moldy,
covered with fruit flies.

While the time before the window takes up to a week (and after as long a you can stand the flies), the peach window seems to be sized 12 hours in average.

Unfortunately, here they come packed at least by eight, and worse I seem always to get them in a synchronized set. So once a week, it's peach diet. Lucky me.

Wednesday, July 16, 2008

The longest classnames in spring security

If you ever wondered, how long a classname can become, have a look at spring security.

Here are the top-five of the longest ones (excluding package-name):

Sharing the second place, there are:

BasicAclEntryAfterInvocationCollectionFilteringProvider
J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource
PreAuthenticatedGrantedAuthoritiesAuthenticationDetails
WebSpherePreAuthenticatedWebAuthenticationDetailsSource


This almost look like a PGP key block.
Excited, who the winner is *gasp*? Here we go.

PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails

HemingwayWroteStoriesShorterThanThat.

Wednesday, July 9, 2008

Eclipse Ganymede branding - Getting your launcher icon right

Still, eclipse is picky when you're not explicit on your branding.
When providing icons for your windows application one by one (i.e. not with a combined .ico but single bitmaps) it is mandatory to specify a file for each
of the six sizes/depths.
Looks like win xp is looking for a 32-bit icon, so the "fault" is not on eclipse's side. Of course, it's on mine.

Iconomaker is capable of creating 32-bit bitmaps, but it is shareware.
Haven't tried gimp yet, but i suppose it can do so as well.

[update]
Yeah, gimp can do. Eclipse is just overwriting the icons from the original launcher.
If you drag your launcher in irfanview you will see a multipage icon (7 pages) you can
scroll through. I only wonder where i can specify the seventh icon, since the branding wizard only allows for six?

Friday, June 27, 2008

My ganymede icon

So eclipse ganymede is finally out. Good news, although some plugins still have to be updated to work with
it. If you don't have the JEE package, don't try to install the Spring IDE Mylyn Integration, look for installation instructions here.)
The Mantis-mylyn integration is not yet ready for 3.4, so you have to use the dev version to make it work, the update-site URL is http://mylyn-mantis.sourceforge.net/eclipse/dev/update/site.xml

Unfortunately, Eclipse did not provide a new icon for ganymede but having seven zillions different versions on my desktop, I need some visual distinction. Fortunately, irfanview can extract icons from exe's, so look at this masterpiece.
Bow, Picasso!


Tuesday, June 17, 2008

Spring Security + Spring Remoting + Digest Authentication Part 2

Now for the server configuration. I will spare out the setup of a web application, since you will know that yourself.

First, the SecurityService and its implementation:

public interface SecurityService {
public String[] getRoles();
}



import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContextHolder;

public class SecurityServiceImpl implements SecurityService {
public String[] getRoles() {
GrantedAuthority[] gas = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
String[] roles = new String[gas.length];
for (int i=0;i<gas.length; i++) {
roles[i] = gas[i].getAuthority();
}
return roles;
}
}


Not that complicated.
This is the web.xml, which looks rather straightforward:

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<display-name>web-deployed service layer</display-name>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-service.xml</param-value>
</context-param>


<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>remote</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>remote</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>


</web-app>



Following the convention, there is a [minimal] remote-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>

<bean name="/securityService"
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="serviceInterface" value="de.yyy.xxx.SecurityService" />
<property name="service" ref="securityService" />
</bean>

</beans>



and finally, the biggest artifact, the server's application context.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">


<bean id="securityService" class="de.yyy.xxx.SecurityServiceImpl">
<security:intercept-methods>
<security:protect
method="de.yyy.xxx.SecurityServiceImpl.getRoles" access="ROLE_USER" />
</security:intercept-methods>
</bean>

<security:authentication-manager alias="authenticationManager" />

<bean id="digestProcessingFilter"
class="org.springframework.security.ui.digestauth.DigestProcessingFilter">
<property name="userDetailsService" ref="uds" />
<property name="authenticationEntryPoint"
ref="digestProcessingFilterEntryPoint" />
</bean>

<bean id="digestProcessingFilterEntryPoint"
class="org.springframework.security.ui.digestauth.DigestProcessingFilterEntryPoint">
<property name="realmName" value="ThisIsTheDigestRealm" />
<property name="key" value="acegi" />
<property name="nonceValiditySeconds" value="10" />
</bean>

<bean id="springSecurityFilterChain"
class="org.springframework.security.util.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**"
filters="httpSessionContextIntegrationFilter,digestProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
</security:filter-chain-map>
</bean>

<bean id="httpSessionContextIntegrationFilter"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter" />

<bean id="filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager"
ref="authenticationManager" />
<property name="accessDecisionManager"
ref="accessDecisionManager" />
<property name="objectDefinitionSource">
<security:filter-invocation-definition-source>
<security:intercept-url pattern="/**"
access="ROLE_USER" />
</security:filter-invocation-definition-source>
</property>
</bean>

<bean id="accessDecisionManager"
class="org.springframework.security.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false" />
<property name="decisionVoters">
<list>
<bean
class="org.springframework.security.vote.RoleVoter" />
</list>
</property>
</bean>

<bean id="exceptionTranslationFilter"
class="org.springframework.security.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint"
ref="digestProcessingFilterEntryPoint" />
</bean>

<security:authentication-provider>
<security:user-service id="uds">
<security:user name="jimi" password="jimi"
authorities="ROLE_USER, ROLE_ADMIN" />
<security:user name="bob" password="bob"
authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</beans>



That's it. The client requests will be authenticated via the HTTP Digest algorithm,
the corresponding filter will set up a SecurityContext on the server side. When
the client asks for available roles, method security assures that only authorized clients can request them. The getRoles method then just accesses the SecurityContext and copies the rolenames in a String array which is returned.
There are some edges that need more polish, i.e. one could try to take the GrantedAuthority array and put this in a client's SecurityContext. With some more handcoding it should be possible to send the SecurityContext over the wire, but it needs more analysis if this makes sense.

Spring Security + Spring Remoting + Digest Authentication

This was a hard one. Documentation on how to use spring security with a rich client is thin or outdated. Using search engines, you'll have a name clash with the "spring rich client". The name change from Acegi to Spring Security and other things like the sample code not being completely distributed with the sources made it kinda hard for me to figure things out.
Nevertheless, here's what I've come up with:

The task was to integrate spring security with a rich client that uses spring remoting (via httpinvoker) so that the client knows the roles the user has and the server does so as well. I didn't want the client to use HTTPS for performance reasons, nor did i want to transfer the password in clear over the wire (or only marginally scrambled via Base64). I chose digest authentication to be the one.
I must admit that my knowledge on the spring security architecture is very shallow, so my solution is probably not the most elegant one, but it works for me.

I don't use the RemoteAuthentication classes that are provided since I couldn't make them work together with digest authentication.

Before posting the config, how does it work?
The client takes the user credentials, they would be manual input in a real app.
The creds are put into the HttpState so the Commons HttpClient library can do digest auth with the server. The problem is that you have the SecurityContext with the GrantedAuthorities available on the server, but not on the client. For that, I've created a SecurityService that just returns the GrantedAuthorities via remote invocation. That way, the client can (for example) hide or show menus or buttons,
depending on the available roles.

Ok, let's go. This is the main application, of course just a stub to show it works.

public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( "applicationContext.xml");
String user = "jimi";
String pw = "jimi";
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(user, pw);

HttpState httpState = (HttpState) ctx.getBean("httpState");
httpState.setCredentials(AuthScope.ANY, creds);

//print the available roles
String[] roles = ((SecurityService) ctx.getBean("securityService")).getRoles();
for (int i = 0; i < roles.length; i++) {
System.out.println("Role:" + roles[i]);
}
}


Now, the client's appconfig:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">


<bean id="securityService"
class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:8999/middletierService/securityService" />
<property name="serviceInterface" value="de.yyy.xxx.SecurityService" />
<property name="httpInvokerRequestExecutor" ref="httpInvokerRequestExecutor"/>
</bean>


<bean id="httpInvokerRequestExecutor"
class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor">
<constructor-arg ref="httpClient"/>
</bean>

<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
<property name="state" ref="httpState" />
</bean>

<bean id="httpState" class="org.apache.commons.httpclient.HttpState"/>

</beans>


Part 2 will be on the server's configuration.

Monday, June 16, 2008

Authenticate against NT Domain with JCIFS

I just wanted to authenticate a user against an primary domain controller in java.
The tool of choice seems to be JCIFS, so this is the minimal stripped-down example
to do this.


NtlmPasswordAuthentication auth1= new NtlmPasswordAuthentication("yourdomain", "theuser", "thepassword" );
InetAddress address=InetAddress.getByName("the.domain.controller");
UniAddress dc = new UniAddress(address);
SmbSession.logon(dc, auth1);


This will throw an exception when id or password is wrong. Otherwise it just terminates without an error.

Thursday, June 5, 2008

Telephone Idiots

To my dyin' day, i will never understands the imbeciles that ring a phone
and let it ring for twenty times. What do they expect? That I'm busy the first
nineteen rings and then, decide differently and pick it up?

Extra points for the morons that do this on office phones in a shared office.
Extra points and a pie for the jerk practicing this on my flat-share's phone
in the night.

But the mother of all phone crapheads must be piece of rotten flesh [see Book of Job, 7,5], that is just right now doin' this in the office behind me in a five minute rhythm. THE GUY IS JUST NOT THERE! HE WON'T PICK UP!

Communication rage.

Monday, June 2, 2008

Spring Security Javadoc generation

For whatever reason, there is no javadoc with the current Spring Security.
Here's how to generate it. Mainly for me to remember.

jar xvf spring-security-acl-2.0.1-sources.jar
jar xvf spring-security-cas-client-2.0.1-sources.jar
jar xvf spring-security-catalina-2.0.1-sources.jar
jar xvf spring-security-core-2.0.1-sources.jar
jar xvf spring-security-core-tiger-2.0.1-sources.jar
jar xvf spring-security-jboss-2.0.1-sources.jar
jar xvf spring-security-jetty-2.0.1-sources.jar
jar xvf spring-security-ntlm-2.0.1-sources.jar
jar xvf spring-security-openid-2.0.1-sources.jar
jar xvf spring-security-portlet-2.0.1-sources.jar
jar xvf spring-security-resin-2.0.1-sources.jar
jar xvf spring-security-samples-contacts-2.0.1-sources.jar
jar xvf spring-security-samples-tutorial-2.0.1-sources.jar
jar xvf spring-security-taglibs-2.0.1-sources.jar

javadoc -sourcepath . -subpackages org -d docs
cd docs
jar cf spring-security-javadoc.jar .

Wednesday, May 14, 2008

maven equinox problem

Ran across this one

Couldn't find a version in [1.0.0-v20070423, 1.0.0-v20070606] to match range [1.0.0,2.0.0)
org.eclipse.equinox:app:jar:null

when trying to

mvn clean install pax:eclipse -DdownloadSources

from the Eclipse RCP and Spring-DM tutorial by Jeff Caldwell.

The workaround by Michael Vorburger solved this for me.