Automated Short Term Rental Accommodation Licence Integrity Checking System (ASTRALICS)

Problem

City of Vancouver recently regulated Airbnb and other short term rentals. Hosts are required to obtain a licence from the city and platforms are required to deactivate hosts without a valid licence. Recent news reports indicate that hosts have been getting away with fake numbers as there’s currently no mechanism for platforms to validate licence number.

Solution

Automated Short Term Rental Accommodation Licence Integrity Checking System (ASTRALICS ) is a proposed application programming interface (API) intended for City of Vancouver to publish, which Airbnb can use to validate licence numbers.

  1. Upon a host entering the licence number, Airbnb sends licence number, street number, street name, and unit number (in the case of strata units) to ASTRALICS.
  2. ASTRALICS checks the City of Vancouver licence database to see if an entry matching the request data exists in the system.
  3. If an entry is found, ASTRALICS responds with “valid”. Airbnb will accept the licence number
  4. If an entry is not found, ASTRALICS responds with “invalid”. Airbnb will reject the licence number.

Implementation

I have created a fully functional ASTRALICS prototype as 65-line Azure function in Java. It can be easily ported to other languages.

Demonstration

I have created an example licence database as follows:

 

LICENCENUMBER STREETNAME STREETNUMBER UNITNUMBER
555-1000 Robertson Street 2002
555-1001 Gregor Drive 1001 111

If you access ASTRALICS API with a valid licence number, as in the request below, you will get “valid” as the response.

https://astralics.azurewebsites.net/api/validate?licencenumber=555-1001&streetnumber=1001&streetname=Gregor%20Drive&unitnumber=111

If you access ASTRALICS API with a invalid licence, as in the request below, you will get “invalid” as the response.

https://astralics.azurewebsites.net/api/validate?licencenumber=12345&streetnumber=2002&streetname=Robertson%20Street

Source Code

package ca.rezel.astralics;

import java.sql.*;
import java.util.*;
import com.microsoft.azure.serverless.functions.annotation.*;
import com.microsoft.azure.serverless.functions.*;

/**
 * Automated Short Term Rental Accommodation Licence Integrity Checking System (ASTRALICS).
 * Author: Rohana Rezel
 * Licence: MIT Licence
 */

public class Function {
    @FunctionName("validate")
    public HttpResponseMessage<String> hello(
            @HttpTrigger(name = "req", methods = {"get"}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        String licenceNumber = request.getQueryParameters().get("licencenumber");
        String unitNumber = request.getQueryParameters().get("unitnumber");
        String streetNumber = request.getQueryParameters().get("streetnumber");
        String streetName = request.getQueryParameters().get("streetname");
        HttpResponseMessage<String> returnValue = request.createResponse(500, "Server error");
        if (licenceNumber==null || streetNumber == null || streetName == null) {
            return request.createResponse(400, "licencenumber, streetnumber and streetname are required");
        } else {
            Connection connection;
            try {
                String url = "jdbc:sqlserver:YOUR_CONNECTION_STRING_HERE";
                connection = DriverManager.getConnection(url);

                String selectSql = "SELECT * from Licence WHERE licenceNumber=? AND streetNumber=? AND streetName=?";
                if (unitNumber != null) {
                    selectSql += " AND unitNumber=?";
                }

                try {
                    PreparedStatement statement = connection.prepareStatement(selectSql);
                    statement.setString(1, licenceNumber);
                    statement.setString(2, streetNumber);
                    statement.setString(3, streetName);
                    if (unitNumber != null) {
                        statement.setString(4, unitNumber);
                    }
                    ResultSet resultSet = statement.executeQuery();
                    if (resultSet.next()) {
                        returnValue = request.createResponse(200, "valid");
                    } else {
                        returnValue = request.createResponse(200, "invalid");
                    }
                    connection.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return returnValue;
    }
}