Version 9 (modified by Jamie McClelland, 4 years ago) (diff)


Login Service

May First/People Link provides a web-based API for verifying login credentials called "login-service". It is designed to allow applications to verify that a given username and password is valid or that a given username exists.

In "check" mode it takes as input a username, password, and application id, and responds with either a no (indicating invalid) or a yes indicating a valid username and password or error.

In "user" mode it takes as input a username and application id, and responds with either a no (indicating the username doesn't exist) or a yes indicating a valid username or error.

Server side

The server is running a python twisted web application, available via git: git:// It is currently installed on in /usr/local/share/login-service, listens on port 8080, requires tls, and is configured to use the key and certificate.

The application is managed by runit (via /etc/sv/login-service), so it should restart when the system restarts.

The application runs as the login-service unix user. It also has access to it's own mysql username and password (configured via files in /etc/sv/login-service/env) that grant it the privilege of logging into the MySQL server on hay and of executing the get_salt and valid_hash MySQL procedures that enable it to verify a username and password witout having access to the table of usernames and passwords.

One environment variable set via the file /etc/sv/login-service/env/LS_APP_IDS contains a space separated list of randomly generated strings that act as an application id. The idea is that each application that we configure to use the service will share a secret that is stored in this file. The shared secret helps prevent dictionary attacks against the service.

Client side

Writing a client to interface with the login service is relatively easy.




if [ -z "$service" -o -z "$app_id" -o -z "$user" ]; then
  printf "Please pass service app_id and user as the first three arguments.\n"
  exit 2

if [ "$service" != "user" -a "$service" != "check" ]; then
  printf "Service must be user or check.\n"
  exit 2

if [ "$service" = "check" -a -z "$pass" ]; then
  printf "If you pass user as the service, the last argument should be a password.\n"
  exit 2

out=$(curl -s "${service}?user=${user}&password=${pass}&app_id=${app_id}")

[ "$out" = "yes" ] && exit 0
exit 1


mayfirstAuth is a simple python module (currently only installed on mcchesney), source below. It allows a writer of any python script to easily query the login-service.



from mayfirstAuth import auth

username = 'YOUR-USER-NAME'
password = 'YOUR-PASSWORD'
appid = 'YOUR-APP-ID'

check = auth(username, password, appid)

if check == "0":
    print 'Login success'
    print 'Login failure'



import requests

# set the login service URL
url = ''

def auth(username, password, appid):
    values = {'user' : username,
              'password' : password,
              'app_id' : appid}
    req = + "check", data=values)
    is_valid_user = req.text

    if is_valid_user == "yes":
        return "0"
    return "1"

def user(username):
    values = {'user' : username,
              'app_id' : appid}
    req = + user, data=values)
    is_valid_user = req.text

    if is_valid_user == "yes":
        return "0"
    return "1"



function authenticate_user($user, $password, $app_id) {
  $url = '' . urlencode($user) .
   '&password=' . urlencode($password) . '&app_id=' . $app_id;
  $out = file_get_contents($url);
  if($out == "yes") return TRUE; 
  return FALSE;

While GET functions are easier to write, POST functions are less likely to log your password (on the client side - logging is disabled on the server side).


function authenticate_user($user, $password, $app_id) {
        $url = '';
        $vars = 'user=' . urlencode($user) . '&password=' . urlencode($password) .
         '&app_id=' . urlencode($app_id);

        $ch = curl_init( $url );
        curl_setopt( $ch, CURLOPT_POST, 1);
        curl_setopt( $ch, CURLOPT_POSTFIELDS, $vars);
        curl_setopt( $ch, CURLOPT_HEADER, 0);
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);

        $response = curl_exec( $ch );

        if($response == "yes") return TRUE;
        return FALSE;