#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from __future__ import division, absolute_import, print_function, unicode_literals

import datetime
import hashlib
import json
import os
import random
import sys
import time
import urllib
from urlparse import urlparse

import tornado.autoreload
import tornado.gen
import tornado.httpclient
import tornado.httpserver
import tornado.web
import tornado.websocket
from tornado.httputil import url_concat
from tornado.log import app_log as log
from tornado.options import define, options
from tornado.web import HTTPError

from mpin_utils.common import (
    detectProxy,
    getLogLevel,
    Keys,
    Seed,
    SIGNATURE_EXPIRES_OFFSET_SECONDS,
    signMessage,
    Time,
)
from mpin_utils import secrets
from storage import get_storage_cls
from dynamic_options import (
    generate_dynamic_options,
    process_dynamic_options,
)

if os.name == "posix":
    from mpDaemon import Daemon
elif os.name == "nt":
    from mpWinService import Service as Daemon
else:
    raise Exception("Unsupported platform: {0}".format(os.name))


VERSION = '0.3'
BASE_DIR = os.path.dirname(__file__)
CONFIG_FILE = os.path.join(BASE_DIR, "config.py")
MOBILE_LOGIN_AUTHENTICATION_TIMEOUT_SECONDS = 10

PASS1_EXPIRES_TIME = 15
PERMITS_MIN, PERMITS_MAX = 7, 13


# OPTIONS

# general options
define("configFile", default=os.path.join(BASE_DIR, "config.py"), type=unicode)
define("address", default="127.0.0.1", type=unicode)
define("port", default=8011, type=int)
define("allowOrigin", default="*")
define("dynamicOptionsURL", default=None, type=unicode)

# debugging options
define("autoReload", default=False, type=bool)
define("logLevel", default="ERROR", type=unicode)

# time synchronization options
define("timePeriod", default=86400000, type=int)
define("syncTime", default=True, type=bool)

# security options
define("credentialsFile", default=os.path.join(BASE_DIR, "credentials.json"), type=unicode)
define("EntropySources", default="certivox:100", type=unicode)
define("seedValueLength", default=100, type=int)

# customer DTA service discovery options
define("DTALocalURL", default="", type=unicode)

# access number options
define("accessNumberExpireSeconds", default=60, type=int)
define("accessNumberExtendValiditySeconds", default=5, type=int)
define("accessNumberUseCheckSum", default=True, type=bool)

# authentication options
define("waitForLoginResult", default=False, type=bool)
define("VerifyUserExpireSeconds", default=3600, type=int)
define("maxInvalidLoginAttempts", default=3, type=int)
define("cacheTimePermits", default=True, type=bool)

# OTP options
define("requestOTP", default=False, type=bool)
define("OTTLength", default=16, type=int)

# RPA options
define("RPAVerifyUserURL", default="", type=unicode)
define("RPAPermitUserURL", default="", type=unicode)
define("RPAAuthenticateUserURL", default="", type=unicode)
define("RegisterForwardUserHeaders", default="", type=unicode)
define("LogoutURL", default="", type=unicode)

# PIN pad client options
define("rpsBaseURL", default="")
define("rpsPrefix", default="rps")
define("setDeviceName", default=False, type=bool)

# mobile client config
define("mobileUseNative", default=False, type=bool)
define("mobileConfig", default=None, type=list)
define("useNFC", default=False, type=bool)


# Mapping between local names of dynamic options and names from json
# in the form `remote_name`: `local_name`
# Only options that have mapping are processed
DYNAMIC_OPTION_MAPPING = {
    'time_synchronization': 'syncTime',
    'time_synchronization_period': 'timePeriod',
    'mobile_use_native': 'mobileUseNative',
    'mobile_client_config': 'mobileConfig',
}


# Dynamic options handlers
def handle_time_synchronization_update(updated, application, initial):

    log.debug("Handling time synchronization")
    if not any(x in updated for x in ('syncTime', 'timePeriod')) and not initial:
        log.debug("Nothing to do on time synchronization")
        return

    def _stop_scheduler():
            try:
                application.time_sync_scheduler.stop()
                log.debug("Stopped time sync schduler")
            except:
                pass
    if options.syncTime and (options.timePeriod > 0):
        _stop_scheduler()
        application.time_sync_scheduler \
            = tornado.ioloop.PeriodicCallback(
                Time.getTime,
                options.timePeriod,
                io_loop=application.io_loop)
        application.time_sync_scheduler.start()
        log.debug(
            "Started time sync schduler with period {0}"
            .format(options.timePeriod))
    else:
        _stop_scheduler()


# Convenience variable - list of dynamic options update handlers
DYNAMIC_OPTION_HANDLERS = [
    handle_time_synchronization_update,
]


# UTILITIES
def makeMPinID(userId, isMobile):
    endUserData = {
        "issued": str(Time.syncedNow()),
        "userID": userId,
        "mobile": int(isMobile or 0),
        "salt": os.urandom(16).encode("hex")
    }

    mpin_id = json.dumps(endUserData)

    return mpin_id.encode("hex")


def verifyToken(token):
    """A method for verifying the authentication token.

       n.b. The message variable should not be returned in a deployed application
    """
    successCode = int(token["successCode"])
    pinError = int(token["pinError"])

    # Get current time and token expired time
    expiresStr = token["expires"].replace(" ", "T").replace("Z", "")
    expiresTime = datetime.datetime.strptime(expiresStr, '%Y-%m-%dT%H:%M:%S')
    syncedTime = Time.syncedNow()

    # Check if token has expired.
    if syncedTime > expiresTime:
        fail = 1
        status = 401
        reason = "Authentication Failed. Token Expired."

    elif successCode != 0:
        if pinError == 0:  # No token.
            fail = 1
            status = 401
            reason = "Authentication Failed. Invalid Token."
        else:
            # Entering wrong PIN.
            fail = 1
            status = 401
            reason = "Authentication Failed. Invalid PIN."
    else:
        # Successful authentication
        fail = 0
        status = 200
        reason = "OK"

    return (fail, status, reason)


# BASE HANDLERS
class BaseHandler(tornado.web.RequestHandler):

    def set_default_headers(self):
        try:
            log.debug("Origin Header %s" % self.request.headers['Origin'])
            if self.request.headers['Origin'] in options.allowOrigin:
                self.set_header("Access-Control-Allow-Origin", self.request.headers['Origin'])
            elif "*" in options.allowOrigin:
                self.set_header("Access-Control-Allow-Origin", "*")
        except:
            log.debug("Origin header not defined")
        self.set_header("Access-Control-Allow-Credentials", "true")
        self.set_header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS")
        self.set_header("Access-Control-Allow-Headers", "Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, X-Requested-By, If-Modified-Since, X-File-Name, Cache-Control, WWW-Authenticate")

    def write_error(self, status_code, **kwargs):
        self.set_status(status_code, reason=self._reason)
        self.content_type = 'application/json'
        self.write({'version': VERSION, 'message': self._reason})

    def options(self, *args, **kwargs):
        self.set_status(200, reason="OK")
        self.content_type = 'application/json'
        self.write({'version': VERSION, 'message': "options request"})
        self.finish()
        return

    def finish(self, *args, **kwargs):
        if self._status_code == 401:
            self.set_header("WWW-Authenticate", "Authenticate")
        super(BaseHandler, self).finish(*args, **kwargs)

    @property
    def storage(self):
        return self.application.storage


class PrivateBaseHandler(BaseHandler):

    def prepare(self):
        # TODO: Check the remoteIP option
        # allow connections from whitelisted IP's
        # print self.request.remote_ip
        # self.set_status(404)
        # self.finish()
        pass


# PUBLIC HANDLERS
class ClientSettingsHandler(BaseHandler):
    def get(self):
        self.set_header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate")
        self.set_header("Pragma", "no-cache")
        self.set_header("Expires", "Sat, 26 Jul 1997 05:00:00 GMT")

        baseURL = "{0}/{1}".format(options.rpsBaseURL, options.rpsPrefix.strip("/"))
        params = {
            "certivoxURL": Keys.certivoxServer(),
            "signatureURL": "{0}/signature".format(baseURL),
            "registerURL": "{0}/user".format(baseURL),
            "timePermitsURL": "{0}/timePermit".format(baseURL),
            "timePermitsStorageURL": "{0}".format(Keys.timePermitsStorageURL),
            "setupDoneURL": "{0}/setupDone".format(baseURL),
            "mpinAuthServerURL": baseURL,
            "authenticateURL": options.RPAAuthenticateUserURL,
            "mobileAuthenticateURL": "{0}/authenticate".format(baseURL),
            "setDeviceName": options.setDeviceName,
            "accessNumberUseCheckSum": options.accessNumberUseCheckSum,

            "appID": Keys.app_id,
            "requestOTP": options.requestOTP,
            "seedValue": secrets.generate_random_number(
                self.application.server_secret.rng, options.seedValueLength),

            "useWebSocket": False,

            "accessNumberDigits": 7 if options.accessNumberUseCheckSum else 6,
            "cSum": 1,
            "useNFC": options.useNFC,
        }

        if not options.requestOTP:
            params["accessNumberURL"] = "{0}/accessnumber".format(baseURL)
            params["getAccessNumberURL"] = "{0}/getAccessNumber".format(baseURL)

        self.write(params)
        self.finish()


class RPSUserHandler(BaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def put(self, mpinId):

        try:
            data = json.loads(self.request.body)
            mobile = int(data.get("mobile", "0"))
            userId = data.get("userId")
            deviceName = data.get("deviceName", "")
            oldRegOTT = data.get("regOTT")

            if not userId:
                log.error("Missing userId")
                log.debug(self.request.body)
                self.set_status(400, reason="BAD REQUEST. INVALID USERID")
                self.finish()
                return

        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return

        if mpinId.strip("/"):
            mpinId = mpinId.strip("/")
            log.debug("Reactivation request for mpinId: {0}".format(mpinId))

            updateItem = self.storage.find(stage="register", mpinId=mpinId)
            if not updateItem:
                mpinId = None
                oldRegOTT = None
                log.error("Missing or invalid mpinID. Will generate a new mpinID")

            elif updateItem.regOTT != oldRegOTT:
                log.error("Missing or invalid regOTT")
                log.debug(self.request.body)
                self.set_status(400, reason="BAD REQUEST. INVALID REGOTT")
                self.finish()
                return

        if not mpinId:
            # Generate new mpinID
            updateItem = None
            mpinId = makeMPinID(userId, mobile)
            log.debug("New mpinID generated for user {0}: {1}".format(userId, mpinId))

        userData = data.get("userData")

        # Verify user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

        # Generate activateKey
        regOTT = oldRegOTT or secrets.generate_ott(options.OTTLength, self.application.server_secret.rng, "hex")
        activateKey = signMessage("{0}{1}".format(mpinId, regOTT), Keys.app_key)
        nowTime = Time.syncedNow()
        expireTime = nowTime + datetime.timedelta(seconds=options.VerifyUserExpireSeconds)

        requestBody = json.dumps({
            "userId": userId,
            "mpinId": mpinId,
            "mobile": mobile,
            "activateKey": activateKey,
            "expireTime": Time.DateTimeToISO(expireTime),
            "resend": bool(updateItem),
            "deviceName": deviceName,
            "userData": userData or ""
        })

        if updateItem:
            updateItem.delete()

        client = tornado.httpclient.AsyncHTTPClient()

        pr = urlparse(self.request.full_url())
        base_url = "{0}://{1}".format(pr.scheme, pr.netloc)

        headers = {
            "RPS-BASE-URL": base_url
        }

        # Forward headers to the RPA
        if options.RegisterForwardUserHeaders:
            allHeaders = options.RegisterForwardUserHeaders == "*"
            rHeaders = map(lambda x: x.strip().lower(), options.RegisterForwardUserHeaders.split(","))
            for h in self.request.headers:
                if allHeaders or (h.lower() in rHeaders):
                    headers[h] = self.request.headers[h]

        RPAVerifyUserURL = options.RPAVerifyUserURL

        if not RPAVerifyUserURL:
            log.error("RPAVerifyUserURL option not set! Unable to make Verify request")
            self.set_status(400, "RPAVerifyUserURL option not set.")
            self.finish()
            return

        # Make the verify request to the RPA
        response = yield tornado.gen.Task(client.fetch, RPAVerifyUserURL, method="POST", headers=headers, body=requestBody)

        if response.error:
            log.error("RPA verify request error: {0}. Code: {1}, Reason: {2}".format(response.error, response.code, response.reason))
            error = response.code
            if error >= 500:
                error = 500

            self.set_status(error)
            self.finish()
            return

        forceActivate = False
        if response.body:
            try:
                responseData = json.loads(response.body)
                forceActivate = responseData.get("forceActivate", forceActivate)
            except:
                log.error("RPA verify request: Invalid JSON response: {0}".format(response.body))
                self.set_status(500)
                self.finish()
                return

        if forceActivate:
            log.debug("RPA response: force_activate. Activating UserID: {0}".format(userId))

        if forceActivate:
            active = activateKey
        else:
            active = 0

        log.debug("New regOTT generated: {0}. ForceActivate: {1}".format(regOTT, forceActivate))

        self.storage.add(
            expire_time=expireTime,
            stage="register",
            mpinId=mpinId,
            regOTT=regOTT,
            active=active
        )

        # Response to the client
        responseData = {
            "mpinId": mpinId,
            "regOTT": regOTT,
            "expireTime": expireTime.isoformat(),
            "nowTime": nowTime.isoformat(),
            "active": forceActivate
        }

        self.write(responseData)
        self.finish()


class RPSSignatureHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self, mpinId):

        regOTT = self.get_argument("regOTT")

        log.debug("ClientSecret request for mpinID: {0}".format(mpinId))

        mpinData = json.loads(mpinId.decode("hex"))
        mobile = mpinData.get("mobile", 0)

        I = self.storage.find(stage="register", mpinId=mpinId)
        if not I:
            log.debug("MpinID {0} not found.".format(mpinId))
            self.set_status(400, "M-Pin ID not found.")
            self.finish()
            return

        # Verify regOTT
        if I.regOTT != regOTT:
            log.error("MpinID {0} regOTT does not match!".format(mpinId))
            I.delete()
            self.set_status(400, "M-Pin ID not found.")
            self.finish()
            return

        # Verify Activated
        if I.active != signMessage("{0}{1}".format(mpinId, regOTT), Keys.app_key):
            log.debug("MpinID {0} is not activated!".format(mpinId))
            self.set_status(401, "M-PinID not active.")
            self.finish()
            return

        # Get hash of M-PIN ID
        hash_mpin_id_hex = hashlib.sha256(mpinId.decode("hex")).hexdigest()

        # Get hash of UserID ID
        hash_user_id = hashlib.sha256('{user_id}{salt}'.format(
            user_id=mpinData['userID'],
            salt=hashlib.sha256(self.application.server_secret.server_secret).hexdigest(),
        )).hexdigest()

        # Generate signed params
        path = "clientSecret"
        expires = Time.syncedISO(seconds=SIGNATURE_EXPIRES_OFFSET_SECONDS)
        hash_user_id = ""
        M = str("%s%s%s%s%s" % (path, Keys.app_id, hash_mpin_id_hex, hash_user_id, expires))
        signature_hex = signMessage(M, Keys.app_key)

        param_values = {
            'app_id': Keys.app_id,
            'expires': expires,
            'hash_mpin_id': hash_mpin_id_hex,
            'hash_user_id': hash_user_id,
            'mobile': mobile,
            'signature': signature_hex,
        }

        url = "{0}/{1}".format(options.DTALocalURL.rstrip("/"), path)
        urlParams = url_concat(url, param_values)

        client = tornado.httpclient.AsyncHTTPClient()
        response = yield tornado.gen.Task(client.fetch, urlParams, method="GET")

        if response.error:
            log.error("DTA clientSecret failed, URL: {0}. Code: {1}, Reason: {2}".format(urlParams, response.code, response.reason))
            self.set_status(500)
            self.finish()
            return

        if response.body:
            try:
                responseData = json.loads(response.body)
                clientSecretShare = responseData["clientSecret"]
            except:
                log.error("DTA /clientSecret Failed. Invalid JSON response".format(response.body))
                self.set_status(500)
                self.finish()
                return

        I.delete()

        params = urllib.urlencode(param_values)
        data = {
            "params": params,
            "clientSecretShare": clientSecretShare
        }

        self.write(data)
        self.finish()


class RPSTimePermitHandler(BaseHandler):

    def __init__(self, *args, **kwargs):
        super(RPSTimePermitHandler, self).__init__(*args, **kwargs)
        self.http_client = tornado.httpclient.AsyncHTTPClient()

    @tornado.gen.coroutine
    def get_time_permits(self, hash_mpin_id_hex, signature):
        # Get time permit from the local D-TA
        url = url_concat(
            "{0}/{1}".format(options.DTALocalURL.rstrip("/"), "timePermits"), {
                'hash_mpin_id': hash_mpin_id_hex,
                'signature': signature,
                'count': random.randint(PERMITS_MIN, PERMITS_MAX) if options.cacheTimePermits else 1})
        response = yield self.http_client.fetch(url)

        if response.error:
            log.error("DTA timePermit failed, URL: {0}. Code: {1}, Reason: {2}".format(url, response.code, response.reason))
            raise HTTPError(500)

        if response.body:
            try:
                response_data = json.loads(response.body)
                raise tornado.gen.Return(response_data["timePermits"])
            except (ValueError, KeyError):
                log.error("DTA /timePermit Failed. Invalid JSON response".format(
                    response.body))
                raise HTTPError(500)

    def cache_time_permits(self, time_permits, hash_mpin_id_hex):
        # Cache them in storage
        for date_epoch, time_permit in time_permits.iteritems():
            try:
                date_epoch = int(date_epoch)
            except ValueError:
                log.error("DTA /timePermit Failed. Date invalid integer")
                raise HTTPError(500)

            self.storage.add(
                expire_time=datetime.datetime.fromtimestamp(date_epoch * 60 * 1440) + datetime.timedelta(days=1),
                time_permit_id=hash_mpin_id_hex,
                time_permit_date=date_epoch,
                time_permit=time_permit)

    @tornado.gen.coroutine
    def get_time_permit(self, hash_mpin_id_hex, date_epoch, signature):
        """Get time permit from cache or request new."""
        if options.cacheTimePermits:
            time_permit_item = self.storage.find(time_permit_id=hash_mpin_id_hex, time_permit_date=date_epoch)
            if time_permit_item:
                # Get time permit from cache
                raise tornado.gen.Return(time_permit_item.time_permit)

        # No cached time permits for this mpin id, request new from D-TA
        time_permits = yield self.get_time_permits(hash_mpin_id_hex, signature)
        if options.cacheTimePermits:
            self.cache_time_permits(time_permits, hash_mpin_id_hex)

        # Return the one for today
        if str(date_epoch) not in time_permits:
            log.error("DTA /timePermit Failed. No time permit for today")
            raise HTTPError(500)
        raise tornado.gen.Return(time_permits[str(date_epoch)])

    @tornado.gen.coroutine
    def get(self, mpin_id):
        # Check revocation status of mpin id.
        if options.RPAPermitUserURL:
            response = yield self.http_client.fetch(
                url_concat(options.RPAPermitUserURL, {"mpin_id": mpin_id}),
                raise_error=False)

            if response.code != 200:
                # RPA rejects this mpin id
                raise HTTPError(response.code)

        hash_mpin_id_hex = hashlib.sha256(mpin_id.decode("hex")).hexdigest()
        today_epoch = secrets.today()
        signature = signMessage(hash_mpin_id_hex, Keys.app_key)
        time_permit = yield self.get_time_permit(hash_mpin_id_hex, today_epoch, signature)

        self.set_header("Cache-Control", "no-cache")
        self.finish({
            "date": today_epoch,
            "signature": signature,
            "storageId": hash_mpin_id_hex,
            'message': "M-Pin Time Permit Generated",
            'timePermit': time_permit,
            'version': VERSION,
        })


class RPSSetupDoneHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self, mpinId):
        log.debug("Setup done for mpinId: {0}".format(mpinId))
        self.set_status(200)
        self.finish()


class RPSGetAccessNumberHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        # Generate request for MPinWIDServer for WID
        wId = secrets.generate_random_webid(self.application.server_secret.rng, options.accessNumberUseCheckSum)

        while wId is None or (self.storage.find(stage="auth", webID=wId)):
            if wId is None:
                log.debug("WebId is None".format(wId))
            else:
                log.debug("WebId {0} already exists. Generating a new one".format(wId))
            wId = secrets.generate_random_webid(self.application.server_secret.rng, options.accessNumberUseCheckSum)

        log.debug("New webId generated: {0}." .format(wId))

        webOTT = secrets.generate_ott(options.OTTLength, self.application.server_secret.rng, "hex")

        nowTime = Time.syncedNow()
        expirePinPadTime = nowTime + datetime.timedelta(seconds=options.accessNumberExpireSeconds)
        expireTime = expirePinPadTime + datetime.timedelta(seconds=options.accessNumberExtendValiditySeconds)

        self.storage.add(stage="auth", expire_time=expireTime, webOTT=webOTT, wid=wId)

        params = {
            "ttlSeconds": options.accessNumberExpireSeconds,
            "accessNumber": wId,
            "webOTT": webOTT,
            "localTimeStart": Time.DateTimetoEpoch(nowTime),
            "localTimeEnd": Time.DateTimetoEpoch(expirePinPadTime)
        }

        self.write(params)
        self.finish()


class RPSAccessNumberHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        try:
            data = json.loads(self.request.body)
            webOTT = data["webOTT"]
        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return

        I = self.storage.find(stage="auth", webOTT=webOTT)
        if not I:
            log.debug("Cannot find webOTT: {0}".format(webOTT))

            self.set_status(404)
            self.finish()
            return

        authOTT = I.authOTT
        if authOTT and (str(I.status) == "200"):
            self.write({"authOTT": authOTT})
            self.finish()
        else:
            if not authOTT:
                log.debug("authOTT not set for webOTT: {0}".format(webOTT))
            else:
                log.debug("Auth status for webOTT: {0}: {1}".format(webOTT, I.status))
            self.set_status(401)
            self.finish()


class RPSAuthenticateHandler(BaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        try:
            data = json.loads(self.request.body)
            data = data["mpinResponse"]
            authOTT = data["authOTT"]
        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return
        except KeyError:
            log.error("Invalid JSON data structure")
            log.debug(data)
            self.set_status(400, reason="BAD REQUEST. INVALID DATA")
            self.finish()
            return

        I = self.storage.find(stage="auth", authOTT=authOTT)

        if not I:
            log.error("Invalid or expired authOTT")
            status = 412
            message = "Invalid or expired access number"
            userId = ""
            mpinId = ""
            response = {"message": message}

        else:
            authToken = I.authToken
            mpinId = authToken["mpin_id"].encode("hex")
            identity = json.loads(authToken["mpin_id"])
            userId = identity["userID"]

            (fail, status, reason) = verifyToken(authToken)

            aI = self.storage.find(stage="attempts", mpinId=mpinId)
            attemptsCount = aI and aI.attemptsCount or 0
            if attemptsCount >= options.maxInvalidLoginAttempts:
                fail = 1

            if fail == 0:
                # Delete invalid login attempts if any
                if aI:
                    aI.delete()

                # Authentication successful
                message = "Authentication successful"

                # Wait for browser authentication and get Logout information
                I.update(status=status, message=message)

                main_loop = tornado.ioloop.IOLoop.instance()

                # Wait until the browser is ready or timeout occurs
                timeOut = Time.syncedNow(seconds=MOBILE_LOGIN_AUTHENTICATION_TIMEOUT_SECONDS)
                while (not I.browserReady) and (Time.syncedNow() < timeOut):
                    yield tornado.gen.Task(main_loop.add_timeout, time.time() + 1)

                # Get the new status. Status can be changed with the /loginResult request
                if status != I.status:
                    status = I.status
                    message = I.message
                    response = {"message": message}

                elif I.browserReady:
                    logoutURL = I.logoutURL or ""
                    logoutData = I.logoutData or ""
                    response = {"logoutURL": logoutURL, "logoutData": logoutData}
                else:
                    # Timeout occured
                    status = 408
                    message = "Authentication timed out"
                    response = {"message": message}

            else:
                attemptsCount += 1
                if aI:
                    aI.update(attemptsCount=attemptsCount)
                else:
                    self.storage.add(stage="attempts", mpinId=mpinId, attemptsCount=attemptsCount)

                if attemptsCount >= options.maxInvalidLoginAttempts:
                    status = 410

                log.debug("Wrong PIN for user {0}.".format(userId))
                message = "Wrong PIN."
                response = {"message": message}
                I.update(status=status, message=message)

        self.set_status(status, message)
        self.write(response)
        self.finish()


class StatusHandler(BaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        reason = "active"
        self.set_status(200, reason=reason)
        self.write({'version': VERSION, 'message': reason})

        self.finish()


class DefaultHandler(BaseHandler):
    def get(self, input):
        reason = "URI NOT FOUND"
        self.set_status(404, reason=reason)
        self.write({'version': VERSION, 'service_name': 'M-Pin authentication server', 'message': reason})
        return

    def post(self, input):
        reason = "URI NOT FOUND"
        self.set_status(404, reason=reason)
        self.write({'version': VERSION, 'service_name': 'M-Pin authentication server', 'message': reason})
        return

    def put(self, input):
        reason = "URI NOT FOUND"
        self.set_status(404, reason=reason)
        self.write({'version': VERSION, 'service_name': 'M-Pin authentication server', 'message': reason})
        return

    def delete(self, input):
        reason = "URI NOT FOUND"
        self.set_status(404, reason=reason)
        self.write({'version': VERSION, 'service_name': 'M-Pin authentication server', 'message': reason})
        return


# AUTHENTICATION HANDLER
class Pass1Handler(BaseHandler):
    """
    ..  apiTextStart

    *Description*

      Implements the first pass of the M-Pin Protocol

    *URL structure*

      ``/pass1``

    *Version*

      0.3

    *HTTP Request Method*

      POST

    *Request Data*

      JSON request::

        {
          "mpin_id":  "7b22...227d",
          "U":    "0409...3d9c",
          "UT":   "0402...d1d1",
          "pass" : 1
        }

      mpin_id is the hex encoded M-Pin ID, U is x.hash(mpin_id) and UT is
      x.(hash(mpin_id) + hash(data||hash(mpin_id)))

    *Returns*

      JSON response::

        {
          "y" : "212a...8d08",
          "version" : "0.3",
          "message" : "OK",
          "pass" : 1
        }

      y  is a 256 bit random value.

    *Status-Codes and Response-Phrases*

      ::

        Status-Code          Response-Phrase

        200                  OK
        403                  Invalid data received. <argument> argument missing
        403                  Invalid data received. No JSON object could be decoded
        403                  Invalid data received. Non-hexadecimal digit found
        500                  Failed to generate y
        500                  Failed to add pass one to memory

    ..  apiTextEnd

    """
    def post(self):
        # Remote request information
        if 'User-Agent' in self.request.headers.keys():
            UA = self.request.headers['User-Agent']
        else:
            UA = 'unknown'
        request_info = '%s %s %s %s ' % (self.request.path, self.request.remote_ip, UA, Time.syncedISO())

        try:
            receive_data = tornado.escape.json_decode(self.request.body)
            mpin_id = receive_data['mpin_id'].decode("hex")
            ut_hex = receive_data['UT']
            u_hex = receive_data['U']
        except KeyError as ex:
            reason = "Invalid data received. %s argument missing" % ex.message
            log.error("%s %s" % (request_info, reason))
            self.set_status(403, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        except (ValueError, TypeError) as ex:
            reason = "Invalid data received. %s" % ex.message
            log.error("%s %s" % (request_info, reason))
            self.set_status(403, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        log.debug("%s %s" % (request_info, receive_data))

        # Server generates Random number Y and sends it to Client
        try:
            y_hex = self.application.server_secret.get_pass1_value()
        except secrets.SecretsError as e:
            log.error(e.message)
            self.set_status(500, reason=e.message)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': e.message})
            self.finish()
            return

        # Store Pass1 values
        self.storage.add(
            expire_time=Time.syncedISO(seconds=PASS1_EXPIRES_TIME),
            stage="pass1",
            mpinId=mpin_id.encode('hex'),
            ut=ut_hex,
            u=u_hex,
            y=y_hex,
        )

        log.info("%s Stored Pass1 values" % request_info)

        reason = "OK"
        self.set_status(200, reason=reason)
        self.content_type = 'application/json'
        return_data = {
            'version': VERSION,
            'y': y_hex,
            'pass': 1,
            'message': reason
        }
        log.debug("%s %s" % (request_info, return_data))
        self.write(return_data)
        self.finish()
        return


class Pass2Handler(BaseHandler):
    """
    ..  apiTextStart

    *Description*

      Implements the second pass of the M-Pin Protocol. The result will be the authOTP.
      At this point the authentication token has also been written to the RPS.
      An authOTT will always be returned even if authentication fails.

    *URL structure*

      ``/pass2``

    *Version*

      0.3

    *HTTP Request Method*

      POST

    *Request Data*

      JSON request::

        {
          "WID" : "123456"
          "V" : "0411...05f6a",
          "pass" : 2,
          "OTP" : <1||0>
        }

      WID is web identifier used for mobile authentication
      When OTP is set to one this indicates that the radius OTP should be
      generated.  V is a parameter used to perform the final step of the M-Pin
      algorithm.

    *Returns*

      JSON response::

        {
          "OTP": "155317",
          "authOTT": "31ba0ed5efb75d91ef69a2b7eb1d3a26",
          "pass": 2,
          "version": "0.3"
        }

      OTP is the radius one time password. authOTT is the password used to log into the
      Customer's website.

    *Status-Codes and Response-Phrases*

      ::

        Status-Code          Response-Phrase

        200                  OK
        403                  Invalid data received. <argument> argument missing
        403                  Invalid data received. No JSON object could be decoded
        403                  Invalid data received. Non-hexadecimal digit found
        500                  Pass one data is not in memory

    ..  apiTextEnd

    """
    @tornado.gen.coroutine
    def post(self):
        # Remote request information
        if 'User-Agent' in self.request.headers.keys():
            UA = self.request.headers['User-Agent']
        else:
            UA = 'unknown'
        request_info = '%s %s %s %s ' % (self.request.path, self.request.remote_ip, UA, Time.syncedISO())

        try:
            receive_data = tornado.escape.json_decode(self.request.body)
            mpin_id_hex = receive_data['mpin_id']
            mpin_id = mpin_id_hex.decode('hex')
            WID = receive_data['WID']
            OTPEn = receive_data['OTP']
            v_data = receive_data['V'].decode("hex")
        except KeyError as ex:
            reason = "Invalid data received. %s argument missing" % ex.message
            log.error("%s %s" % (request_info, reason))
            self.set_status(403, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        except (ValueError, TypeError) as ex:
            reason = "Invalid data received. %s" % ex.message
            log.error("%s %s" % (request_info, reason))
            self.set_status(403, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        log.debug("%s %s" % (request_info, receive_data))

        # Get pass one values
        pass1Value = self.storage.find(stage="pass1", mpinId=mpin_id_hex)

        if pass1Value:
            u = pass1Value.u.decode("hex")
            ut = pass1Value.ut.decode("hex")
            y = pass1Value.y.decode("hex")
        else:
            reason = "Invalid pass one data"
            log.error("%s %s" % (request_info, reason))
            self.set_status(500, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        log.info("%s loaded Pass1 values" % request_info)

        # Generate OTP value
        if int(OTPEn) == 1:
            OTP = "{0:06d}".format(
                secrets.generate_otp(self.application.server_secret.rng))
        else:
            OTP = '0'

        log.info("%s generate OTP" % request_info)

        successCode = self.application.server_secret.validate_pass2_value(
            mpin_id, u, ut, y, v_data)

        pinError = 0
        pinErrorCost = 0

        # Authentication Token expiry
        expires = Time.syncedISO(seconds=SIGNATURE_EXPIRES_OFFSET_SECONDS)

        # Form Authentication token
        token = {
            "mpin_id": mpin_id,
            "mpin_id_hex": mpin_id_hex,
            "successCode": successCode,
            "pinError": pinError,
            "pinErrorCost": pinErrorCost,
            "expires": expires,
            "WID": WID,
            "OTP": OTP
        }
        log.debug("%s M-Pin Auth token: %s" % (request_info, token))

        # Form authentication 128 hex encoded One Time Password
        authOTT = secrets.generate_auth_ott(self.application.server_secret.rng)

        # Form message to return to client #
        return_data = {
            'version': VERSION,
            'pass': 2,
            'authOTT': authOTT
        }

        if int(OTPEn) == 1:
            return_data['OTP'] = OTP

        if WID != "0":
            # Login with mobile
            I = self.storage.find(stage="auth", wid=WID)

            wid_flow = "wid"
            flow = "mobile"

            # if not I:
            #     log.error("Invalid or expired access number: {0} for mpinid: {1}".format(WID, mpinId))
            #     self.set_status(412, reason="INVALID OR EXPIRED ACCESS NUMBER")
            #     self.finish()
            #     return

            if I:
                I.update(authOTT=authOTT, mpinid=mpin_id, authToken=token)

        else:
            wid_flow = "browser"

            if int(token.get("OTP", "0")) != 0:
                flow = "OTP"
            else:
                flow = "Browser"

            self.storage.add(
                expire_time=Time.ISOtoDateTime(expires),
                stage="auth",
                authOTT=authOTT,
                mpinId=mpin_id,
                wid="",
                webOTT=0,
                authToken=token
            )

        log.debug("New M-Pin Authentication token / {0}. Flow: {1}".format(wid_flow, flow))

        # Always send 200 to PIN Pad even if the user is not authenticated
        reason = "OK"
        log.debug("%s %s" % (request_info, return_data))
        self.set_status(200, reason=reason)
        self.content_type = 'application/json'
        self.write(return_data)
        self.finish()
        return


# PRIVATE HANDLERS
class ManageGetStackInfoHandler(PrivateBaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        # Get signed API settings

        path = "apiSettings"
        expires = Time.syncedISO(seconds=SIGNATURE_EXPIRES_OFFSET_SECONDS)
        M = "{0}{1}{2}" .format(path, Keys.app_id, expires)
        signature_hex = signMessage(M, Keys.app_key)

        param_values = {
            'app_id': Keys.app_id,
            'expires': expires,
            'signature': signature_hex,
        }

        url = "{0}/{1}".format(Keys.api_url.rstrip("/"), path)
        urlParams = url_concat(url, param_values)

        client = tornado.httpclient.AsyncHTTPClient()
        response = yield tornado.gen.Task(client.fetch, urlParams, method="GET")

        status = 200

        if (response.error):
            log.error("API Request Error URL: {0}: {1}: {2}".format(url, response.error, response.body))
            status = 500
            self.set_status(status)
            self.finish()
            return

        resp_data = None
        try:
            resp_data = json.loads(response.body)
        except ValueError:
            log.error("Cannot decode JSON response from API {0}: {1}".format(url, response.body))
            status = 500
            self.set_status(status)
            self.finish()
            return

        expires = Time.syncedISO(hours=1)
        M = "{0}{1}" .format(Keys.app_id, expires)
        signature = signMessage(M, Keys.app_key)

        manage_auth_params = {
            "signature": signature,
            "expires": expires,
            "app_id": Keys.app_id
        }

        result = {
            "managementConsoleURL": resp_data.get("managementConsoleURL", ""),
            "license_info": resp_data.get("license_info", {}),
            "manage_auth": manage_auth_params
        }

        self.write(result)
        self.finish()


class UserHandler(PrivateBaseHandler):
    def post(self, mpinId):
        log.debug("Request for activationg mpinid: {0}".format(mpinId))

        try:
            data = json.loads(self.request.body)
            activateKey = data["activateKey"]
        except:
            log.error("Invalid JSON request: {0}".format(self.request.body))
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return

        I = self.storage.find(stage="register", mpinId=mpinId)
        if not I:
            log.debug("MpinID {0} not found.".format(mpinId))
            self.set_status(401, "M-Pin ID not found.")
            self.finish()
            return

        I.update(active=activateKey)
        self.set_status(200)
        self.finish()


class AuthenticateHandler(PrivateBaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        OTP = ""

        try:
            data = json.loads(self.request.body)
            authOTT = data["authOTT"]
        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return
        except KeyError:
            log.error("Invalid JSON data structure")
            log.debug(data)
            self.set_status(400, reason="BAD REQUEST. INVALID DATA")
            self.finish()
            return

        I = self.storage.find(stage="auth", authOTT=authOTT)

        if not I:
            log.error("Invalid or expired authOTT: {0}".format(authOTT))
            status = 408
            message = "Expired authentication request"
            userId = ""
            mpinId = ""
        else:
            authToken = I.authToken
            mpinId = authToken["mpin_id"].encode("hex")
            identity = json.loads(authToken["mpin_id"])
            userId = identity["userID"]

            if authToken.get("OTP", "0") != "0":
                OTP = authToken["OTP"]

            log.debug("authToken: {0}".format(authToken))

            if I.status:
                # Mobile authentication, status already set
                status = I.status
                message = I.message

                # get logout data
                logoutURL = data.get("logoutURL") or options.LogoutURL
                logoutData = data.get("logoutData")
                # If logoutURL is set, the mobile app will make a request to that URL
                # If logoutData is set, the request method will be POST otherwise it will be GET

                # If option waitForLoginResult is set, browserReady flag will be set on /loginResult request
                # from the RPA
                browserReady = (not options.waitForLoginResult)

                I.update(logoutData=logoutData, logoutURL=logoutURL, browserReady=browserReady)

                if not options.waitForLoginResult:
                    I.delete()
            else:
                (fail, status, reason) = verifyToken(authToken)

                aI = self.storage.find(stage="attempts", mpinId=mpinId)
                log.debug("aI: {0}".format(aI))
                attemptsCount = aI and aI.attemptsCount or 0
                log.debug("attemptsCount: {0}".format(attemptsCount))
                if attemptsCount >= options.maxInvalidLoginAttempts:
                    fail = 1

                if fail == 0:
                    # Authentication successful
                    message = "Authentication successful"
                    if aI:
                        aI.delete()
                else:
                    attemptsCount += 1
                    if aI:
                        aI.update(attemptsCount=attemptsCount)
                    else:
                        self.storage.add(stage="attempts", mpinId=mpinId, attemptsCount=attemptsCount)

                    if attemptsCount >= options.maxInvalidLoginAttempts:
                        status = 410

                    log.debug("Wrong PIN for user {0}.".format(userId))
                    message = "Wrong PIN."

                if not options.waitForLoginResult:
                    I.delete()

        returnData = {
            "userId": userId,
            "mpinId": mpinId,
            "status": status,
            "message": message
        }

        if OTP:
            returnData["OTP"] = OTP

        self.set_status(status, message)
        self.write(returnData)
        self.finish()


class LoginResultHandler(PrivateBaseHandler):

    def post(self):
        if not options.waitForLoginResult:
            self.set_status(404)
            self.finish()
            return

        try:
            data = json.loads(self.request.body)
            authOTT = data["authOTT"]
            status = data["status"]
        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return
        except KeyError:
            log.error("Invalid JSON data structure")
            log.debug(data)
            self.set_status(400, reason="BAD REQUEST. INVALID DATA")
            self.finish()
            return

        I = self.storage.find(stage="auth", authOTT=authOTT)

        if not I:
            log.error("Invalid or expired authOTT")
            self.set_status(408, reason="Invalid or expired authOTT")
            self.finish()
            return

        if int(status) != 200:
            I.update(status=status, message=data.get("message", I.message), browserReady=True)
        else:
            # Get the logout data
            # Logout data can be set on the previous /authenticate request as well.
            logoutURL = data.get("logoutURL") or I.logoutURL or options.LogoutURL
            logoutData = data.get("logoutData") or I.logoutData
            # If logoutURL is set, the mobile app will make a request to that URL
            # If logoutData is set, the request method will be POST otherwise it will be GET

            I.update(logoutData=logoutData, logoutURL=logoutURL, browserReady=True)

        I.delete()


class DynamicOptionsHandler(PrivateBaseHandler):
    @tornado.web.asynchronous
    def post(self):
        if options.dynamicOptionsURL:
            process_dynamic_options(
                DYNAMIC_OPTION_MAPPING,
                DYNAMIC_OPTION_HANDLERS,
                application=self.application)
            self.set_status(200, 'OK')
        else:
            self.set_status(403, 'Dynamic options are disabled')
        self.finish()

    def get(self):
        if options.dynamicOptionsURL:
            self.set_status(200, 'OK')
            self.write(generate_dynamic_options(DYNAMIC_OPTION_MAPPING))
        else:
            self.set_status(403, 'Dynamic options are disabled')


class MobileConfigHandler(BaseHandler):
    def get(self):
        if not options.mobileConfig:
            self.set_status(403, 'No config is available')
        elif not options.mobileUseNative:
            self.set_status(404, 'Native client is disabled')
        else:
            self.set_status(200, 'OK')
            self.write(json.dumps(options.mobileConfig))


# MAIN
class Application(tornado.web.Application):
    def __init__(self):
        rpsPrefix = options.rpsPrefix.strip("/")
        handlers = [
            (r"/user/([0-9A-Fa-f]+)", UserHandler),  # POST
            (r"/{0}/user(/?[0-9A-Fa-f]*)".format(rpsPrefix), RPSUserHandler),  # PUT
            (r"/{0}/signature/([0-9A-Fa-f]+)".format(rpsPrefix), RPSSignatureHandler),  # GET
            (r"/{0}/timePermit/([0-9A-Fa-f]+)".format(rpsPrefix), RPSTimePermitHandler),  # GET
            (r"/{0}/setupDone/([0-9A-Fa-f]+)".format(rpsPrefix), RPSSetupDoneHandler),  # POST
            (r"/{0}/accessnumber".format(rpsPrefix), RPSAccessNumberHandler),  # POST
            (r"/{0}/getAccessNumber".format(rpsPrefix), RPSGetAccessNumberHandler),  # POST
            (r"/{0}/clientSettings".format(rpsPrefix), ClientSettingsHandler),
            (r"/{0}/authenticate".format(rpsPrefix), RPSAuthenticateHandler),  # POST, for mobile login
            # Authentication
            (r"/{0}/pass1".format(rpsPrefix), Pass1Handler),
            (r"/{0}/pass2".format(rpsPrefix), Pass2Handler),

            (r"/authenticate", AuthenticateHandler),  # POST

            (r"/manage/getStackInfo", ManageGetStackInfoHandler),  # GET

            (r"/loginResult", LoginResultHandler),  # POST

            (r"/status", StatusHandler),
            (r"/dynamicOptions", DynamicOptionsHandler),  # POST, GET
            (r"/{0}/mobileConfig".format(rpsPrefix), MobileConfigHandler),  # GET
            (r"/(.*)", DefaultHandler),
        ]
        settings = {}
        super(Application, self).__init__(handlers, **settings)

        Seed.getSeed(options.EntropySources)  # Get seed value for random number generator
        self.server_secret = secrets.ServerSecret(
            Seed.seedValue,
            Keys.app_id,
            Keys.app_key)

        log.debug("Using storage: {0}".format(options.storage))
        storage_cls = get_storage_cls()
        self.storage = storage_cls(
            tornado.ioloop.IOLoop.instance(),
            "stage,mpinId",
            "stage,authOTT",
            "stage,wid",
            "stage,webOTT",
            "time_permit_id,time_permit_date"
        )


def main():
    options.parse_command_line()

    if os.path.exists(options.configFile):
        try:
            options.parse_config_file(options.configFile)
            options.parse_command_line()
        except Exception, E:
            print("Invalid config file {0}".format(options.configFile))
            print(E)
            sys.exit(1)

    # Set Log level
    log.setLevel(getLogLevel(options.logLevel))

    detectProxy()

    # Load the credentials from file
    log.info("Loading credentials")
    try:
        credentialsFile = options.credentialsFile
        Keys.loadFromFile(credentialsFile)
    except Exception as E:
        log.error("Error opening the credentials file: {0}".format(credentialsFile))
        log.error(E)
        sys.exit(1)

    # TMP fix for 'ValueError: I/O operation on closed epoll fd'
    # Fixed in Tornado 4.2
    tornado.ioloop.IOLoop.instance()

    # Sync time to CertiVox time server
    if options.syncTime:
        Time.getTime(wait=True)

    Keys.getAPISettings(wait=True)

    log.info("Server starting on {0}:{1}...".format(options.address, options.port))

    http_server = Application()
    http_server.listen(options.port, options.address, xheaders=True)
    main_loop = tornado.ioloop.IOLoop.instance()
    http_server.io_loop = main_loop

    if options.autoReload:
        log.debug("Starting autoreloader")

        tornado.autoreload.watch(CONFIG_FILE)
        tornado.autoreload.start(main_loop)

    process_dynamic_options(
        DYNAMIC_OPTION_MAPPING,
        DYNAMIC_OPTION_HANDLERS,
        application=http_server,
        initial=True)

    log.info("Server started. Listening on {0}:{1}".format(options.address, options.port))
    main_loop.start()


class ServiceDaemon(Daemon):
    def run(self):
        main()


if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1].lower() in ("start", "stop"):
        action = sys.argv.pop(1)
        logFile = os.path.join(BASE_DIR, "rps.log")
        pidFile = os.path.join(BASE_DIR, "rps.pid")

        daemon = ServiceDaemon(pidfile=pidFile, stdout=logFile, stderr=logFile)
        if action == "start":
            log.info("Starting as daemon. Log file: {0}".format(logFile))
            daemon.start()
        elif action == "stop":
            log.info("Stopping daemon...")
            daemon.stop()
            sys.exit()
    else:
        try:
            main()
        except Exception as e:
            log.error(str(e))
            sys.exit(1)
