Applying for a job? What we like to see

We recently just finished hiring another engineer for our team (welcome Jared!), during which we’ve seen quite a few different applications and it also led to http://shout.setfive.com/2013/05/07/recruiters-before-you-call-do-a-little-research/">my previous post about what we’d like to see recruiters do before contacting us.

While I am certainly no hiring expert, I think some of the following points may help people applying for a job out.

Read the Full Posting

Many job postings, including ours, will include details about what they want to see from any potential candidate. I've seen everything from a simple put in the subject "XYZ" to answer the following programming questions. On some of our job postings we include something like include your favorite beer, the best place you've vacationed, etc.. These questions aren't only used to weed out spam, but we like to see what people come up with and to see if they are a good fit. Regardless of what the posting request is, it's important to fully read it and apply properly. Several potential candidates didn't read ours in full and didn't follow the simple application instructions. If you don't follow the instructions it can reflect poorly as it may indicate you aren't able to pay attention to details.

Shorter Can Be Better

I remember back in college when working on resumes many advocated "keep it to a single page"; I can't agree more now. I've received some resumes that are over 6 pages long. A resume, in my point of view, should be something that bullet points your skills, experience, and education. Most of the time, you can fit all this information on to a single page. Being clear and concise pays its dividends. I'm much more interested in the resumes that I could briefly look at and get a good feeling about the candidate. The long resumes often spent a half page to page summarizing some activity at a previous job; it's much easier to inquire about a specific experience you have if I don't understand it.

Keep Programming Languages Short

One thing I saw on an alarming number of resumes was that someone would list 10+ programming languages as their core languages. I'm all for having basic knowledge in multiple languages, but I wouldn't list all the languages I've ever worked on as my core language.

The long lists (java,python,php,ruby, perl, c++, c# and scala), more often on recent graduates, seemed more like a list of languages the candidate knew existed. Understandably, right out school you may not have a specific language that you have an in-depth knowledge of. In this case, I recommend looking up what language the job position that you are applying for is, and list that and one or two others that compliment it (such as PHP, Javascript, SQL) rather than listing everything you’ve ever worked in. I gave much more attention to candidates who applied with fewer languages and then listed a few projects/concepts they did within each language.

Past Projects, Not Classwork

One of the last points I want to touch on is when people want to know past projects you've worked on. What I'm looking for is something to just show that you can put all the programming concepts you've learned together to form some sort of project. Whether this is a simple side project you had or something you worked on at your last job, it shows you are able to take some theory and apply it to realistic applications. Often at career fairs I'd get 30 resumes all which list the exact same project, which was an assignment from class. While coming straight from college you may not have many side projects, have at least one (or make one), and list it first. By having at least one side project that you've built (or been a major part of), it shows that you're able to take what you've learned in theory and apply it. Classroom assignments are often "fill in the blank" or too rigid, follow these exact instructions, to demonstrate your full capabilities.

While these are only some of the points I look for on incoming applicants, they are extremely important. Let me now if you think I’ve missed a few!

Good luck on applying to your next job!

Symfony2: Logging users in programatically with Doctrine2 and FOSUserBundle

Recently I was doing a fairly common task on Symfony2, logging in a user programatically. Often applications do this on registration, via auto login links, complex login forms, etc. This time I was using an auto login link that expires that users get via email. I came across the issue that it seemed the first time the page loaded I was logged in properly but then as soon as I redirect or navigated anywhere I was logged out.

Here is the basic workflow we were using:

  1. Create an auto login link, basically just an entity which had an expiration date and a special url hash
  2. When clicked forward to action which gets the related entity, and then retrieves the user.
  3. Login the user programatically
  4. Redirect to whatever we want them to see

The issue was somewhere between step 3 and 4 something was amiss, if I eliminated step 3 the profiler toolbar showed I was properly logged in as expect, as soon as I redirect it showed me as unauthenticated. Here is the code for the most part:

<?php

    /**
     * @Route("/login-token/{token}/{userHash}", name="participant_autologin_token")
     * @ParamConverter("autologinToken", class="MyBundle:AutologinToken")
     * @Template()
     */
    public function autoLoginAction(Request $request, AutologinToken $autologinToken, $userHash){
        
        $csrf_token = $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate');
        $now = new \DateTime();
        
        if( $autologinToken->getExpiresAt() != NULL && $autologinToken->getExpiresAt() < $now ){
            return array("csrf_token" => $csrf_token, "last_username" => "", "nextUrl" => $autologinToken->getUrl());
        }        
        
        if( $autologinToken->getUser()->getAutologinToken() != $userHash ){
            return array("csrf_token" => $csrf_token, "last_username" => "", "error" => "Sorry! There is a problem with your link. Please contact support.");    
        }
        
        $user = $autologinToken->getUser();

        $providerKey = $this->container->getParameter('fos_user.firewall_name');
        $token = new UsernamePasswordToken($user, null, $providerKey, $user->getRoles());
        $this->get('security.context')->setToken($token);
        
        $event = new InteractiveLoginEvent($request, $token);
        $this->get("event_dispatcher")->dispatch("security.authentication", $event);

        return $this->redirect( $autologinToken->getUrl() );     
    }

Fairly simple, used a ParamConverter to convert the incoming request to an entity. After a while of troubleshooting, I noticed that the ‘$user’ in this case wasn’t an actual Entity, it was a ProxyClass that Doctrine2 had generated. I had read that Doctrine2 ProxyClasses when serialized don’t properly bring over some of their attributes, namely the ID. This caused an issue with FOSUserBundle as the UserProvider looks up the user by their ID. Since the ID was blank this kept causing it to not find my user on the next page load.

There are a number of ways you can fix this, two that come to mind is to override the ‘refreshUser’ method of the UserProvider to look up by username as that is properly serialized from Proxy objects. Instead, as this was only for this one action and I wanted to be more efficient I switched the query to do a join to the user from the get go. This means when you do getUser Doctrine will return the actual Entity and not a Proxy class. Here is my update annotation:

<?php
    /**
     * @Route("/login-token/{token}/{userHash}", name="participant_autologin_token")
     * @ParamConverter("autologinToken", class="MyBundle:AutologinToken", options={"repository_method" = "findByTokenJoinWithUser"})
     * @Template()
     */
    public function autoLoginAction(Request $request, AutologinToken $autologinToken, $userHash){
    ....
    }

For more on how to use joins and entity repository specific consult the current manual.

Good luck!

Symfony2 forms without an entity and with a conditional validator

Recently on a project I had a situation where I was using the Symfony2 forms component without an entity. In addition to each field’s constraints, I needed to something similar to symfony 1.4’s conditional validator so that I could make sure that the form on the whole was valid. There are a bunch of docs out there on how to use callback functions on an entity to do this, however I didn’t see much on how to get the entire form that has no entity to do a callback. After reading some of the source code, found that you can set up some ‘form level’ constraints in the setDefaultOptions method. So it will look something like this:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(
        array('constraints'=>array(new Callback(array('methods'=>array(array($this,'checkAvailableFunds'))))),			
	)
    );
	
}

You pass the Callback constraint an array methods which it can call. If you pass one of those methods is an array it is parsed as class::method. In my case by passing $this it uses the currently instantiated form, rather than trying to call the method statically.

From there you can do something like this:

public function checkAvailableFunds($data,ExecutionContextInterface $context)
{
    if($data['oneField']===1&&$data['twoField']===3){
        $context->addViolation('No or not enough giftcodes for selected export are available!');
    }
	 
}

The first parameter is the form’s data fields. From there you can add global level errors to the form, such as if a combination of fields are not valid.

Good luck out there.

HTTPs, Reverse Proxys, and Port 80!?

Recently we were getting ready to deploy a new project which functions only over SSL. The project is deployed on AWS using the Elastic Load Balancers (ELB). We have the ELB doing the SSL termination to reduce the load on the server and to help simply management of the SSL certs. Anyways the the point of this short post. One of the developers noticed that on some of the internal links she kept getting a link something like “https://dev.app.com:80/….”, it was properly generating the link to HTTPS but then specify port 80. Of course your browser really does not like that as its conflicting calls of port 80 and 443. After a quick look into the project we found that we had yet to enable the proxy headers and specify the proxy(s), it was we had to turn on trust_proxy_headers. However, doing this did not fix the issue. You must in addition to enable the headers specify which ones you trust. This can be easily done via the following:

<?php

use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\HttpFoundation\Request;

$loader = require_once __DIR__.'/../app/bootstrap.php.cache';

// Use APC for autoloading to improve performance.
// Change 'sf2' to a unique prefix in order to prevent cache key conflicts
// with other applications also using APC.
/*
$loader = new ApcClassLoader('sf2', $loader);
$loader->register(true);
*/

require_once __DIR__.'/../app/AppKernel.php';
//require_once __DIR__.'/../app/AppCache.php';

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
//$kernel = new AppCache($kernel);
$request = Request::createFromGlobals();

Request::setTrustedProxies(array('192.168.1.1'));

// If it is only available via the proxy:
//Request::setTrustedProxies(array($request->server->get('REMOTE_ADDR')));

$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

Here is a very simple example of how you could specify them. You just let it know the IP’s of the proxy(s) and it will then properly generate your links.

You can read up on this more in the Symfony documentation on trusting proxies.

Anyways just wanted to put throw this out there incase you see this and realize you forgot to configure the proxy in your app!

Symfony2 and Impersonating Users, a Heads Up

Recently I was working on a project in which it admins were able to impersonate other users. It’s a fairly easy task to add to Symfony2, merely adding a switch_user reference to your firewall can make it possible, consult the Symfony docs for more on that. One thing I noticed was that every now and then when testing I would get weird errors after switching between multiple users, however it didn’t always happen. After some digging around, it turns out when you switch user it does not clear that sessions attributes, ie if you set attribute ‘hello’ to value ‘world’ it would persist after you’ve impersonated another user. This caused a few issues as on this application we used the session to store a few things like which set of database connections you currently use.

After looking at the SecurityBundle configuration setup it was clear that there wasn’t any options to have it clear all session attributes on switch user. At this point it was clear I needed to use an event listener as the firewall dispatched the SwitchUserEvent when a user successfully switched user. Below is an excerpt from my services.yml

services:
    my.login_listener:
        class: Setfive\DemoBundle\Listener\LoginListener
        tags:
            - { name: kernel.event_listener, event: security.switch_user, method: onSecuritySwitchUser }

This makes it so that it will call the following code on a successful impersonation of a user:

<?php
namespace Setfive\DemoBundle\Listener;

use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;

class LoginListener
{
  
    /**
     * Fired on switch user, you can remove attributes or whatever you want here.
     * @param SwitchUserEvent $event
     */
    public function onSecuritySwitchUser(SwitchUserEvent $event)
    {
        $session = $event->getRequest()->getSession();
        $session->remove('partThatShouldNotCarryOver');
        
    }
}

It’s as simple as that, you can get the actual user by calling $event->getTargetUser(). Long story short, the session can have some tainted values when using switch user as all attributes are not cleared.