/**
  * {@inheritDoc}
  */
 public function register(SilexApplication $app)
 {
     $app['payum.api.controller.root'] = $app->share(function () {
         return new RootController();
     });
     $app['payum.api.controller.payment'] = $app->share(function () use($app) {
         return new PaymentController($app['payum.security.token_factory'], $app['payum.security.http_request_verifier'], $app['payum'], $app['api.view.order_to_json_converter'], $app['form.factory'], $app['api.view.form_to_json_converter']);
     });
     $app['payum.api.controller.gateway'] = $app->share(function () use($app) {
         return new GatewayController($app['form.factory'], $app['url_generator'], $app['api.view.form_to_json_converter'], $app['payum.gateway_config_storage'], $app['api.view.gateway_config_to_json_converter']);
     });
     $app['payum.api.controller.gateway_meta'] = $app->share(function () use($app) {
         return new GatewayMetaController($app['form.factory'], $app['api.view.form_to_json_converter'], $app['payum']);
     });
     $app->get('/', 'payum.api.controller.root:rootAction')->bind('api_root');
     $app->get('/payments/meta', 'payum.api.controller.payment:metaAction')->bind('payment_meta');
     $app->get('/payments/{payum_token}', 'payum.api.controller.payment:getAction')->bind('payment_get');
     $app->put('/payments/{payum_token}', 'payum.api.controller.payment:updateAction')->bind('payment_update');
     $app->delete('/payments/{payum_token}', 'payum.api.controller.payment:deleteAction')->bind('payment_delete');
     $app->post('/payments', 'payum.api.controller.payment:createAction')->bind('payment_create');
     $app->get('/payments', 'payum.api.controller.payment:allAction')->bind('payment_all');
     $app->get('/gateways/meta', 'payum.api.controller.gateway_meta:getAllAction')->bind('payment_factory_get_all');
     $app->get('/gateways', 'payum.api.controller.gateway:allAction')->bind('gateway_all');
     $app->get('/gateways/{name}', 'payum.api.controller.gateway:getAction')->bind('gateway_get');
     $app->delete('/gateways/{name}', 'payum.api.controller.gateway:deleteAction')->bind('gateway_delete');
     $app->post('/gateways', 'payum.api.controller.gateway:createAction')->bind('gateway_create');
     $app->before(function (Request $request, Application $app) {
         if (in_array($request->getMethod(), array('GET', 'OPTIONS', 'DELETE'))) {
             return;
         }
         if ('json' !== $request->getContentType()) {
             throw new BadRequestHttpException('The request content type is invalid. It must be application/json');
         }
         $decodedContent = json_decode($request->getContent(), true);
         if (null === $decodedContent) {
             throw new BadRequestHttpException('The request content is not valid json.');
         }
         $request->attributes->set('content', $decodedContent);
     });
     $app->after(function (Request $request, Response $response) use($app) {
         if ($response instanceof JsonResponse && $app['debug']) {
             $response->setEncodingOptions($response->getEncodingOptions() | JSON_PRETTY_PRINT);
         }
     });
     $app->after($app["cors"]);
     $app->error(function (\Exception $e, $code) use($app) {
         if ('json' !== $app['request']->getContentType()) {
             return;
         }
         return new JsonResponse(array('exception' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'file' => $e->getFile(), 'line' => $e->getLine(), 'stackTrace' => $e->getTraceAsString()));
     }, $priority = -100);
 }
 /**
  * {@inheritdoc}
  */
 public function register(Application $app)
 {
     // handling CORS preflight request
     $app->before(function (Request $request) {
         if ($request->getMethod() === 'OPTIONS') {
             $response = new Response();
             $response->headers->set('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
             $response->headers->set('Access-Control-Allow-Headers', 'Content-Type');
             $response->headers->set('Access-Control-Allow-Origin', '*');
             $response->setStatusCode(200);
             return $response;
         }
     }, $app::EARLY_EVENT);
     $app->before(function (Request $request) {
         if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
             $data = json_decode($request->getContent(), true);
             $request->request->replace(is_array($data) ? $data : []);
         }
     });
     // CORS domain
     $app->after(function (Request $request, Response $response) {
         $response->headers->set('Access-Control-Allow-Origin', '*');
         return $response;
     });
     // Returns the status code in the response body
     $app->after(function (Request $request, Response $response) {
         $status = $response->getStatusCode();
         // Errors
         if ($status >= 400 && $response instanceof JsonResponse) {
             $data = json_decode($response->getContent(), true);
             if (!is_array($data)) {
                 $data = [];
             }
             $response->setData(array_merge($data, ['status' => $status]));
         }
         return $response;
     });
     // Converts HTTP exception to response
     $app->error(function (\Exception $e) {
         $response = null;
         switch (true) {
             case $e instanceof NotFoundHttpException:
             case $e instanceof BadRequestHttpException:
                 $response = new JsonResponse(['message' => $e->getMessage()], $e->getStatusCode(), $e->getHeaders());
                 break;
             default:
         }
         return $response;
     });
 }
 public function boot(Application $app)
 {
     $app->before(function () use($app) {
         $app['np.extensions']['debug'] = $app['debug'];
         $app['np.extensions']['admin'] = $app['np.admin'];
         $app['np.extensions']->boot();
         // add template paths for all extensions and blocks
         $app['twig.loader.filesystem'] = $app->share($app->extend('twig.loader.filesystem', function ($loader, $app) {
             foreach ($app['np.extensions']->getAll() as $namespace => $extension) {
                 $loader->addPath($extension->getPath(), $namespace);
             }
             foreach ($app['np.extensions']['block_types'] as $blockType) {
                 $loader->addPath($blockType->getPath(), 'block_' . $app['np.slug_helper']->slugify($blockType->name));
             }
             return $loader;
         }));
         // load collected twig functions
         $app['twig'] = $app->share($app->extend('twig', function ($twig, $app) {
             foreach ($app['np.extensions']['twig_extensions'] as $extension) {
                 $twig->addExtension($extension);
             }
             return $twig;
         }));
     });
     $app->after(function (Request $request, Response $response) use($app) {
         if ($response instanceof BinaryFileResponse || !$app['np.extensions']->booted) {
             return;
         }
         $app['np.extensions']->prepareSnippets();
         $response->setContent($app['np.extensions']['snippet_queue']->processAll($app, $response->getContent()));
     });
 }
 /**
  * @param Application $app
  */
 public function boot(Application $app)
 {
     $options = $this->options;
     $cors = new CorsService($options);
     // handle OPTIONS preflight request if necessary
     $app->before(function (Request $request) use($app, $cors, $options) {
         if (!$cors->isCorsRequest($request)) {
             return;
         }
         if ($cors->isPreflightRequest($request)) {
             $response = $cors->handlePreflightRequest($request);
             $denied_codes = array(Response::HTTP_METHOD_NOT_ALLOWED, Response::HTTP_FORBIDDEN);
             $is_denied = in_array($response->getStatusCode(), $denied_codes);
             if ($is_denied && !empty($options['denied_reponse_class'])) {
                 $response = new $options['denied_reponse_class']($response->getContent(), $response->getStatusCode(), $response->headers->all());
             }
             return $response;
         }
         if (!$cors->isActualRequestAllowed($request)) {
             if (!empty($options['denied_reponse_class'])) {
                 $response = new $options['denied_reponse_class']('Not allowed', 403);
             } else {
                 $response = new Response('Not allowed.', 403);
             }
             return $response;
         }
     }, Application::EARLY_EVENT);
     // when the response is sent back, add CORS headers if necessary
     $app->after(function (Request $request, Response $response) use($cors) {
         if (!$cors->isCorsRequest($request)) {
             return;
         }
         $cors->addActualRequestHeaders($response, $request);
     });
 }
Example #5
0
 public function register(Application $app)
 {
     $app['monolog'] = $app->share(function () use($app) {
         $log = new Logger(isset($app['monolog.name']) ? $app['monolog.name'] : 'myapp');
         $app['monolog.configure']($log);
         return $log;
     });
     $app['monolog.configure'] = $app->protect(function ($log) use($app) {
         $log->pushHandler($app['monolog.handler']);
     });
     $app['monolog.handler'] = function () use($app) {
         return new StreamHandler($app['monolog.logfile'], $app['monolog.level']);
     };
     if (!isset($app['monolog.level'])) {
         $app['monolog.level'] = function () {
             return Logger::DEBUG;
         };
     }
     if (isset($app['monolog.class_path'])) {
         $app['autoloader']->registerNamespace('Monolog', $app['monolog.class_path']);
     }
     $app->before(function (Request $request) use($app) {
         $app['monolog']->addInfo('> ' . $request->getMethod() . ' ' . $request->getRequestUri());
     });
     $app->error(function (\Exception $e) use($app) {
         $app['monolog']->addError($e->getMessage());
     });
     $app->after(function (Request $request, Response $response) use($app) {
         $app['monolog']->addInfo('< ' . $response->getStatusCode());
     });
 }
 public function boot(Application $app)
 {
     $app->before(function (Request $request) use($app) {
         $app['monolog']->addInfo('> ' . $request->getMethod() . ' ' . $request->getRequestUri());
     });
     /*
      * Priority -4 is used to come after those from SecurityServiceProvider (0)
      * but before the error handlers added with Silex\Application::error (defaults to -8)
      */
     $app->error(function (\Exception $e) use($app) {
         $message = sprintf('%s: %s (uncaught exception) at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
         if ($e instanceof HttpExceptionInterface && $e->getStatusCode() < 500) {
             $app['monolog']->addError($message, array('exception' => $e));
         } else {
             $app['monolog']->addCritical($message, array('exception' => $e));
         }
     }, -4);
     $app->after(function (Request $request, Response $response) use($app) {
         if ($response instanceof RedirectResponse) {
             $app['monolog']->addInfo('< ' . $response->getStatusCode() . ' ' . $response->getTargetUrl());
         } else {
             $app['monolog']->addInfo('< ' . $response->getStatusCode());
         }
     });
 }
 public function boot(Application $app)
 {
     $app->before(function (Request $request, Application $app) {
         //echo "Before Service Event<hr>";
     });
     $app->after(function (Request $request, Response $response) {
         //echo "After Service Event <hr>";
     });
 }
 public function boot(Application $app)
 {
     $app->before($app['monolog.boot.before']);
     /*
      * Priority -4 is used to come after those from SecurityServiceProvider (0)
      * but before the error handlers added with Silex\Application::error (defaults to -8)
      */
     $app->error($app['monolog.boot.error'], -4);
     $app->after($app['monolog.boot.after']);
 }
 public function boot(Application $app)
 {
     if ($app['lazycache']->isActive()) {
         $app->before(function (Request $request) use($app) {
             return $app['lazycache']->before($request);
         });
         $app->after(function (Request $request, Response $response) use($app) {
             return $app['lazycache']->after($request, $response);
         });
     }
 }
Example #10
0
 public function boot(Application $app)
 {
     $app->before(function (Request $request) use($app) {
         $app['monolog']->addInfo('> ' . $request->getMethod() . ' ' . $request->getRequestUri());
     });
     $app->error(function (\Exception $e) use($app) {
         $app['monolog']->addError($e->getMessage());
     }, 255);
     $app->after(function (Request $request, Response $response) use($app) {
         $app['monolog']->addInfo('< ' . $response->getStatusCode());
     });
 }
Example #11
0
 public function register(Application $app)
 {
     $app->after(function (Request $request, Response $response) use($app) {
         $response->headers->set('Access-Control-Allow-Origin', $request->headers->get('origin', '*'));
         $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
         $response->headers->set('Access-Control-Allow-Credentials', 'Bearer');
         $response->headers->set('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
     });
     $app->before(function (Request $request) use($app) {
         if ($request->getMethod() === 'OPTIONS') {
             return new Response('', 200);
         }
     });
 }
 public function boot(Application $app)
 {
     // BC: to be removed before 1.0
     if (isset($app['monolog.class_path'])) {
         throw new \RuntimeException('You have provided the monolog.class_path parameter. The autoloader has been removed from Silex. It is recommended that you use Composer to manage your dependencies and handle your autoloading. If you are already using Composer, you can remove the parameter. See http://getcomposer.org for more information.');
     }
     $app->before(function (Request $request) use($app) {
         $app['monolog']->addInfo('> ' . $request->getMethod() . ' ' . $request->getRequestUri());
     });
     $app->error(function (\Exception $e) use($app) {
         $app['monolog']->addError($e->getMessage());
     }, 255);
     $app->after(function (Request $request, Response $response) use($app) {
         $app['monolog']->addInfo('< ' . $response->getStatusCode());
     });
 }
 public function boot(Application $app)
 {
     $app->before(function (Request $request) use($app) {
         $app['monolog']->addInfo('> ' . $request->getMethod() . ' ' . $request->getRequestUri());
     });
     $app->error(function (\Exception $e) use($app) {
         $message = sprintf('%s: %s (uncaught exception) at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
         if ($e instanceof HttpExceptionInterface && $e->getStatusCode() < 500) {
             $app['monolog']->addError($message);
         } else {
             $app['monolog']->addCritical($message);
         }
     }, 255);
     $app->after(function (Request $request, Response $response) use($app) {
         $app['monolog']->addInfo('< ' . $response->getStatusCode());
     });
 }
 public function testCallbacksAsServices()
 {
     $app = new Application();
     $app['service'] = $app->share(function () {
         return new self();
     });
     $app->before('service:beforeApp');
     $app->after('service:afterApp');
     $app->finish('service:finishApp');
     $app->error('service:error');
     $app->on('kernel.request', 'service:onRequest');
     $app->match('/', 'service:controller')->convert('foo', 'service:convert')->before('service:before')->after('service:after');
     $request = Request::create('/');
     $response = $app->handle($request);
     $app->terminate($request, $response);
     $this->assertEquals(array('CONVERT', 'BEFORE APP', 'ON REQUEST', 'BEFORE', 'ERROR', 'AFTER', 'AFTER APP', 'FINISH APP'), $app['service']->called);
 }
 protected function setupAfterMiddleware(Application $app)
 {
     $app->after(function (Request $request, Response $response) use($app) {
         switch ($app['newrelic.options']['transaction_name_method']) {
             case 'route':
                 $name = $request->attributes->get('_route');
                 break;
             case 'uri':
             default:
                 $name = $request->getRequestUri();
                 break;
         }
         if (!$name) {
             $name = NewRelicServiceProvider::DEFAULT_TRANSACTION_NAME;
         }
         $app['newrelic']->nameTransaction($name);
     });
 }
 protected function registerServicesBase(Application $app)
 {
     // Configuration service
     $app['clientlogin.config'] = $app->share(function ($this) use($app) {
         $rooturl = $app['resources']->getUrl('rooturl');
         return new Config($this->config, $rooturl);
     });
     // Twig user interface service
     $app['clientlogin.ui'] = $app->share(function ($app) {
         return new UserInterface($app);
     });
     // Feedback message handling service
     $app['clientlogin.feedback'] = $app->share(function ($app) {
         $feedback = new Feedback($app['session']);
         $app->after([$feedback, 'after']);
         return $feedback;
     });
 }
 /**
  * 
  * @return string|boolean
  */
 public function createApplication()
 {
     $app = new Application();
     $app['debug'] = true;
     $app['exception_handler']->disable();
     // Register the ServiceProvider
     $app->register(new LiveReloadServiceProvider());
     $app->get(self::$url, function () {
         return '<!doctype html><html><head><title>LiveReloadTest</title></head><body></body></html>';
     });
     $app['profiler'] = $app->share(function ($app) {
         return new Profile(substr(hash('sha256', uniqid(mt_rand(), true)), 0, 6));
     });
     $app->after(function (Request $request, Response $response) use($app) {
         $response->headers->set('X-Debug-Token', $app['profiler']->getToken());
     });
     return $app;
 }
Example #18
0
 public function boot(Application $app)
 {
     // BC: to be removed before 1.0
     if (isset($app['monolog.class_path'])) {
         throw new \RuntimeException('You have provided the monolog.class_path parameter. The autoloader has been removed from Silex. It is recommended that you use Composer to manage your dependencies and handle your autoloading. If you are already using Composer, you can remove the parameter. See http://getcomposer.org for more information.');
     }
     $app->before(function (Request $request) use($app) {
         $app['monolog']->addInfo('> ' . $request->getMethod() . ' ' . $request->getRequestUri());
     });
     $app->error(function (\Exception $e) use($app) {
         $message = sprintf('%s: %s (uncaught exception) at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
         if ($e instanceof HttpExceptionInterface && $e->getStatusCode() < 500) {
             $app['monolog']->addError($message);
         } else {
             $app['monolog']->addCritical($message);
         }
     }, 255);
     $app->after(function (Request $request, Response $response) use($app) {
         $app['monolog']->addInfo('< ' . $response->getStatusCode());
     });
 }
Example #19
0
 public function register(Application $app)
 {
     $app['app.ratelimit'] = $app->share(function () use($app) {
         try {
             $cache = $app['caches']['redis'];
         } catch (Exception $ex) {
             $app['monolog']->addError("Redis is not available: {$ex->getMessage()})");
         }
         if (empty($cache)) {
             $cache = $app['caches']['file'];
         }
         $storage = new DoctrineRateLimitStorage($cache);
         $rateLimiter = new RateLimiter($storage);
         return $rateLimiter;
     });
     $app->before(function (Request $request) use($app) {
         $token = $app['security.token_storage']->getToken();
         if (null !== $token) {
             $userId = $token->getUsername();
             if ($app['app.ratelimit']->hasReachedLimit($userId)) {
                 $response = new Response('', Response::HTTP_TOO_MANY_REQUESTS);
                 $response->headers->add(array('X-RateLimit-Limit' => $app['app.ratelimit']->getMaxLimit(), 'X-RateLimit-Remaining' => 0));
                 return $response;
             }
         }
     });
     $app->after(function (Request $request, Response $response) use($app) {
         if ($response->headers->has('X-RateLimit-Limit')) {
             return;
         }
         $token = $app['security.token_storage']->getToken();
         if (null !== $token) {
             $userId = $token->getUsername();
             $app['app.ratelimit']->substract($userId, 1);
             $currentAmount = $app['app.ratelimit']->getCurrentAmount($userId);
             $response->headers->add(array('X-RateLimit-Limit' => $app['app.ratelimit']->getMaxLimit(), 'X-RateLimit-Remaining' => $currentAmount));
         }
     });
 }
Example #20
0
 public function boot(Application $app)
 {
     $allowedResponseHeaders = $app["cors.response.headers"];
     $allowedRequestHeaders = array_merge($app["cors.request.defaultHeaders"], $app["cors.request.headers"]);
     //handling CORS preflight request
     $app->before(function (Request $request) use($allowedRequestHeaders) {
         if ($request->getMethod() === "OPTIONS") {
             $response = new Response();
             $response->headers->set("Access-Control-Allow-Origin", "*");
             $response->headers->set("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
             $response->headers->set("Access-Control-Allow-Headers", implode(",", $allowedRequestHeaders));
             $response->setStatusCode(200);
             $response->send();
             exit;
         }
     }, Application::EARLY_EVENT);
     //handling CORS response with right headers
     $app->after(function (Request $request, Response $response) use($allowedResponseHeaders) {
         $response->headers->set("Access-Control-Allow-Origin", "*");
         $response->headers->set("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
         $response->headers->set("Access-Control-Expose-Headers", implode(",", $allowedResponseHeaders));
     });
 }
    $isValidToken = false;
    $guard = new Guardian();
    if ($pathInfo == '/auth') {
        if ($guard->validateAppToken($appToken)) {
            $app['AppToken'] = $appToken;
            $isValidToken = true;
        }
    } else {
        $clientToken = $request->headers->get('ClientToken');
        if ($guard->validateAppAndClientToken($appToken, $clientToken)) {
            $app['ClientToken'] = $clientToken;
            $isValidToken = true;
        }
    }
    if (!$isValidToken) {
        return new JsonResponse('Bad Request', 400);
    }
});
$app->after(function (Request $request, Response $response, Application $app) {
    if (isset($app['AppToken'])) {
        $response->headers->set('AppToken', $app['AppToken']);
    }
    if (isset($app['ClientToken'])) {
        $response->headers->set('ClientToken', $app['ClientToken']);
    }
    $response->headers->set('Access-Control-Allow-Origin', '*');
    $response->headers->set('Access-Control-Expose-Headers', 'AppToken');
    $response->headers->set('Access-Control-Expose-Headers', 'ClientToken');
    $response->headers->set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, ClientToken, AppToken');
});
$app->run();
 public function boot(Application $app)
 {
     $app['devture_localization.translator.resource_loader']->addResources(dirname(__FILE__) . '/Resources/translations/');
     $app->before($app['devture_user.listener.user_from_request_initializer']);
     $app->before($app['devture_user.listener.csrf_token_manager_salter']);
     $app->before(array($app['devture_user.access_control'], 'enforceProtection'));
     $app->after($app['devture_user.listener.conditional_session_extender']);
     //Also register the templates path at a custom namespace, to allow templates overriding+extending.
     $app['twig.loader.filesystem']->addPath(__DIR__ . '/Resources/views/');
     $app['twig.loader.filesystem']->addPath(__DIR__ . '/Resources/views/', 'DevtureUserBundle');
     $app['twig']->addExtension($app['devture_user.twig.user_extension']);
     if (isset($app['console'])) {
         $app['console']->add($app['devture_user.console.command.add_user']);
         $app['console']->add($app['devture_user.console.command.change_user_password']);
     }
 }
 /**
  *
  * @param  Application $app
  */
 function boot(Application $app)
 {
     $app['twig']->addExtension(new TwigAsseticIntegrationExtension($app['assetic.asset_factory'], array(), null, $app));
     $app->after(function (Request $request, Response $response) use($app) {
         $templates = $app['twig.loader']->getTemplate();
         foreach ($templates as $filename => $fullpath) {
             $resource = new TwigResource($app['twig']->getLoader(), $filename);
             $app['assetic.lazy_asset_manager']->addResource($resource, 'twig');
         }
         $app['assetic.asset_writer']->writeManagerAssets($app['assetic.lazy_asset_manager']);
     });
 }
Example #24
0
<?php

require_once __DIR__ . '/../vendor/autoload.php';
require '../server/CategoryHandler.php';
require '../server/SubcategoryHandler.php';
require '../server/BusinessHandler.php';
require '../server/AdminHandler.php';
require '../server/Authentication.php';
require '../server/password.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Silex\Application;
$app = new Silex\Application();
$app['debug'] = true;
$app->after(function (Request $request, Response $response) {
    $response->headers->set('Access-Control-Allow-Origin', '*');
    // echo $response->headers;
});
// Request::setTrustedProxies(array($ip));
$app->GET('/', function (Application $app, Request $request) {
    return new Response("<p>All good!</p>", 200);
});
// Category Routes
// All categories
$app->GET('/categories', function (Application $app, Request $request) {
    $handler = new CategoryHandler();
    $result = $handler->getAll();
    return new Response($result, 200);
});
// Create category
$app->PUT('/categories', function (Application $app, Request $request) {
    if (!authenticate('2', null)) {
 public function boot(Application $app)
 {
     $app->after($app['JSONP']);
 }
Example #26
0
$app->register(new DoctrineORMServiceProvider(), ['doctrine_orm.entities_path' => __DIR__ . DS . 'src', 'doctrine_orm.proxies_path' => __DIR__ . DS . 'tmp' . DS . 'proxy', 'doctrine_orm.proxies_namespace' => 'ApplicationPro', 'doctrine_orm.connection_parameters' => $app['config']['database'][APPLICATION_ENV], 'doctrine_orm.simple_annotation_reader' => false]);
// Loading service container
$app->register(new DiContainerProvider($app['config']['services']));
// CORS provider
$app->register(new CorsServiceProvider());
// Router Provider
$app->register(new RouterServiceProvider(__DIR__ . DS . 'config' . DS . 'routes' . DS . 'routes.yml'));
$app->before(function (Request $request) use($app) {
    // Skipping OPTIONS requests
    if ($request->getMethod() === 'OPTIONS') {
        return;
    }
    // If body request is JSON, decode it!
    if (0 === strpos($request->headers->get('Content-Type', 'application/json'), 'application/json')) {
        $data = json_decode($request->getContent(), true);
        $request->request->replace(is_array($data) ? $data : []);
    }
});
$app->after(function (Request $request, Response $response, SilexApplication $app) {
    $app[CorsServiceProvider::HTTP_CORS]($request, $response);
});
$app->error(function (\Exception $e, $code = Response::HTTP_INTERNAL_SERVER_ERROR) {
    if ($e->getCode() !== 0) {
        $code = $e->getCode();
    }
    if ($code > 505 || $code < 100) {
        $code = 500;
    }
    return new Response(["exception" => $e->getMessage(), "status" => "error"], $code);
});
return $app;
Example #27
0
 public function testFiltersShouldFireOnHttpException()
 {
     $i = 0;
     $app = new Application();
     $app->before(function () use(&$i) {
         $i++;
     });
     $app->after(function () use(&$i) {
         $i++;
     });
     $app->error(function () {
         return 'error handled';
     });
     $request = Request::create('/nowhere');
     $app->handle($request);
     $this->assertEquals(2, $i);
 }
 public function boot(Application $app)
 {
     $app->after(new DescribedBy());
 }
Example #29
0
/**
 * Client
 *
 * Create a micropub client app — allows users to log in and authorize this app to make requests on their behalf to,
 * e.g. a micropub endpoint, authenticates requests based on remember-me cookie.
 * $dataToCookie and $dataFromCookie map between the array of information about the current user and the string value
 * stored in the remember-me cookie
 *
 * Adds routes:
 * /login (indieauth.login) — POST to this URL with required “me” and optional “next” parameters to start the login process
 * /authorize (indieauth.authorize) — the URL redirected to by the user’s authorization server after successful authorization. Checks details and sets remember-me cookie
 * /logout (indieauth.logout) — POST to this URL (with optional “next” parameter) whilst logged in to log out, i.e. remove the remmeber-me cookies.
 *
 * Adds ->before() handler which attaches data about the current user, which scopes they’ve granted this app (if any)
 * their URL, access token and micropub endpoint to $request. Example usage within a controller:
 *
 *     $token = $request->attributes->get('indieauth.client.token', null);
 *     if ($token !== null) {
 *       // User is logged in as $token['me']
 *       if (!empty($token['access_token'] and !empty($token['micropub_endpoint'])) {
 *         // The user has granted this app privileges detailed in $token['scope'], which can be carried out by sending
 *         // requests to $token['micropub_endpoint'] with $token['access_token']
 *         // Now you might check that the “post” scope is granted, and create some new content on their site (pseudocode):
 *         if (in_array('post', explode($scope, ' '))) {
 *           micrpub_post($token['micropub_endpoint'], $token['access_token'], $postDetails);
 *         }
 *       } else {
 *         // The user has logged in using the basic indieauth flow — we know that they’re authenticated as $token['me'],
 *         // but they haven’t granted us any permissions.
 *       }
 *     }
 *
 * @param \Silex\Application $app
 * @param callable|null $dataToCookie
 * @param callable|null $dataFromCookie
 * @return \Symfony\Component\Routing\RouteCollection
 */
function client($app, $dataToCookie = null, $dataFromCookie = null)
{
    $auth = $app['controllers_factory'];
    // If cookie mapping functions aren’t defined, use the simplest approach of encrypting the data.
    if ($dataToCookie === null) {
        $dataToCookie = function ($data) use($app) {
            return $app['encryption']->encrypt($data);
        };
    }
    if ($dataFromCookie === null) {
        $dataFromCookie = function ($token) use($app) {
            return $app['encryption']->decrypt($token);
        };
    }
    $app['indieauth'] = new IndieauthHelpers($app);
    // If no cookie lifetime is set, default to 60 days.
    $cookieLifetime = !empty($app['indieauth.cookielifetime']) ? $app['indieauth.cookielifetime'] : 60 * 60 * 24 * 60;
    $cookieName = !empty($app['indieauth.cookiename']) ? $app['indieauth.cookiename'] : 'indieauth_token';
    $secureCookies = isset($app['indieauth.securecookies']) ? $app['indieauth.securecookies'] : true;
    $clientIdForRequest = function (Http\Request $request) use($app) {
        // If no explicit client ID is set, use the domain name of this site.
        return !empty($app['indieauth.clientid']) ? $app['indieauth.clientid'] : $request->getHttpHost();
    };
    $redirectUrlForRequest = function (Http\Request $request) use($app) {
        // If no default login redirect URL is set (it can be reset on a request-by-request basis by setting the “next” parameter), default to the homepage
        $defaultLoginRedirectUrl = !empty($app['indieauth.loginredirecturl']) ? $app['indieauth.loginredirecturl'] : "{$request->getScheme()}://{$request->getHttpHost()}";
        return $request->request->get('next', $defaultLoginRedirectUrl);
    };
    $auth->post('/login/', function (Http\Request $request) use($app, $cookieName, $redirectUrlForRequest, $clientIdForRequest, $secureCookies) {
        $me = $request->request->get('me');
        $next = $redirectUrlForRequest($request);
        if ($me === null) {
            // TODO: better error handling, although in practical cases this will never happen.
            return $app->redirect($next);
        }
        $authorizationEndpoint = IndieAuth\Client::discoverAuthorizationEndpoint(ensureUrlHasHttp($me));
        if ($authorizationEndpoint === false) {
            // If the current user has no authorization endpoint set, they are using the basic indieauth flow.
            $authorizationEndpoint = rtrim($app['indieauth.url'], '/') . '/auth';
            return $app->redirect("{$authorizationEndpoint}?me={$me}&redirect_uri={$next}");
        }
        // As more scopes become defined, this will need to be expanded + probably made configurable.
        $micropubEndpoint = IndieAuth\Client::discoverMicropubEndpoint(ensureUrlHasHttp($me));
        $scope = !empty($micropubEndpoint) ? 'post' : '';
        $random = mt_rand(1000000, pow(2, 31));
        $redirectEndpoint = $app['url_generator']->generate('indieauth.authorize', [], true);
        $authorizationUrl = IndieAuth\Client::buildAuthorizationUrl($authorizationEndpoint, $me, $redirectEndpoint, $clientIdForRequest($request), $random, $scope);
        $response = $app->redirect($authorizationUrl);
        // Retain random state for five minutes in secure, HTTP-only cookie.
        $cookie = new Http\Cookie("{$cookieName}_random", $app['encryption']->encrypt($random), time() + 60 * 5, null, null, $secureCookies, true);
        $response->headers->setCookie($cookie);
        return $response;
    })->bind('indieauth.login');
    $auth->get('/authorize/', function (Http\Request $request) use($app, $dataToCookie, $cookieName, $cookieLifetime, $redirectUrlForRequest, $clientIdForRequest, $secureCookies) {
        $random = $app['encryption']->decrypt($request->cookies->get("{$cookieName}_random"));
        $me = $request->query->get('me');
        $state = $request->query->get('state');
        $code = $request->query->get('code');
        if ($state != $random) {
            $app['logger']->info('Authentication failed as state didn’t match random in cookie', ['state' => $state, 'cookie.random' => $random]);
            return $app->redirect('/');
        }
        $tokenEndpoint = IndieAuth\Client::discoverTokenEndpoint($me);
        $redirectUrl = $app['url_generator']->generate('indieauth.authorize', [], true);
        $token = IndieAuth\Client::getAccessToken($tokenEndpoint, $code, $me, $redirectUrl, $clientIdForRequest($request), $state);
        $token['micropub_endpoint'] = IndieAuth\Client::discoverMicropubEndpoint(ensureUrlHasHttp($me));
        $app['logger']->info("Indieauth: Got token, discovered micropub endpoint", ['token' => $token]);
        $response = $app->redirect($redirectUrlForRequest($request));
        // Store token data in secure, HTTP-only session cookie.
        $tokenCookie = new Http\Cookie($cookieName, $dataToCookie($token), time() + $cookieLifetime, null, null, $secureCookies, true);
        $response->headers->setCookie($tokenCookie);
        return $response;
    })->bind('indieauth.authorize');
    $auth->post('/logout/', function (Http\Request $request) use($app, $redirectUrlForRequest, $cookieName) {
        // In the bizarre case that a request to /logout/ also had a basic-flow indieauth token, prevent the ->after() handler
        // from setting remember-me cookies.
        $request->attributes->set('indieauth.islogoutrequest', true);
        $response = $app->redirect($redirectUrlForRequest($request));
        $app['indieauth']->logoutResponse($response);
        return $response;
    })->bind('logout');
    $app->before(function (Http\Request $request) use($app, $dataFromCookie, $cookieName) {
        // If the user has full indieauth credentials, make their token information (scope,
        // access key, micropub endpoint) available to controllers.
        if ($request->cookies->has($cookieName)) {
            try {
                /**
                 * indieauth.client.token is an array potentially containing the following properties:
                 * * me: URL of the current user (guaranteed to exist + be a valid URL)
                 * * scope: space-separated list of scopes the user has granted this app
                 * * access_token: the user’s access token
                 * * micropub_endpoint: the user’s micropub endpoint
                 *
                 * If only “me” exists then the user is logged in using the basic indieauth flow — their URL is confirmed but they
                 * haven’t granted us any permissions, and maybe don’t even have a micropub endpoint.
                 */
                $token = $dataFromCookie($request->cookies->get($cookieName));
                $loggableToken = $token;
                // Don’t log the sensitive access key, only the length, so devs can see if there *was* an access token or not.
                $loggableToken['access_token'] = 'Unlogged string of length ' . strlen($token['access_token']);
                $request->attributes->set('indieauth.client.token', $token);
                $app['logger']->info('Request has indieauth token', ['token' => $loggableToken]);
            } catch (Exception $e) {
                $app['logger']->warning("Caught an unhandled exception whilst running \$dataFromCookie on the current user’s indieauth token — consider handling this exception appropriately", ['exception class' => get_class($e), 'message' => $e->getMessage()]);
            }
        } elseif ($request->query->has('token')) {
            // The user is logging in using the basic indieauth flow, so all we know about them is their URL.
            // A remember-me cookie will be set for them later.
            $client = new Guzzle\Http\Client($app['indieauth.url']);
            try {
                $response = $client->get('session?token=' . $request->query->get('token'))->send();
                $basicToken = json_decode($response->getBody(true), true);
                $request->attributes->set('indieauth.client.token', $basicToken);
            } catch (Guzzle\Common\Exception\GuzzleException $e) {
                $app['logger']->warning('Authenticating user with indieauth.com failed: ' . $e->getMessage());
            }
        }
    });
    $app->after(function (Http\Request $request, Http\Response $response) use($app, $dataToCookie, $cookieName, $cookieLifetime, $secureCookies) {
        // If the request is a basic-flow indieauth login request, set a remember-me cookie.
        if ($request->query->has('token') and $request->attributes->has('indieauth.client.token') and !$request->attributes->get('indieauth.islogoutrequest', false)) {
            $tokenCookie = new Http\Cookie($cookieName, $dataToCookie($request->attributes->get('indieauth.client.token')), time() + $cookieLifetime, null, null, $secureCookies, true);
            $response->headers->setCookie($tokenCookie);
        }
    });
    return $auth;
}
 public function testFinishFilter()
 {
     $containerTarget = array();
     $app = new Application();
     $app->finish(function () use(&$containerTarget) {
         $containerTarget[] = '4_filterFinish';
     });
     $app->get('/foo', function () use(&$containerTarget) {
         $containerTarget[] = '1_routeTriggered';
         return new StreamedResponse(function () use(&$containerTarget) {
             $containerTarget[] = '3_responseSent';
         });
     });
     $app->after(function () use(&$containerTarget) {
         $containerTarget[] = '2_filterAfter';
     });
     $app->run(Request::create('/foo'));
     $this->assertSame(array('1_routeTriggered', '2_filterAfter', '3_responseSent', '4_filterFinish'), $containerTarget);
 }