1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 101 102 103 104 
<?php

/* --------------------------------------------------------------
   ApiV2Authenticator.inc.php 2017-12-18
   Gambio GmbH
   http://www.gambio.de
   Copyright (c) 2017 Gambio GmbH
   Released under the GNU General Public License (Version 2)
   [http://www.gnu.org/licenses/gpl-2.0.html]
   --------------------------------------------------------------
*/

use \HubPublic\Http\CurlRequest;

class ApiV2Authenticator
{
    /**
     * @var \Slim\Slim
     */
    protected $api;
    
    /**
     * @var array
     */
    protected $uri;
    
    
    /**
     * ApiV2Authenticator constructor.
     *
     * @param \Slim\Slim $api
     * @param array      $uri
     */
    public function __construct(\Slim\Slim $api, array $uri)
    {
        $this->api = $api;
        $this->uri = $uri;
    }
    
    
    /**
     * Authorize request with HTTP Basic Authorization
     *
     * Call this method in every API operation that needs to be authorized with the HTTP Basic
     * Authorization technique.
     *
     * @link http://php.net/manual/en/features.http-auth.php
     *
     * Not available to child-controllers (private method).
     *
     * @param string $controllerName Name of the parent controller for this api call.
     *
     * @throws HttpApiV2Exception If request does not provide the "Authorization" header or if the
     *                            credentials are invalid.
     *
     * @throws InvalidArgumentException If the username or password values are invalid.
     */
    public function authorize($controllerName)
    {
        if(empty($_SERVER['PHP_AUTH_USER']) && empty($_SERVER['PHP_AUTH_PW']) && !empty($_SERVER['HTTP_AUTHORIZATION']))
        {
            list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':',
                                                                               base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'],
                                                                                                    6)));
        }
        elseif(empty($_SERVER['PHP_AUTH_USER']) && empty($_SERVER['PHP_AUTH_PW'])
               && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])
        )
        {
            list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':',
                                                                               base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'],
                                                                                                    6)));
        }
        
        if(!isset($_SERVER['PHP_AUTH_USER']))
        {
            $this->api->response->headers->set('WWW-Authenticate', 'Basic realm="Gambio GX3 APIv2 Login"');
            throw new HttpApiV2Exception('Unauthorized', 401);
        }
        
        $authService = StaticGXCoreLoader::getService('Auth');
        $credentials = MainFactory::create('UsernamePasswordCredentials',
                                           new NonEmptyStringType($_SERVER['PHP_AUTH_USER']),
                                           new StringType($_SERVER['PHP_AUTH_PW']));
        
        $db      = StaticGXCoreLoader::getDatabaseQueryBuilder();
        $query   = $db->get_where('customers', [
            'customers_email_address' => $_SERVER['PHP_AUTH_USER'],
            'customers_status'        => '0'
        ]);
        $isAdmin = $query->num_rows() === 1;
        $user    = $query->row_array();
        
        $controllerName     = substr($controllerName, 0, -10);
        $adminAccessService = StaticGXCoreLoader::getService('AdminAccess');
        $hasPermission      = (bool)$adminAccessService->checkReadingPermissionForController(new NonEmptyStringType($controllerName),
                                                                                             new IdType((int)$user['customers_id']));
        
        if(!$authService->authUser($credentials) || !$isAdmin || !$hasPermission)
        {
            throw new HttpApiV2Exception('Invalid Credentials', 401);
        }
    }
}