Beispiel #1
0
 /**
  * Displays a login form on {@link SecurityException}.
  *
  * @param \ICanBoogie\Exception\RescueEvent $event
  * @param SecurityException $target
  */
 public static function on_security_exception_rescue(\ICanBoogie\Exception\RescueEvent $event, SecurityException $target)
 {
     global $core;
     $request = $event->request;
     if ($request->context->dispatcher instanceof \ICanBoogie\Operation\Dispatcher && $request->is_xhr) {
         return;
     }
     if ($target instanceof PermissionRequired || \ICanBoogie\Routing\decontextualize($request->normalized_path) != '/admin/') {
         \ICanBoogie\log_error($target->getMessage());
     }
     $block = $core->modules['users']->getBlock('connect');
     $document = new \Icybee\DocumentDecorator(new \Icybee\AdminDecorator($block));
     $document->body->add_class('page-slug-authenticate');
     $event->response = new Response((string) $document, $target->getCode(), ['Content-Type' => 'text/html; charset=utf-8']);
     $event->stop();
 }
Beispiel #2
0
 /**
  * Redirects the request to the first available website to the user if the request matches
  * none.
  *
  * Only online websites are used if the user is a guest or a member.
  *
  * @param Dispatcher\BeforeDispatchEvent $event
  * @param Dispatcher $target
  */
 public static function before_http_dispatcher_dispatch(Dispatcher\BeforeDispatchEvent $event, Dispatcher $target)
 {
     global $core;
     if ($core->site_id) {
         return;
     }
     $request = $event->request;
     if (!in_array($request->method, array(Request::METHOD_ANY, Request::METHOD_GET, Request::METHOD_HEAD))) {
         return;
     }
     $path = \ICanBoogie\normalize_url_path(\ICanBoogie\Routing\decontextualize($request->path));
     if (strpos($path, '/api/') === 0) {
         return;
     }
     try {
         $query = $core->models['sites']->order('weight');
         $user = $core->user;
         if ($user->is_guest || $user instanceof \Icybee\Modules\Members\Member) {
             $query->filter_by_status(Site::STATUS_OK);
         }
         $site = $query->one;
         if ($site) {
             $request_url = \ICanBoogie\normalize_url_path($core->site->url . $request->path);
             $location = \ICanBoogie\normalize_url_path($site->url . $path);
             #
             # we don't redirect if the redirect location is the same as the request URL.
             #
             if ($request_url != $location) {
                 $query_string = $request->query_string;
                 if ($query_string) {
                     $location .= '?' . $query_string;
                 }
                 $event->response = new RedirectResponse($location, 302, array('Icybee-Redirected-By' => __CLASS__ . '::' . __FUNCTION__));
                 return;
             }
         }
     } catch (\Exception $e) {
     }
     \ICanBoogie\log_error('You are on a dummy website. You should check which websites are available or create one if none are.');
 }
Beispiel #3
0
 /**
  * Creates an operation instance from a request.
  *
  * An operation can be defined as a route, in which case the path of the request starts with
  * "/api/". An operation can also be defined using the request parameters, in which case
  * the {@link DESTINATION}, {@link NAME} and optionally {@link KEY} parameters are defined
  * within the request parameters.
  *
  * When the operation is defined as a route, the method searches for a matching route.
  *
  * If a matching route is found, the captured parameters of the matching route are merged
  * with the request parameters and the method tries to create an Operation instance using the
  * route.
  *
  * If no matching route could be found, the method tries to extract the {@link DESTINATION},
  * {@link NAME} and optional {@link KEY} parameters from the route using the
  * `/api/:destination(/:key)/:name` pattern. If the route matches this pattern, captured
  * parameters are merged with the request parameters and the operation decoding continues as
  * if the operation was defined using parameters instead of the REST API.
  *
  * Finally, the method searches for the {@link DESTINATION}, {@link NAME} and optional
  * {@link KEY} parameters within the request parameters to create the Operation instance.
  *
  * If no operation was found in the request, the method returns null.
  *
  *
  * Instancing using the matching route
  * -----------------------------------
  *
  * The matching route must define either the class of the operation instance (by defining the
  * `class` key) or a callback that would create the operation instance (by defining the
  * `callback` key).
  *
  * If the route defines the instance class, it is used to create the instance. Otherwise, the
  * callback is used to create the instance.
  *
  *
  * Instancing using the request parameters
  * ---------------------------------------
  *
  * The operation destination (specified by the {@link DESTINATION} parameter) is the id of the
  * destination module. The class and the operation name (specified by the {@link NAME}
  * parameter) are used to search for the corresponding operation class to create the instance:
  *
  *     ICanBoogie\<normalized_module_id>\<normalized_operation_name>Operation
  *
  * The inheritance of the module class is used the find a suitable class. For example,
  * these are the classes tried for the "articles" module and the "save" operation:
  *
  *     ICanBoogie\Modules\Articles\SaveOperation
  *     ICanBoogie\Modules\Contents\SaveOperation
  *     ICanBoogie\Modules\Nodes\SaveOperation
  *
  * An instance of the found class is created with the request arguments and returned. If the
  * class could not be found to create the operation instance, an exception is raised.
  *
  * @param Request $request The request parameters.
  *
  * @throws \BadMethodCallException when the destination module or the operation name is
  * not defined for a module operation.
  *
  * @throws NotFound if the operation is not found.
  *
  * @return Operation|null The decoded operation or null if no operation was found.
  */
 protected static function from_request(Request $request)
 {
     $path = \ICanBoogie\Routing\decontextualize($request->path);
     $extension = $request->extension;
     if ($extension == 'json') {
         $path = substr($path, 0, -5);
         $request->headers['Accept'] = 'application/json';
         $request->headers['X-Requested-With'] = 'XMLHttpRequest';
         // FIXME-20110925: that's not very nice
     } else {
         if ($extension == 'xml') {
             $path = substr($path, 0, -4);
             $request->headers['Accept'] = 'application/xml';
             $request->headers['X-Requested-With'] = 'XMLHttpRequest';
             // FIXME-20110925: that's not very nice
         }
     }
     $path = rtrim($path, '/');
     if (substr($path, 0, self::RESTFUL_BASE_LENGTH) == self::RESTFUL_BASE) {
         $operation = static::from_route($request, $path);
         if ($operation) {
             return $operation;
         }
         if ($request->is_patch) {
             preg_match('#^([^/]+)/(\\d+)$#', substr($path, self::RESTFUL_BASE_LENGTH), $matches);
             if (!$matches) {
                 throw new NotFound(format('Unknown operation %operation.', ['operation' => $path]));
             }
             list(, $module_id, $operation_key) = $matches;
             $operation_name = 'patch';
         } else {
             #
             # We could not find a matching route, we try to extract the DESTINATION, NAME and
             # optional KEY from the URI.
             #
             preg_match('#^([a-z\\.\\-]+)/(([^/]+)/)?([a-zA-Z0-9_\\-]+)$#', substr($path, self::RESTFUL_BASE_LENGTH), $matches);
             if (!$matches) {
                 throw new NotFound(format('Unknown operation %operation.', ['operation' => $path]));
             }
             list(, $module_id, , $operation_key, $operation_name) = $matches;
         }
         if (empty(\ICanBoogie\app()->modules->descriptors[$module_id])) {
             throw new NotFound(format('Unknown operation %operation.', ['operation' => $path]));
         }
         if ($operation_key) {
             $request[self::KEY] = $operation_key;
         }
         return static::from_module_request($request, $module_id, $operation_name);
     }
     $module_id = $request[self::DESTINATION];
     $operation_name = $request[self::NAME];
     if (!$module_id && !$operation_name) {
         return null;
     } else {
         if (!$module_id) {
             throw new \BadMethodCallException("The operation's destination is required.");
         } else {
             if (!$operation_name) {
                 throw new \BadMethodCallException("The operation's name is required.");
             }
         }
     }
     return static::from_module_request($request, $module_id, $operation_name);
 }