示例#1
0
 /**
  * @param Request $request
  * @param Closure $next
  *
  * @return array|mixed|string
  */
 public function handle($request, Closure $next)
 {
     //  Allow console requests through
     if (env('DF_IS_VALID_CONSOLE_REQUEST', false)) {
         return $next($request);
     }
     try {
         static::setExceptions();
         if (static::isAccessAllowed()) {
             return $next($request);
         } elseif (static::isException($request)) {
             //API key and/or (non-admin) user logged in, but if access is still not allowed then check for exception case.
             return $next($request);
         } else {
             $apiKey = Session::getApiKey();
             $token = Session::getSessionToken();
             if (empty($apiKey) && empty($token)) {
                 throw new BadRequestException('Bad request. No token or api key provided.');
             } elseif (true === Session::get('token_expired')) {
                 throw new UnauthorizedException(Session::get('token_expired_msg'));
             } elseif (!Session::isAuthenticated()) {
                 throw new UnauthorizedException('Unauthorized.');
             } else {
                 throw new ForbiddenException('Access Forbidden.');
             }
         }
     } catch (\Exception $e) {
         return ResponseFactory::getException($e, $request);
     }
 }
示例#2
0
 /**
  * Handle an incoming request.
  *
  * @param  \Illuminate\Http\Request $request
  * @param  \Closure                 $next
  *
  * @return mixed
  */
 public function handle($request, Closure $next)
 {
     //Get the Console API Key
     $consoleApiKey = AccessCheck::getConsoleApiKey($request);
     // Get limits
     if (config('df.standalone') === true || $consoleApiKey === Managed::getConsoleKey()) {
         return $next($request);
     } else {
         $limits = Managed::getLimits();
         // The limits array comes across from the console as a bunch of Std Objects, need to turn it back
         // into an array
         $limits['api'] = (array) $limits['api'];
         foreach (array_keys($limits['api']) as $key) {
             $limits['api'][$key] = (array) $limits['api'][$key];
         }
     }
     if (!empty($limits) && is_null($this->_getServiceName()) === false) {
         $this->_inUnitTest = \Config::get('api_limits_test');
         $userName = $this->_getUser(Session::getCurrentUserId());
         $userRole = $this->_getRole(Session::getRoleId());
         $apiName = $this->_getApiKey(Session::getApiKey());
         $serviceName = $this->_getServiceName();
         $clusterName = Managed::getClusterName();
         // Build the list of API Hits to check
         $apiKeysToCheck = ['cluster.default' => 0, 'instance.default' => 0];
         $serviceKeys[$serviceName] = 0;
         if (is_null($userRole) === false) {
             $serviceKeys[$serviceName . '.' . $userRole] = 0;
         }
         if (is_null($userName) === false) {
             $serviceKeys[$serviceName . '.' . $userName] = 0;
         }
         if (is_null($apiName) === false) {
             $apiKeysToCheck[$apiName] = 0;
             if (is_null($userRole) === false) {
                 $apiKeysToCheck[$apiName . '.' . $userRole] = 0;
             }
             if (is_null($userName) === false) {
                 $apiKeysToCheck[$apiName . '.' . $userName] = 0;
             }
             foreach ($serviceKeys as $key => $value) {
                 $apiKeysToCheck[$apiName . '.' . $key] = $value;
             }
         }
         if (is_null($clusterName) === false) {
             $apiKeysToCheck[$clusterName] = 0;
             if (is_null($userRole) === false) {
                 $apiKeysToCheck[$clusterName . '.' . $userRole] = 0;
             }
             if (is_null($userName) === false) {
                 $apiKeysToCheck[$clusterName . '.' . $userName] = 0;
             }
             foreach ($serviceKeys as $key => $value) {
                 $apiKeysToCheck[$clusterName . '.' . $key] = $value;
             }
         }
         if (is_null($userName) === false) {
             $apiKeysToCheck[$userName] = 0;
         }
         if (is_null($userRole) === false) {
             $apiKeysToCheck[$userRole] = 0;
         }
         $apiKeysToCheck = array_merge($apiKeysToCheck, $serviceKeys);
         $timePeriods = ['minute', 'hour', 'day', '7-day', '30-day'];
         $overLimit = false;
         try {
             foreach (array_keys($apiKeysToCheck) as $key) {
                 foreach ($timePeriods as $period) {
                     $keyToCheck = $key . '.' . $period;
                     if (array_key_exists($keyToCheck, $limits['api']) === true) {
                         $cacheValue = \Cache::get($keyToCheck, 0);
                         $cacheValue++;
                         \Cache::put($keyToCheck, $cacheValue, $limits['api'][$keyToCheck]['period']);
                         if ($cacheValue > $limits['api'][$keyToCheck]['limit']) {
                             $overLimit = true;
                         }
                     }
                 }
             }
         } catch (\Exception $e) {
             return ResponseFactory::getException(new InternalServerErrorException('Unable to update cache'), $request);
         }
         if ($overLimit === true) {
             return ResponseFactory::getException(new TooManyRequestsException('Specified connection limit exceeded'), $request);
         }
     }
     return $next($request);
 }
示例#3
0
 /**
  * @param Request $request
  * @param Closure $next
  *
  * @return array|mixed|string
  */
 public function handle($request, Closure $next)
 {
     try {
         static::setExceptions();
         //Get the api key.
         $apiKey = static::getApiKey($request);
         Session::setApiKey($apiKey);
         $appId = App::getAppIdByApiKey($apiKey);
         //Get the JWT.
         $token = static::getJwt($request);
         Session::setSessionToken($token);
         //Get the Console API Key
         $consoleApiKey = static::getConsoleApiKey($request);
         //Check for basic auth attempt.
         $basicAuthUser = $request->getUser();
         $basicAuthPassword = $request->getPassword();
         if (config('df.managed') && !empty($consoleApiKey) && $consoleApiKey === Managed::getConsoleKey()) {
             //DFE Console request
             return $next($request);
         } elseif (!empty($basicAuthUser) && !empty($basicAuthPassword)) {
             //Attempting to login using basic auth.
             Auth::onceBasic();
             /** @var User $authenticatedUser */
             $authenticatedUser = Auth::user();
             if (!empty($authenticatedUser)) {
                 $userId = $authenticatedUser->id;
                 Session::setSessionData($appId, $userId);
             } else {
                 throw new UnauthorizedException('Unauthorized. User credentials did not match.');
             }
         } elseif (!empty($token)) {
             //JWT supplied meaning an authenticated user session/token.
             try {
                 JWTAuth::setToken($token);
                 /** @type Payload $payload */
                 $payload = JWTAuth::getPayload();
                 JWTUtilities::verifyUser($payload);
                 $userId = $payload->get('user_id');
                 Session::setSessionData($appId, $userId);
             } catch (TokenExpiredException $e) {
                 JWTUtilities::clearAllExpiredTokenMaps();
                 if (!static::isException($request)) {
                     throw new UnauthorizedException($e->getMessage());
                 }
             } catch (TokenBlacklistedException $e) {
                 throw new ForbiddenException($e->getMessage());
             } catch (TokenInvalidException $e) {
                 throw new BadRequestException('Invalid token: ' . $e->getMessage(), 401);
             }
         } elseif (!empty($apiKey)) {
             //Just Api Key is supplied. No authenticated session
             Session::setSessionData($appId);
         } elseif (static::isException($request)) {
             //Path exception.
             return $next($request);
         } else {
             throw new BadRequestException('Bad request. No token or api key provided.');
         }
         if (static::isAccessAllowed()) {
             return $next($request);
         } elseif (static::isException($request)) {
             //API key and/or (non-admin) user logged in, but if access is still not allowed then check for exception case.
             return $next($request);
         } else {
             if (!Session::isAuthenticated()) {
                 throw new UnauthorizedException('Unauthorized.');
             } else {
                 throw new ForbiddenException('Access Forbidden.');
             }
         }
     } catch (\Exception $e) {
         return ResponseFactory::getException($e, $request);
     }
 }
示例#4
0
 /**
  * @param Request  $request
  * @param \Closure $next
  *
  * @return array|mixed|string
  */
 public function handle(Request $request, \Closure $next)
 {
     if (!in_array($route = $request->getPathInfo(), ['/setup', '/setup_db'])) {
         try {
             $apiKey = static::getApiKey($request);
             Session::setApiKey($apiKey);
             $appId = App::getAppIdByApiKey($apiKey);
             //Get the JWT.
             $token = static::getJwt($request);
             Session::setSessionToken($token);
             //Check for basic auth attempt.
             $basicAuthUser = $request->getUser();
             $basicAuthPassword = $request->getPassword();
             if (!empty($basicAuthUser) && !empty($basicAuthPassword)) {
                 //Attempting to login using basic auth.
                 Auth::onceBasic();
                 /** @var User $authenticatedUser */
                 $authenticatedUser = Auth::user();
                 if (!empty($authenticatedUser)) {
                     $userId = $authenticatedUser->id;
                     Session::setSessionData($appId, $userId);
                 } else {
                     throw new UnauthorizedException('Unauthorized. User credentials did not match.');
                 }
             } elseif (!empty($token)) {
                 //JWT supplied meaning an authenticated user session/token.
                 /**
                  * Note: All caught exception from JWT are stored in session variables.
                  * These are later checked and handled appropriately in the AccessCheck middleware.
                  *
                  * This is to allow processing API calls that do not require any valid
                  * authenticated session. For example POST user/session to login,
                  * PUT user/session to refresh old JWT, GET system/environment etc.
                  *
                  * This also allows for auditing API calls that are called by not permitted/processed.
                  * It also allows counting unauthorized API calls against Enterprise Console limits.
                  */
                 try {
                     JWTAuth::setToken($token);
                     /** @type Payload $payload */
                     $payload = JWTAuth::getPayload();
                     JWTUtilities::verifyUser($payload);
                     $userId = $payload->get('user_id');
                     Session::setSessionData($appId, $userId);
                 } catch (TokenExpiredException $e) {
                     JWTUtilities::clearAllExpiredTokenMaps();
                     Session::set('token_expired', true);
                     Session::set('token_expired_msg', $e->getMessage());
                 } catch (TokenBlacklistedException $e) {
                     Session::set('token_blacklisted', true);
                     Session::set('token_blacklisted_msg', $e->getMessage());
                 } catch (TokenInvalidException $e) {
                     Session::set('token_invalid', true);
                     Session::set('token_invalid_msg', 'Invalid token: ' . $e->getMessage());
                 }
             } elseif (!empty($apiKey)) {
                 //Just Api Key is supplied. No authenticated session
                 Session::setSessionData($appId);
             }
             return $next($request);
         } catch (\Exception $e) {
             return ResponseFactory::getException($e, $request);
         }
     }
     return $next($request);
 }
 /**
  * Handle an incoming request.
  *
  * @param  \Illuminate\Http\Request $request
  * @param  \Closure                 $next
  *
  * @return mixed
  */
 public function handle(Request $request, Closure $next)
 {
     /**
      * It is assumed, if you get this far, that ClusterServiceProvider was registered via
      * the ManagedInstance bootstrapper. If not, you're in a world of shit.
      *
      * We use provider's service() method because Facades are not loaded yet
      */
     $_cluster = ClusterServiceProvider::service();
     //  Get limits or bail
     if (!$_cluster instanceof ProvidesManagedLimits || empty($limits = $_cluster->getLimits())) {
         return $next($request);
     }
     $this->testing = config('api_limits_test', 'testing' == env('APP_ENV'));
     if (!empty($limits)) {
         $userName = $this->getUser(Session::getCurrentUserId());
         $userRole = $this->getRole(Session::getRoleId());
         $apiName = $this->getApiKey(Session::getApiKey());
         $clusterName = $_cluster->getClusterId();
         $instanceName = $_cluster->getInstanceName();
         $serviceName = $this->getServiceName($request);
         $limits = json_encode($limits);
         //TODO: Update dfe-console to properly set this, but right now, we want to touch as few files as possible
         if (!$this->testing) {
             $limits = str_replace(['cluster.default', 'instance.default'], [$clusterName, $clusterName . '.' . $instanceName], $limits);
         }
         //  Convert to an array
         $limits = json_decode($limits, true);
         //  Build the list of API Hits to check
         $apiKeysToCheck = [$clusterName . '.' . $instanceName => 0];
         $serviceKeys = [];
         if ($serviceName) {
             $serviceKeys[$serviceName] = 0;
             $userRole && ($serviceKeys[$serviceName . '.' . $userRole] = 0);
             $userName && ($serviceKeys[$serviceName . '.' . $userName] = 0);
         }
         if ($apiName) {
             $apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $apiName] = 0;
             $userRole && ($apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $apiName . '.' . $userRole] = 0);
             $userName && ($apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $apiName . '.' . $userName] = 0);
             foreach ($serviceKeys as $key => $value) {
                 $apiKeysToCheck[$apiName . '.' . $key] = $value;
             }
         }
         if ($clusterName) {
             $apiKeysToCheck[$clusterName] = 0;
             $userRole && ($apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $userRole] = 0);
             $userName && ($apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $userName] = 0);
             foreach ($serviceKeys as $key => $value) {
                 $apiKeysToCheck[$clusterName . '.' . $instanceName . '.' . $key] = $value;
             }
         }
         /* Per Ben, we want to increment every limit they hit, not stop after the first one */
         $overLimit = [];
         try {
             foreach (array_keys($apiKeysToCheck) as $key) {
                 foreach ($this->periods as $period) {
                     $_checkKey = $key . '.' . $period;
                     /** @noinspection PhpUndefinedMethodInspection */
                     if (array_key_exists($_checkKey, $limits['api'])) {
                         $_limit = $limits['api'][$_checkKey];
                         // For any cache drivers that make use of the cache prefix, we need to make sure we use
                         // a prefix that every instance can see.  But first, grab the current value
                         $dfCachePrefix = env('DF_CACHE_PREFIX');
                         putenv('DF_CACHE_PREFIX' . '=' . 'df_limits');
                         $_ENV['DF_CACHE_PREFIX'] = $_SERVER['DF_CACHE_PREFIX'] = 'df_limits';
                         //  Increment counter
                         $cacheValue = $this->cache()->get($_checkKey, 0);
                         $cacheValue++;
                         if ($cacheValue > $_limit['limit']) {
                             // Push the name of the rule onto the over-limit array so we can give the name in the 429 error message
                             $overLimit[] = array_get($_limit, 'name', $_checkKey);
                         } else {
                             // Only increment the counter if we are not over the limit.  Fixes DFE-205
                             $this->cache()->put($_checkKey, $cacheValue, $_limit['period']);
                         }
                         // And now set it back
                         putenv('DF_CACHE_PREFIX' . '=' . $dfCachePrefix);
                         $_ENV['DF_CACHE_PREFIX'] = $_SERVER['DF_CACHE_PREFIX'] = $dfCachePrefix;
                     }
                 }
             }
         } catch (\Exception $_ex) {
             return ResponseFactory::getException(new InternalServerErrorException('Unable to update cache: ' . $_ex->getMessage()), $request);
         }
         if ($overLimit) {
             /* Per Ben, we want to increment every limit they hit, not stop after the first one */
             return ResponseFactory::getException(new TooManyRequestsException('API limit(s) exceeded: ' . implode(', ', $overLimit)), $request);
         }
     }
     return $next($request);
 }
示例#6
0
 /**
  * @param Request  $request
  * @param \Closure $next
  *
  * @return array|mixed|string
  */
 public function handle(Request $request, \Closure $next)
 {
     if (!in_array($route = $request->getPathInfo(), ['/setup', '/setup_db'])) {
         try {
             $apiKey = static::getApiKey($request);
             Session::setApiKey($apiKey);
             $appId = App::getAppIdByApiKey($apiKey);
             //Get the JWT.
             $token = static::getJwt($request);
             Session::setSessionToken($token);
             //Check for basic auth attempt.
             $basicAuthUser = $request->getUser();
             $basicAuthPassword = $request->getPassword();
             if (!empty($basicAuthUser) && !empty($basicAuthPassword)) {
                 //Attempting to login using basic auth.
                 Auth::onceBasic();
                 /** @var User $authenticatedUser */
                 $authenticatedUser = Auth::user();
                 if (!empty($authenticatedUser)) {
                     $userId = $authenticatedUser->id;
                     Session::setSessionData($appId, $userId);
                 } else {
                     throw new UnauthorizedException('Unauthorized. User credentials did not match.');
                 }
             } elseif (!empty($token)) {
                 //JWT supplied meaning an authenticated user session/token.
                 try {
                     JWTAuth::setToken($token);
                     /** @type Payload $payload */
                     $payload = JWTAuth::getPayload();
                     JWTUtilities::verifyUser($payload);
                     $userId = $payload->get('user_id');
                     Session::setSessionData($appId, $userId);
                 } catch (TokenExpiredException $e) {
                     JWTUtilities::clearAllExpiredTokenMaps();
                     Session::set('token_expired', true);
                     Session::set('token_expired_msg', $e->getMessage());
                 } catch (TokenBlacklistedException $e) {
                     throw new ForbiddenException($e->getMessage());
                 } catch (TokenInvalidException $e) {
                     throw new BadRequestException('Invalid token: ' . $e->getMessage(), 401);
                 }
             } elseif (!empty($apiKey)) {
                 //Just Api Key is supplied. No authenticated session
                 Session::setSessionData($appId);
             }
             return $next($request);
         } catch (\Exception $e) {
             return ResponseFactory::getException($e, $request);
         }
     }
     return $next($request);
 }