<?php

/**
 * @author buchhofer
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is protected by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2014 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 *
 */

namespace Sso\RestBundle\Controller;

use FOS\RestBundle\View\View;
use Symfony\Component\HttpFoundation\Request;
use JMS\SecurityExtraBundle\Annotation\Secure;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use FOS\RestBundle\Controller\Annotations\NamePrefix;
use FOS\RestBundle\Controller\Annotations\RequestParam;

/**
 * Class PdfController
 * @package StepsBox\RestBundle\Controller
 *
 * @NamePrefix("api_rest_idp_")
 *
 */
class MfaController extends AbstractController
{
    /**
     * *This service enables MFA for a user! The service generates a secret and returns a QR-Code in the response. This documentation only shows decrypted request body!
     * The service expects a header authentication (x-wsse/servicetoken).*
     *
     * **Attention: to secure this service against replay attacks the x-wsse header is only valid for one request!**
     *
     * #Request (header)
     *
     *      Key                 | Value               | Description
     *      ------------------- | ------------------- | --------------------------------------
     *      x-wsse              |  (string)           | a generated x-wsse header
     *      servicetoken        |  (string)           | servicetoken to use this service
     *
     * ##x-wsse header example
     *
     *      UsernameToken Username="admin", PasswordDigest="inRgz7oomhSiWBWdKtLCT8wn7zM=", Nonce="ZDk5YWV3MTkxODVmOTMxNw==", Created="2015-12-28T10:27:37+01:00"
     *
     * ##Requests
     *
     *
     * **Request example XML**
     *
     *      POST /api/v1/mfas/adds/users.xml
     *
     *
     * **Example XML Request (decrypted)**
     *
     *      <?xml version="1.0" encoding="UTF-8"?>
     *          <mfaAddUser>
     *              <userIdentifier>Doe</userIdentifier>
     *          </mfaAddUser>
     *
     *
     * **Request example JSON**
     *
     *     POST /api/v1/mfas/adds/users.json
     *
     * **Example JSON Request (decrypted)**
     *
     *      {
     *       "userIdentifier": "Doe"
     *       }
     *
     *
     * ##Response Success 200 (verified)
     *
     * **Example XML Response 200 (body)**
     *
     *      <?xml version="1.0" encoding="UTF-8"?>
     *       <response>
     *           <status>200</status>
     *           <message><![CDATA[OK]]></message>
     *           <trackId><![CDATA[29f9bb75d6]]></trackId>
     *           <durationSeconds><![CDATA[0.4535]]></durationSeconds>
     *           <userIdentifier><![CDATA[admin]]></userIdentifier>
     *           <userFirstname><![CDATA[7753aed5]]></userFirstname>
     *           <userLastname><![CDATA[eb521d95]]></userLastname>
     *           <lastLogin><![CDATA[2016-01-04T12:35:35+0100]]></lastLogin>
     *           <loginFails>2</loginFails>
     *       </response>
     *
     * **Example JSON Response 200 (body)**
     *
     *       {
     *           "status": 200,
     *           "message": "OK",
     *           "trackId": "bfdff27708",
     *           "durationSeconds": "0.4736",
     *           "loginStatus": "verified",
     *           "userIdentifier": "admin",
     *           "userFirstname": "7753aed5",
     *           "userLastname": "eb521d95",
     *           "lastLogin": "2016-01-04T12:35:48+0100",
     *           "loginFails": 0
     *       }
     *
     *
     *
     * ##Response error
     *
     * **Example (header)**
     *
     *      401 Forbidden
     *
     * **Example JSON (body)**
     *
     *       {
     *       "status": 401,
     *       "message": "Forbidden",
     *       "trackId": "13562a3481",
     *       "count": 1,
     *       "errors": [
     *              {
     *              "code": 401,
     *              "message": "here is the error message",
     *              "trackId": "13562a3481",
     *              "type": "external",
     *              "exception": "not set",
     *              "debug": "not set"
     *              }
     *          ]
     *       }
     *
     *
     * **Example XML (body)**
     *
     *      <?xml version="1.0" encoding="UTF-8"?>
     *       <response>
     *          <status>401</status>
     *          <message><![CDATA[Forbidden]]></message>
     *          <trackId><![CDATA[13562a3481]]></trackId>
     *          <count>1</count>
     *          <errors>
     *              <error>
     *                  <code>401</code>
     *                  <message><![CDATA[here is the error message]></message>
     *                  <trackId><![CDATA[13562a3481]]></trackId>
     *                  <type><![CDATA[external]]></type>
     *                  <exception><![CDATA[not set]]></exception>
     *                  <debug><![CDATA[not set]]></debug>
     *              </error>
     *          </errors>
     *       </response>
     *
     * @ApiDoc(
     *  resource=true,
     *  description="secured: add MFA secret to user",
     *  statusCodes={
     *         200="Returned when successful",
     *         400="Bad request",
     *         401="Forbidden",
     *         403="Returned when the user is not authorized to do this request",
     *         500="Internal Server Error"
     *     },
     *   tags={
     *         "beta" = "#FF0000"
     *     }
     * )
     *
     *
     * @Secure(roles="ROLE_API")
     * @return View
     */
    public function postMfaAddUserAction(Request $request)
    {

        $user = $this->getUser();
        $lastDigest = $user->getRestLastDigest();
        $encyptedBody = $request->getContent();

        $format = preg_match('/\.xml/i', $request->getUri()) ? 'xml' : 'json';

        return $this->restApiM()->worker()->mfa()->postMfaAddUser()->init($encyptedBody, $lastDigest, $format);
    }

    /**
     * *This service validates a OTP (One Time Password) for an MFA user, the request body must be highly encrypted! This documentation only shows decrypted request body!
     * The service expects a header authentication (x-wsse/servicetoken).*
     *
     * **Attention: to secure this service against replay attacks the x-wsse header is only valid for one request!**
     *
     * #Request (header)
     *
     *      Key                 | Value               | Description
     *      ------------------- | ------------------- | --------------------------------------
     *      x-wsse              |  (string)           | a generated x-wsse header
     *      servicetoken        |  (string)           | servicetoken to use this service
     *
     * ##x-wsse header example
     *
     *      UsernameToken Username="admin", PasswordDigest="inRgz7oomhSiWBWdKtLCT8wn7zM=", Nonce="ZDk5YWV3MTkxODVmOTMxNw==", Created="2015-12-28T10:27:37+01:00"
     *
     * ##Requests
     *
     *
     * **Request example XML**
     *
     *      POST /api/v1/logins.xml
     *
     *
     * **Example XML Request (decrypted)**
     *
     *      <?xml version="1.0" encoding="UTF-8"?>
     *          <mfaValidateOtp>
     *              <userIdentifier>Doe</userIdentifier>
     *              <otp>123456</otp>
     *          </mfaValidateOtp>
     *
     *
     * **Request example JSON**
     *
     *     POST /api/v1/logins.json
     *
     * **Example JSON Request (decrypted)**
     *
     *      {
     *       "userIdentifier": "Doe",
     *       "otp": "123456"
     *       }
     *
     *
     * ##Response Success 200 (verified)
     *
     * **Example XML Response 200 (body)**
     *
     *      <?xml version="1.0" encoding="UTF-8"?>
     *       <response>
     *           <status>200</status>
     *           <message><![CDATA[OK]]></message>
     *           <trackId><![CDATA[29f9bb75d6]]></trackId>
     *           <durationSeconds><![CDATA[0.4535]]></durationSeconds>
     *           <userIdentifier><![CDATA[admin]]></userIdentifier>
     *           <userFirstname><![CDATA[7753aed5]]></userFirstname>
     *           <userLastname><![CDATA[eb521d95]]></userLastname>
     *           <lastLogin><![CDATA[2016-01-04T12:35:35+0100]]></lastLogin>
     *           <loginFails>2</loginFails>
     *       </response>
     *
     * **Example JSON Response 200 (body)**
     *
     *       {
     *           "status": 200,
     *           "message": "OK",
     *           "trackId": "bfdff27708",
     *           "durationSeconds": "0.4736",
     *           "loginStatus": "verified",
     *           "userIdentifier": "admin",
     *           "userFirstname": "7753aed5",
     *           "userLastname": "eb521d95",
     *           "lastLogin": "2016-01-04T12:35:48+0100",
     *           "loginFails": 0
     *       }
     *
     *
     *
     * ##Response error
     *
     * **Example (header)**
     *
     *      401 Forbidden
     *
     * **Example JSON (body)**
     *
     *       {
     *       "status": 401,
     *       "message": "Forbidden",
     *       "trackId": "13562a3481",
     *       "count": 1,
     *       "errors": [
     *              {
     *              "code": 401,
     *              "message": "here is the error message",
     *              "trackId": "13562a3481",
     *              "type": "external",
     *              "exception": "not set",
     *              "debug": "not set"
     *              }
     *          ]
     *       }
     *
     *
     * **Example XML (body)**
     *
     *      <?xml version="1.0" encoding="UTF-8"?>
     *       <response>
     *          <status>401</status>
     *          <message><![CDATA[Forbidden]]></message>
     *          <trackId><![CDATA[13562a3481]]></trackId>
     *          <count>1</count>
     *          <errors>
     *              <error>
     *                  <code>401</code>
     *                  <message><![CDATA[here is the error message]></message>
     *                  <trackId><![CDATA[13562a3481]]></trackId>
     *                  <type><![CDATA[external]]></type>
     *                  <exception><![CDATA[not set]]></exception>
     *                  <debug><![CDATA[not set]]></debug>
     *              </error>
     *          </errors>
     *       </response>
     *
     * @ApiDoc(
     *  resource=true,
     *  description="secured: validate MFA credentials",
     *  statusCodes={
     *         200="Returned when successful",
     *         400="Bad request",
     *         401="Forbidden",
     *         403="Returned when the user is not authorized to do this request",
     *         500="Internal Server Error"
     *     },
     *   tags={
     *         "beta" = "#FF0000"
     *     }
     * )
     *
     *
     * @Secure(roles="ROLE_API")
     * @return View
     */
    public function postMfaValidateAction(Request $request)
    {
        $user = $this->getUser();
        $lastDigest = $user->getRestLastDigest();
        $encyptedBody = $request->getContent();

        $format = preg_match('/\.xml/i', $request->getUri()) ? 'xml' : 'json';

        return $this->restApiM()->worker()->mfa()->postMfaValidate()->init($encyptedBody, $lastDigest, $format);
    }
}
