Monday, June 29, 2015

Faster builds of my TYPO3 extensions on Travis CI

tl;dr If your Travis CI project was created before 01.01.2015 and you think your builds must run faster, switch to container based builds by adding sudo: false and configuring a cache for composer dependencies in your .travis.yml file.

Nearly all my Open Source TYPO3 extensions are built on Travis CI. This runs really fine and I am very happy with the service Travis CI offers for free if your project is Open Source. What I did'nt know was, that Travic CI also offers the possibility to use container based builds (saw it first in this commit for the TYPO3 master). This feature was announced in the end of 2014 and has some advantages over the Travis CI standard infrastructure. Container based builds do have more resources (2 cores vs. 1.5 cores and 4 GB Ram vs. 3 GB ram), better network capacity and can use a cache for dependencies (e.g. composer dependencies).

My extension sf_event_mgt has a lot of functional tests and since I also collect code coverage data, builds did run very long (15-30 minutes, worst result was more than 48 minutes) on the Travis CI standard infrastructure. Since my Travis CI project was created before the 1st of january 2015, my builds were automatically built using the old infrastructure. I therefore tried to use the container based infrastructure to see if my builds would run faster.

In order to force your build to run on the container based infrastructure, you just have to add the following to your .travis.yml file.

sudo: false

    - $HOME/.composer/cache

The sudo: false option tells Travis CI to use the container based infrastructure and the cache configuration sets the cache-directory, which will persist during builds.

When I started the first build, I was really amazed about how fast the builds started and how much faster builds were completed. There was only one problem, which showed up in the logs.

  - Installing  symfony/yaml  ( v2.7.1 )
    Downloading:  connection...      Failed to download symfony/yaml from dist: Could not authenticate against 
    Now trying to download from source 
  - Installing symfony/yaml  ( v2.7.1 )
    Cloning 9808e75c609a14f6db02f70fccf4ca4aab53c160

In order to fix the failing download of dependencies from, you must create an OAUTH token for your GitHub repository and add it to the .travis.yml. I therefore created an OAUTH token (which just has read access to my public repositoried) in my GitHub account. Next I added the OATH token to the .travis.yml file. As the token should and must be kept secret, Travis CI offers the possibility to encrypt sensitive data. For my TYPO3 extension sf_event_mgt I did as shown below:

sudo gem install travis
travis encrypt GITHUB_COMPOSER_AUTH=my-github-oauth-token -r derhansen/sf_event_mgt

Next I added the resulting encrypted key to my .travis.yml and configured composer to use the GitHub OAUTH token if available.

    secure: my-encrypted-key

  - if [ "$GITHUB_COMPOSER_AUTH" ]; then composer config -g $GITHUB_COMPOSER_AUTH; fi
  - composer install

After restarting the build, the error did'nt show up in the logs of my Travis CI build any more. My complete configuration can be found in this gist.

Finally, the switch to the container based builds seems to have reduced the average build time by about 50% and seems to run more stable than before.

Tuesday, June 16, 2015

TYPO3 7.3 - Extending the backend login form by using the new backend login form API

Back in january 2015 I added support for TYPO3 7.1 to the YubiKey TYPO3 extension and raised the extension compatibility level to be compatible with TYPO3 version 6.2.0 up to 7.99.99. When TYPO3 7.2 was released, I found out, that the YubiKey extension did'nt work any more with the new TYPO3 version, because the TYPO3 backend login has been rewritten. I debugged into the issue and found out, that the new backend login did not respect the template set in $TBE_STYLES['htmlTemplates'][$tmplPath].

It seemed I was not the only one having this problem, as another user already reported the same issue on forge. So with TYPO3 7.2+, you can't use $TBE_STYLES['htmlTemplates'][$tmplPath] to add own fields to the backend login form, since it is not supported any more.

In this article I describe, how the new backend login form API is integrated in the OpenID extension and I also describe, how I extended the username/passwors login provider to add an additional field to the default backend login form.

The new login form API in TYPO3 7.3

In order to get the missing functionality of extending the backend login form back, the TYPO3 core developers added the backend login form API and also did a lot of great work refactoring the backend login. The backend login form API uses login providers to enable extension developers to add an own backend login form for e.g. an own authentication service. As an example, lets have a look at how the OpenID authentication service is integrated.

The OpenID authentication service registers a new login provider by adding the following code in the file ext_localconf.php

New login providers must add a new key to the array $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['backend']['loginProviders']. The new key must be an unix timestamp (unique for all login providers). The following array has the following keys:

  • provider: The name of the login provider
  • sorting: Defines the sorting order in case of there are multiple login providers
  • icon-class: A class which defines the icon for the login provider
  • label: the label for the login provider 

Having the OpenID authentication service installed, the login provider of the OpenID extension adds a link to the backend login (see screenshot below).

TYPO3 7.3 backend login form showing the OpenID link
When you follow the "Login with OpenID" link, you come to an own login form showing the OpenID field (screenshot below).

TYPO3 7.3 OpenID login form
From there, you have the possibility to switch back to the username and password login. This is, because also the username and password login has an own login provider.

Lets have a look at the contents of the login provider class.

As you can see, there is not much magic there. The OpenidLoginProvider implements the LoginProviderInterface and has only one method (render), which is called in the LoginController of the TYPO3 backend login form. In case of the OpenID extension, you see that setTemplatePathAndFilename is used to set the Fluid template for the OpenID login form.

The template is kept really simple. It uses the layout "Login" (this is required) and has a section called "loginFormFields" (also required), which contains the OpenID login field.

Integration of the backend login form API to the YubiKey extension

For the YubiKey extension, I could have used the same technique as the OpenID extension does, but since some TYPO3 installations may require each user to use YubiKey two-factor authentication, it would be not very user-friendly to let a user manually switch to the YubiKey backend login provider when opening the TYPO3 backend login form.

In order to add the YubiKey field to the backend login, I extended the existing username and password login provider with my own login form. In the ext_localconf.php, I added the following code.

Next I created the YubiKey login provider, which calls the parent login provider (username and password) and sets the path to the Fluid template which contains the both the username and password fields and the YubiKey login field.

Note, that I do not implement the LoginProviderInterface, but extend the UsernamePasswordLoginProvider.

Finally, after the YubiKey extension is installed and activated, the TYPO3 backend login now again has an additional field for the YubiKey two factor authentication (screenshot below)

TYPO3 7.3 backend login with the additional YubiKey field
As TYPO3 7.3 has been released yesterday, extension authors ,who created own authentication providers for the TYPO3 backend, can now start to implement the new backend login API to their extensions.

The latest version 1.1.0 of the TYPO3 YubiKey extension uses the new backend login form API and is compatible with TYPO3 6.2 and TYPO3 7.x (except 7.2)