Архив за месяц: Март 2009

Yii на ru.wikipedia.org

До сегодняшнего дня на ru.wikipedia.org не было страницы о Yii (может конечно я плохо искал 🙁 )….
Теперь она там есть http://ru.wikipedia.org/wiki/Yii!
В качестве моего бонуса – оставил ссылку на свой блог!

p.s. то моя первая статья на вики – так что прошу сильно не пинать!

День Ubuntu!

Сегодня у меня день linux!

Выдался свободный денек (правда я приболел немного). и я решил поставить Linux на свою домашнюю машину, а так же на свой любимый Asus. Долгое время (начиная с версии 10, кажется) я пользовался Open Suse Linux, но 11 версия меня разочаровала – постоянные глюки и зависания (на форуме сказали,что скорее всего дело в моем оборудовании и несовместимости с данной версией ОС….в 11.1 обещали испарвить) Однако решил сменить дистрибутив и попробывать, хвалимую всеми Ubuntu!

Не буду описывать процесс установки, все и так прекрасно знают!!!!

На свою домашнюю машину поставил – Ubuntu 8.10 и еще некоторый софт:

LAMP (Perl,Php,Python)

JDK 1.6

NetBeans IDE

Subversion

После всего этого мой рабочий стол стал похож на что-то вроде этого:

ubuntu 8.10

ubuntu 8.10

Если при выборе дистрибутива для домашнего компьютера есть большой выбор дистрибутивов, можно поставить Mandriva, Suse, Fedora и другие….То для eeepc лучше (хотя и не обязательно) ставить специально собранный для него, их тоже достаточно много. Я остановился так же на убунту (а именно сборка http://www.geteasypeasy.com/). После установки пришлось поставить несколько (3) дополнительных пакета после чего все (wifi, web-камера) прекрасно заработало!

И вот такой получился рабочий стол:

screenshot1

ubuntu easypeasy

Вот такие вот дела!

p.s. Поставил MysqlWorkbench….что могу сказать……файл созданный в версии для Windows – коряво открывается РАБОТАТЬ ПРОСТО НЕВОЗМОЖНО!!!!

Ошибочки и интересные факты

Добрый день, уважаемые читатели!

Данная статья положит начало серии  статей.

Я хочу собрать коллекцию скриншотов с интересными сообщениями об ошибках, ну или просто с сообщениями об ошибках на популярных ресурсах сети.

Сегодня хочу представить Вашему вниманию сразу 2 экземпляра.

Ошибка сертификата у Google

Ошибка сертификата у Google

Вот такое вот замечательное сообщение получил я, попытавшись зайти в раздел статистики Google Analytics. Может, конечно, может быть,  моя машина захвачена чудовищными вирусами (лицензия на KIS недавно закончилась :-)).

Второе менее страшное, да же, я  бы сказал, более веселое – отличился всеми любимый хабр.

Хабр жжет!

Хабр жжет!

Даже если в этот момент хабр действительно “лежал”, такое сообщение оставило приятное впечатление!

Думаю это не последняя моя заметка на эту тему, ведь не существует идеальных разработок 🙁     🙂

Yii, создаем свою CMS. База данных.

Краткое содержание предыдущих серий

1 Вступление

И так, имея скромный набор требований, описанный в первой статье, перейдем непосредственно к разработке.

Когда я приступаю к разработке нового приложения или сайта, и уже более или менее понятно с какими сущностями придется работать и какие данные хранить, лично я, предпочитаю нарисовать схему базы данных, которая в будущем будет хранить всю информацию приложения. Такая схема позволит более наглядно представить все объекты, разрабатываемого приложения и взаимосвязи между ними. Для рисования таких схем, можно воспользоваться любым инструментом, начиная от листа бумаги и карандаша, заканчивая специализированным ПО, типа MS VISIO. Однако, я предпочитаю программное обеспечение, специально предназначенное для этих целей. Довольно давно, я пользуюсь Mysql Workbench, для проектирования баз данных Mysql, подробнее узнать про эту программу и скачать ее, можно тут.

Примерно за 40 минут работы, у меня получилась вот такая вот схема БД.

Схема бвзы данных

Сейчас постараюсь подробно рассказать про назначение каждой таблицы и каждого столбца.

И так поехали!

User – предназначена для хранения данных о зарегистрированных пользователях (на первом этапе разработки, наша цмска будет однопользовательской – т.е.  добавлять контент сможет любой пользователь прошедший авторизацию, в связи с этим, на первом этапе не будет возможности регистрироваться новым пользователям).

  • userId – идентификатор пользователя;
  • name   – имя пользователя;
  • email  – email пользователя;
  • password – пароль пользователя;
  • creationDate – дата регистрации пользователя (пока система однопользовательская – особого смысла в этом поле нет);
  • status  – 0 – пользователь активен 1 – пользователь заблокирован;
  • accessLevel – 0 – простой пользователь 1 – администратор (может управлять контентом и совершать административные действия)

System – таблица для хранения всех системных параметров.

  • systemId   – идентификатор записи
  • siteUrl  – основной url сайта
  • siteInfo– информация о сайте
  • siteDescription – описание сайта
  • ownerInfo            – информация о владельце
  • ownerEmail        – email администратора сайта
  • userId                      – пользователь создавший настройку (в однопользовательской работе на учитывается)

Content – данная таблица будет содержать все записи (посты), страницы и все остальное наполнение нашего движка.

  • contentId – идентификатор записи
  • title  – заголовок записи
  • alias  – строка Url данного записи
  • content – содержимое поста
  • status  – 0 – черновик, 1 – опубликовано
  • keywords – ключевые слова для записи (meta)
  • description – описание записи (meta)
  • createdBy   – идентификатор пользователя создавшего запись
  • creationDate – дата создания
  • active       – признак того что эта запись является самой последней (актуальной)
  • canComment   – разрешены ли комментарии для данной записи
  • isPrivate    – пост доступен только авторизованным пользователям (в версии 1 нашего движка это работать не будет)
  • publishDate  – дата публикации
  • revision – номер версии записи
  • contentParentId – идентификатор, изначально созданной записи
  • revisionParentId – идентификатор, предыдущей ревизии
  • contentType – тип контента  2 – запись (пост) 1 – страница
  • modifyDate – дата изменения
  • modifyBy                   – кем изменено
  • commentCnt          – количество комментариев

Comment – таблица хранит комментарии к постам и страницам (?).

  • commentId – идентификатор комментария
  • parentId  – родительский комментарий (в первой версии движка мы его использовать скорее всего не будем)
  • postId    – идентификатор поста, к которому относится комментарий
  • comment   – текст комментария
  • creationDate – дата создания комментария
  • userName     – имя пользователя, создавшего комментарий
  • userEmail    – email пользователя, создавшего комментарий
  • userUrl      – url пользователя, создавшего комментарий
  • userIp       – ip-адрес пользователя оставившего комментарий
  • status       – 0 – комментарий не подтвержден, 1 – комментарий одобрен, 2 – спам


Tag –
таблица хранит тэги.

  • tagId – идентификатор тэга
  • tag   – название тэга

TagContent- таблица предназначена для хранения отношения тегов и постов

  • tagContentId – идентификатор контента
  • contentId    – идентификатор записи
  • tagId     – идентификатор тэга

Я думаю, что в процессе разработки, придется корректировать и дополнять эту схему, но для начала работы она вполне подойдет.

Если есть какие-то замечание или предложения – прошу высказываться в комментариях.

p.s. Названия движка, пока так и не выбрано – любые варианты приветствуются!

Основной сайт Юпи! – http://yupe.ru

Исходный код – https://github.com/yupe/yupe

Присоединяйтесь!

Yii, пишем фильтр для предотвращения XSS атак.

Начну с небольшого отступления.

И все таки правильно говорят, а на некторых форумах (особенно UNIX-овых), прямо кричат – RTFM! Кто не понял очем идет речь – RTFM в переводе означает “читай эту чертову документацию!”.  Это все я собственно вот к чему: изучая и что-то пытаясь написать на фреймворке Yii,  возникла задача фильтрации входных данных от различного рода “зловредных” символов (аля XSS-атака) и первое что пришло в голову – это написать свой фильтр (что я все таки и сделал), однако creocoder, на форуме Yii , совершенно спрпаведливо заметил, что не зачем изобретать велосипед, все уже есть готовое, необходимо только RTFM! Речь шла о классе CHtmlPurifier, который является оберткой для библиотеки HTML Purifier , и выполняет все те функции, которые мне необходимы (правда я так и не попробывал его в действии, может и зря конечно). Но раз уж я начал писать свой фильтр – решил все таки это дело завершить, да и просто написать статью о фильтрах в Yii.

И так!

Фильтры – фрагменты кода, которые могут быть выполнены до и\или после выполнения экшена  контроллера.  Фильтры, при необходимости, могут  не допустить выполнения запрошенного экшена.

Фильтры могут быть как методами текущего контроллера, так и отдельными классами – что позволяет повторно их использовать. Если фильтр реализуется как метод класса, он должен иметь префикс “filter”.

Пример:

public function filterAccessControl()
{
 .......
}

Фильтр, реализованный в виде отдельного класса, должен быть наследником класса CFilter.

Пример:

class XssFilter extends CFilter
{
   // код который выполнится до выполнения экшена
 public function preFilter()
 {
  .......
 }
 // код который выполнится после выполнения экшена
 public function postFilter()
 {
 .......
 }
}

Для активации фильтров, необходимо в контроллере переопределить метод filters,который должен вернуть массив всех фильтров для данного контроллера (или его отдельных экшенов).

Пример:

public function filters()
{
 return array(
           'accessControl',
           array(
             'application.filters.XssFilter',
             'clean' => 'all'
          )
  );
}

В этом примере ‘accessControl’ – фильтр, реализованный как метод контроллера, а ‘application.filters.XssFilter’ – фильтр, реализованный в виде отдельного класса, который хранится в каталоге /protected/filters/. ‘clean’ – устанавливаем свойство фильтра.

Это была краткая справка  по фильтрам в Yii, более подробно можно почитать тут.

Теперь непосредственно приступим к реализации нашего фильтра. Функцию очистки данных, которая и выполняет всю работу – я взял из фреймворка Kohana. Ну на этом достаточно слов, приведу сам код фильтра – он  совсем простой, так что думаю проблем быть не должно.

  /**
   *  @author  Opeykin A. <opeykin.ru&; <aopeykin@gmail.com>
   *  @version 0.0.1
   *  @package filters
   *
   * Фильтр предназначен для фильтрации входных данных, c целью предотвратить xss атаки.
   * Для фильтрации используются регулярные выражения из фреймворка Kohana 2.3.1
   * @example
   *
   *  public function filters()
   *  {
   *         return array(
   *                 array('application.filters.XssFilter',
   *                       'clean' =>; 'all'
   *                 )
   *         );
   *
   *   }
   *
   *   В качетве параметра 'clean' могут быть:
   *  - 'all' - фильтруются GET,POST,COOKIE,FILES массивы;
   *  - '*'   - аналог ALL;
   *  - так же возможно сочетание любых из параметров, например GET,COOKIE или POST,FILES
   */

class XssFilter extends CFilter
{
   public  $clean = 'all';

  protected function preFilter($filterChain)
  {
  $this->clean  = trim(strtoupper($this->clean));
  $data = array(
  'GET'    =>&$_GET,
  'POST'   =>&$_POST,
  'COOKIE' =>&$_COOKIE,
  'FILES'  =>&$_FILES
  );

  if($this->clean === 'ALL' || $this->clean === '*')
  {
    $this->clean = 'GET,POST,COOKIE,FILES';
  }
  $dataForClean = split(',',$this->clean);
  if(count($dataForClean))
  {
     foreach ($dataForClean as $key => $value)
     {
        if(isset ($data[$value]) && count($data[$value]))
        {
           $this->doXssClean($data[$value]);
        }
     }
 }
return true;
}

  protected function postFilter($filterChain)
  {
    // logic being applied after the action is executed
  }

  private function doXssClean(&$data)
  {
     if(is_array($data) && count($data))
  {
    foreach($data as $k => $v)
  {
     $data[$k] = $this->doXssClean($v);
  }
     return $data;
}

if(trim($data) === '')
{
return $data;
}

// xss_clean function from Kohana framework 2.3.1
$data = str_replace(array('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;gt;'), $data);
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');
// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);
// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);
// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);
// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);
do
{
// Remove really unwanted tags
$old_data = $data;
$data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);
return $data;
}

}

Я совсем немного протестировал это фильтр – на первый взгляд – все работает!

Любые замечания и комментарии приветствуются!

Хочу добавить свои замечания к реализации фильтров в Yii…

Мне кажется было удобно иметь метод, который вызывается перед выполнением preFilter и postFilter, например init() – который выполняет инициализацию фильтра, при этом в нем должны быть доступны параметры, передавемые в фильтр из контроллера  (по этой причине невозможно использовать __construct). Конечно можно расширить CFilter для этих целей, но “родная” возможность сделать это была бы лучшим вариантом.

Надеюсь, описанный материал окажется полезен!

Ищите разработчиков на Yii ?

Мы решим Ваши задачи!

Скачать xssfilter