Importing Contacts from Yahoo Mail using OAuth

Importing contacts from mail accounts using OAuth is a long solved problem which doesn’t have a good implementation. I googled and googled for a good library which imports contacts from Yahoo/GMail/Hotmail. Finally, I was forced to create one by myself. Here are the instructions on how to get it up and running for Yahoo Mail in your server in 2 mins.

1. You need a Yahoo API Key to fetch contacts from Yahoo. Proceed to Yahoo Developer Dashboard and create a key.

Application URL in the createKey page is the URL to which you will be redirected to after a successful/failed login attempt.
Application Domain is be your domain name.
Choose “This app requires access to private user data.” in the Access Scope and under the options which appear below that, select “Read” access for “Yahoo! Contacts”.
Store the API Key, Shared Secret and Application ID carefully.

2. Download Yahoo Social SDK for PHP from http://developer.yahoo.com/social/sdk/php/

$this->config->item(‘yahoo_consumerkey’) is your Yahoo API Key.
$this->config->item(‘yahoo_consumersecret’) is your Yahoo Shared Secret.
$this->config->item(‘yahoo_applicationurl’) is your Application URL you provided in Step 1.
$this->config->item(‘yahoo_applicationid’) is your Yahoo Application ID.

3. Add the following code where the user has to select Yahoo Mail


<a href="<?php echo YahooSession::createAuthorizationUrl($this->config->item('yahoo_consumerkey'), $this->config->item('yahoo_consumersecret'), $this->config->item('yahoo_applicationurl').'?data=abc'); ?>">Fetch Yahoo Contacts</a>

You may remove the ?data=abc if you don’t want to pass any data to Yahoo. Anything you pass here can retrieved back at Application URL as GET parameters.

4. Include the required files from the opensocial SDK library and then add the following snippet to the Application URL you provided in Step 1.

if (YahooSession::hasSession($this->config->item('yahoo_consumerkey'), $this->config->item('yahoo_consumersecret'), $this->config->item('yahoo_applicationid')))
{
    $session = YahooSession::requireSession($this->config->item('yahoo_consumerkey'), $this->config->item('yahoo_consumersecret'), $this->config->item('yahoo_applicationid'));
    $user = $session->getSessionedUser();
    $contacts = $user->getContacts(0, 1000);
    foreach ($contacts->contacts->contact as $contact)
    {
        foreach ($contact->fields as $field)
        {
            if ($field->type == "email")
            {
                $emails[] = $field->value;
            }
        }
    }
    //$_GET['data'] will be equal to "abc" at this page.
}
//$emails array has the email addresses of all the contacts.

5. That’s it folks. It is that simple.

Further reading :
1. http://developer.yahoo.com/social/sdk/php/
2. http://developer.yahoo.com/oauth/

Security settings for a LAMP Server : Iptables

Security is the major concern for anyone hosting a website on the internet. These are the preliminary security settings to be performed to protect your server.

iptables
Our server stack is LAMP. Hence iptables as the firewall is the most natural choice. The requirements are like

1. Block everything except Ping, SSH, Apache, and SSL.
2. Enabled SSH only from the selected IP addresses.

The following script takes care of all iptables settings. (Idea copied from here)

Note: Please enter the command one by one. Make sure you replace IP1.IP2.IP3.IP4 with your own IP address.

# Establish a clean slate
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F # Flush all rules
iptables -X # Delete all chains
# Disable routing. Drop packets if they reach the end of the chain.
iptables -P FORWARD DROP
# Drop all packets with a bad state
iptables -A INPUT -m state --state INVALID -j DROP
# Accept any packets that have something to do with ones we've sent on outbound
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Accept any packets coming or going on localhost (this can be very important)
iptables -A INPUT -i lo -j ACCEPT
# Accept ICMP
iptables -A INPUT -p icmp -j ACCEPT
# Allow ssh
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow httpd
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Allow mysql
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
# Allow SSL
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Block all other traffic
iptables -A INPUT -j DROP

I guess the above script should take care of the basic security issues. Hope it helps.

Apache Fix : NameVirtualHost *:80 has no VirtualHosts

I get this error every time I install apache web-server in an ubuntu machine. We use LAMP stack at Interviewstreet and this error was nagging me all the this while.

The error message shows up something like this.


root@interviewstreet:~# /etc/init.d/apache2 restart
* Restarting web server apache2 apache2: Could not reliably determine the server's fully qualified domain name, using interviewstreet.com for ServerName
[warn] NameVirtualHost *:80 has no VirtualHosts ... waiting apache2: Could not reliably determine the server's fully qualified domain name, using interviewstreet.com for ServerName
[warn] NameVirtualHost *:80 has no VirtualHosts [ OK ]

After some googling, I found the actual solution at http://serverfault.com/questions/1405/apache2-startup-warning-namevirtualhost-80-has-no-virtualhosts.

The reason why this happens is because of having NameVirtualHost in more than one place. In this case, it occurs at 2 different files, sites-available/default and ports.conf.

So, this is how we fixed this issue.

1. Removed the line “NameVirtualHost *” from sites-available/default.
2. Changed “NamedVirtualHost *:80″ to “NamedVirtualHost *” in ports.conf

Done. That fixes the problem. Now apache restart shows something like this.

root@interviewstreet:/etc/apache2/sites-available# /etc/init.d/apache2 restart
* Restarting web server apache2 ... waiting [ OK ]

3 interesting Codeigniter tips

Finally we’ve started doing all our development using a framework, Codeigniter. It has a small learning curve, simple to use and very flexible with how much you want to adhere to MVC pattern. You have the control to code every damn thing in the controller or have proper models and views to help the controller.

Three nice tips/tricks I found in Codeigniter after googling a lot.

1. How to print the last query executed by codeigniter when using active record?

The following function returns the sql query executed. You may need this for debugging purposes.

$this->db->last_query();

2. How to add a function in controller which can’t be accessed through URL?

Usually, if you add a function func in controller c, then it can be accessed by /c/func. If you want to code a function, which you don’t want people to access, then you need to name the function _func(). If you have a function named with a _ in front of it, then you can’t access it through the URL.

3. How to store the string generated by a view in a variable?

When you load a view using $this->load->view(‘view.php’, $data); the view gets rendered in the browser. But if you want to store the HTML string generated by the view in a variable, then add a third parameter TRUE, which will return the generated string.

The code will be
$output = $this->load->view("view.php", $data, TRUE);