bash based time tracking

written by Raphael

Time tracking has been a recurring theme in my career as software developer. I've previously developed multiple solutions to do this myself, but this is the one that I like the most - and since I've been using it for about half a year now it's time to publish it:

say hello to traq - bash based time tracking which works on Linux and OS X

I like to be in control of my own data. Traq gives me complete control and it complies with unix best practice by using a text based format which can be easily read & manipulated by a human.

Usage

traq enables you to track times for different clients into different folders so you can easily evaluate them later.

To start time tracking for website-a I'm working on all I need to execute is

traq -p client website-a
Later the same day before going to lunch I execute
traq -p client stop
to stop the tracking.

Anytime I want to know for how long I've been working I can execute this:

traq -p client -w 50
per week or
traq -p client -d 2012-12-09
per date or
traq -p client
for today only. The output lists all tracked hours like this:


Sun Dec 09 16:07:38 +0100 2012;#project
Sun Dec 09 16:51:26 +0100 2012;#meeting
Sun Dec 09 19:43:39 +0100 2012;stop
%%

Now I'd like to know for how long I've been working on a given project. For this I'm going to use the two helpers bundled with traq: traqtrans and traqeval:

traq -p client -d 2012-12-09 | traqtrans | traqeval

which gives me the total of hours I've been working so far:

2012-12-09
#project:0.73
#meeting:2.870277777777778
%%

Now I can combine this with standard unix utilities:

traq -p client -d 2012-12-09 | traqtrans | traqeval | \
grep '#' | cut -d':' -f2 | paste -sd+ - | bc
# 3.600277777777778 

It's a small step to interface with online time tracking services now - but I'm in complete control.

closing note

If you are a freelancer or an employee who likes to be in control of what data is being tracked this might be something for you. Check out the git repository, the installation is only four lines and I'd love your feedback.


authenticate sudo using Yubikey

written by Raphael

I'm a huge fan of security by "Something You Have" in combination with "Something You Know". A good example for web developers probably is their public/ private key pair they use to authenticate access via ssh to their web servers.

When I read about the Yubikey I immediatly wanted to use it to authenticate sudo access on my web server. I've been using my ssh agent to do that via pam-ssh-auth, but I can add a physical component to my authentication setup with a yubikey. Sounds compelling? Yes it does!

First I'm assuming you've got a yubikey, and a yubikey validation server which can be used to validate your yubikey. Yubico has free servers available which you need to register with, but you can also host them yourself because the software is open source.

Second I'm assuming you're running an ubuntu based server. Let's start by installing the yubico pam extension used for authentication:

$ sudo apt-get install libpam-yubico

Next, create a yubikey mapping file to map yubikey public identifiers to your physical users. Only the users listed in this file can authenticate their sudo using a yubikey. Other users with sudo privileges can use passwords just as before.

$ cat > /etc/yubikey_mappings <<EOF
administrator:aabbccddeeff
EOF

Here I've mapped the yubikey identified by aabbccddeeff to the user administrator.

Now let's adjust the pam sudo configuration:

$ vim /etc/pam.d/sudo

Insert

auth      sufficient pam_yubico.so id=<insert id> url=https://your.yubicloud.server.com/wsapi/2.0/verify?id=%d&otp=%s authfile=/etc/yubikey_mappings

just before the first line reading auth required …

You must replace <insert id> with your client-id from your yubico validation server in the above example. Also make sure to replace your.yubicloud.server.com with a real server address! Otherwise this will not work!

That's about it - you can authenticate sudo using your yubikey: test it!

$ ssh administrator@example.com
Welcome to Ubuntu 12.04.1 LTS (GNU/Linux 3.2.0-33-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

Last login: Sat Dec  8 12:01:26 2012 from 235-47-142-46.pool.kielnet.net
administrator@example.com:~$ sudo -i
Yubikey for `administrator': # press on your yubikey
root@example.com:~# logout

The good parts

  • Never look up your root-password again - unless you've lost or destroyed your yubikey.
  • You can add Yubikey based authentication to your web apps - great for internal-use applications!

The bad parts

  • A yubikey costs $ 25 per piece. For now that's a one-time investment, but I do not know about their durability.
  • Maintenance - if you decide to host the validation server yourself you'll have to administrate those as well.

Q/A

Q. Where to find my yubico client id?

A. I've not found a way to determine the client ID from the yubico cloud servers. That's why I've hosted the entire stack myself. It's straight forward using the documentation available at github.

Q. What's my yubikey public identifier?

A. It's the first 12 characters from your Yubikeys OTP string.

Q. It's not working!

A. Add debug to the line in /etc/pam.d/sudo and tail the syslog for authentication informations. Connect the dots.


Check for Unit-Tests in Objective-C

written by Raphael

I've been adding some Unit Tests to an iOS App lately, which had both Test Host and Bundle Loader set for the Unit-Testing target. Now executing the unit tests caused the iOS App to launch, and the launch itself interfered with my unit-tests (e.g. real network calls which interfere with your mocked network calls).

I needed a way to stop the launch if we are running in a unit testing scenario. So how do you detect if Unit-Tests are being run in Objective-C ? Turns out it's extremly simple:


BOOL runningTests = NSClassFromString(@"SenTestCase") != nil;

That's all you need to check if you are running Unit-Tests - an additional return at the right place and your app stops dead when executing unit tests.

There are a few assumptions about your test targets setup:

  • Test Host is set to your iOS App
  • Bundle Loader is set to your iOS App

Happy Hacking :)