Browse Source

Merge branch 'master' of git://github.com/yiisoft/yii2 into guide-structure-applications

tags/2.0.6
elysdir 10 years ago
parent
commit
6029cd1632
  1. 61
      docs/guide-pt-BR/concept-properties.md
  2. 6
      docs/guide-ru/README.md
  3. 2
      docs/guide-ru/runtime-sessions-cookies.md
  4. 34
      docs/guide-ru/security-authentication.md
  5. 113
      docs/guide-ru/security-authorization.md
  6. 177
      docs/guide-ru/security-best-practices.md
  7. 152
      docs/guide-ru/security-passwords.md
  8. 2
      docs/guide/concept-properties.md
  9. 5
      docs/guide/security-best-practices.md
  10. 10
      docs/internals-ja/git-workflow.md
  11. 3
      docs/internals-pt-BR/translation-workflow.md
  12. 15
      docs/internals-ru/automation.md
  13. 233
      docs/internals-ru/git-workflow.md
  14. 53
      docs/internals-ru/view-code-style.md
  15. 34
      docs/internals/git-workflow.md

61
docs/guide-pt-BR/concept-properties.md

@ -0,0 +1,61 @@
Propriedades
===========
No PHP, atributos da classe são sempre chamadas de *propriedades*. Esses atributos fazem parte da definição da classe e são usadas para representar o estado de uma instância da classe (para diferenciar uma instância da classe de outra). Na prática, muitas vezes você pode querer lidar com a leitura ou a escrita de propriedades de maneiras especiais. Por Exemplo, você pode querer trimar uma string sempre que for atribuído um valor para a propriedade `label`. Você *poderia* usar o código a seguir para realizar esta tarefa:
```php
$object->label = trim($label);
```
A desvantagem do código acima é que você teria que chamar `trim ()` em todos os lugares onde você definir a propriedade `label` no seu código. Se, no futuro, a propriedade `label` receber um novo requisito, tais como a primeira letra deve ser capitalizado, você teria que modificar novamente todos os pedaços de código que atribui um valor para a propriedade `label`. A repetição de código leva a erros, e é uma prática que você deve evitar sempre que possível.
Para resolver este problema, Yii introduz uma classe base chamada [[yii\base\Object]] que suporta definições de propriedades baseadas nos métodos *getter* e *setter* da classe. Se uma classe precisa dessa funcionalidade, ela deve estender de [[yii\base\Object]], ou de uma classe-filha.
> Informação: Quase todas as classes nativas (core) do framework Yii estendem de [[yii\base\Object]] ou de uma classe-filha. Isto significa que sempre que você vê um método *getter* ou *setter* em uma classe nativa (core), você pode usá-lo como uma propriedade.
Um método getter é um método cujo nome inicia com a palavra `get`; um método setter inicia com `set`.
O nome depois do prefixo `get` ou `set` define o nome da propriedade. Por exemplo, um getter `getLabel()` e/ou um setter `setLabel()` define a propriedade chamada `label`, como mostrado no código a seguir:
```php
namespace app\components;
use yii\base\Object;
class Foo extends Object
{
private $_label;
public function getLabel()
{
return $this->_label;
}
public function setLabel($value)
{
$this->_label = trim($value);
}
}
```
(Para ser claro, os métodos getter e setter criam a propriedade `label`, que neste caso internamente refere-se ao atributo privado chamado `_label`.)
Propriedades definidas por getters e setters podem ser usados como atributos da classe. A principal diferença é que quando tal propriedade é iniciada para leitura, O método getter correspondente será chamado; quando a propriedade é iniciada atribuindo um valor, o método setter correspondente será chamado. Por Exemplo:
```php
// equivalent to $label = $object->getLabel();
$label = $object->label;
// equivalent to $object->setLabel('abc');
$object->label = 'abc';
```
A propriedade definida por um método getter sem um método setter é *somente de leitura*. Tentando atribuir um valor a tal propriedade causará uma exceção [[yii\base\InvalidCallException|InvalidCallException]]. Semelhantemente, uma propriedade definida por um método setter sem um método getter é *somente de gravação *, e tentar ler tal propriedade também causará uma exceção. Não é comum ter propriedade *somente de gravação*.
Existem várias regras especiais para, e limitações sobre, as propriedades definidas via getters e setters:
* Os nomes dessas propriedades são *case-insensitive*. Por exemplo, `$object->label` e `$object->Label` são a mesma coisa. Isso ocorre porque nomes de métodos no PHP são case-insensitive.
* Se o nome de uma tal propriedade é o mesmo que um atributo da classe, esta última terá precedência. Por exemplo, se a classe `Foo` descrita acima tiver um atributo `label`, então a atribuição `$object->label = 'abc'` afetará o *atributo* 'label'; esta linha não executaria `setLabel()` método setter.
* Essas propriedades não suportam visibilidade. Não faz nenhuma diferença para a definição dos métodos getter ou setter se a propriedade é pública, protegida ou privada.
* As propriedades somente podem ser definidas por getters e/ou setters *não estáticos*. Os métodos estáticos não serão tratados da mesma maneira.
Voltando para o problema descrito no início deste guia, em vez de chamar `trim()` em todos os lugares que um valor for atribuído a `label`, `trim()`Agora, só precisa ser invocado dentro do setter `setLabel()`.E se uma nova exigência faz com que seja necessário que o 'label' seja inicializado capitalizado, o método `setLabel()` pode rapidamente ser modificado sem tocar em nenhum outro código. Esta única mudança afetará de forma global cada atribuição à propriedade `label`.

6
docs/guide-ru/README.md

@ -109,9 +109,9 @@ All Rights Reserved.
* [Аутентификация](security-authentication.md) * [Аутентификация](security-authentication.md)
* [Авторизация](security-authorization.md) * [Авторизация](security-authorization.md)
* **TBD** [Работа с паролями](security-passwords.md) * [Работа с паролями](security-passwords.md)
* [Клиенты авторизации](https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md) * **TBD** [Клиенты авторизации](security-auth-clients.md)
* **TBD** [Лучшие практики](security-best-practices.md) * [Лучшие практики](security-best-practices.md)
Кеширование Кеширование

2
docs/guide-ru/runtime-sessions-cookies.md

@ -267,7 +267,7 @@ unset($cookies['language']);
Во время записи и чтения кук через компоненты `request` и `response`, как будет показано в двух последующих подразделах, фреймворк предоставляет автоматическую валидацию, которая обеспечивает защиту кук от модификации на стороне клиента. Это достигается за счет подписи каждой куки секретным ключом, позволяющим приложению распознать куку, которая была модифицирована на клиентской стороне. В таком случае кука НЕ БУДЕТ доступна через свойство [[yii\web\Request::cookies|cookie collection]] компонента `request`. Во время записи и чтения кук через компоненты `request` и `response`, как будет показано в двух последующих подразделах, фреймворк предоставляет автоматическую валидацию, которая обеспечивает защиту кук от модификации на стороне клиента. Это достигается за счет подписи каждой куки секретным ключом, позволяющим приложению распознать куку, которая была модифицирована на клиентской стороне. В таком случае кука НЕ БУДЕТ доступна через свойство [[yii\web\Request::cookies|cookie collection]] компонента `request`.
> Замечение: Валидация кук защищает только от их модификации. Если валидация не была пройдена, получить доступ к кукам все еще можно через глобальную переменную `$_COOKIE`. Это связано с тем, что дополнительные пакеты и библиотеки могут манипулировать куками без вызова валидации, которую обеспепичает Yii. > Замечение: Валидация кук защищает только от их модификации. Если валидация не была пройдена, получить доступ к кукам все еще можно через глобальную переменную `$_COOKIE`. Это связано с тем, что дополнительные пакеты и библиотеки могут манипулировать куками без вызова валидации, которую обеспечивает Yii.
По-умолчанию валидация кук включена. Её можно отключить, установив свойство [[yii\web\Request::enableCookieValidation]] По-умолчанию валидация кук включена. Её можно отключить, установив свойство [[yii\web\Request::enableCookieValidation]]
в false, однако мы настоятельно не рекомендуем это делать. в false, однако мы настоятельно не рекомендуем это делать.

34
docs/guide-ru/security-authentication.md

@ -1,11 +1,11 @@
Аутентификация Аутентификация
============== ==============
Аутентификация это процесс проверки подлинности пользователя. Обычно используется идентификатор Аутентификация - это процесс проверки подлинности пользователя. Обычно используется идентификатор
(например `username` или адрес электронной почты) и секретный токен (например пароль или ключ доступа), чтобы судить о (например `username` или адрес электронной почты) и секретный токен (например пароль или ключ доступа), чтобы судить о
том что пользователь именно тот за кого себя выдаёт. Аутентификация является основной функуцией формы входа. том что пользователь именно тот за кого себя выдаёт. Аутентификация является основной функуцией формы входа.
Yii обеспечивает фреймворк авторизации с различнымы компонентами обеспечивающими процесс входа. Yii обеспечивает фреймворк авторизации с различнымы компонентами, обеспечивающими процесс входа.
Для использования этого фреймворка, вам нужно проделать следующее: Для использования этого фреймворка, вам нужно проделать следующее:
* Настроить компонент приложения [[yii\web\User|user]]; * Настроить компонент приложения [[yii\web\User|user]];
@ -38,12 +38,12 @@ return [
* [[yii\web\IdentityInterface::findIdentity()|findIdentity()]]: Этот метод находит экземпляр `identity class`, * [[yii\web\IdentityInterface::findIdentity()|findIdentity()]]: Этот метод находит экземпляр `identity class`,
используя ID пользователя. Этот метод используется, когда необходимо поддерживать состояние аутентификации через сессии. используя ID пользователя. Этот метод используется, когда необходимо поддерживать состояние аутентификации через сессии.
* [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]: Этот метод находит экземпляр `identity class`, * [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]: Этот метод находит экземпляр `identity class`,
используя токен доступа. Этот метод используется когда нужно аутентифицировать пользователя используя токен доступа. Этот метод используется, когда нужно аутентифицировать пользователя
по единственному секретному токену (например в RESTful приложениях, не сохраняющих состояние между запросами). по одному секретному токену (например в RESTful приложениях, не сохраняющих состояние между запросами).
* [[yii\web\IdentityInterface::getId()|getId()]]: Этот метод возвращает ID пользователя представленного данным экземпляром `identity`. * [[yii\web\IdentityInterface::getId()|getId()]]: Этот метод возвращает ID пользователя, представленного данным экземпляром `identity`.
* [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]: Этот метод возвращает ключ используемый для основанной на `cookie` аутентификации. * [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]: Этот метод возвращает ключ, используемый для основанной на `cookie` аутентификации.
Ключ сохраняется в аутентификационной cookie и позже сравниватеся с версией находящейся на сервере, Ключ сохраняется в аутентификационной cookie и позже сравниватеся с версией находящейся на сервере,
чтоб удостоверится что аутентификационная `cookie` верная. чтобы удостоверится что аутентификационная `cookie` верная.
* [[yii\web\IdentityInterface::validateAuthKey()|validateAuthKey()]]: Этот метод реализует логику проверки ключа * [[yii\web\IdentityInterface::validateAuthKey()|validateAuthKey()]]: Этот метод реализует логику проверки ключа
для основанной на `cookie` аутентификации. для основанной на `cookie` аутентификации.
@ -117,7 +117,7 @@ class User extends ActiveRecord implements IdentityInterface
} }
``` ```
Как обьяснялось ранее, вам нужно реализовать только `getAuthKey()` и `validateAuthKey()` если ваше приложение использует Как обьяснялось ранее, вам нужно реализовать только `getAuthKey()` и `validateAuthKey()`, если ваше приложение использует
только аутентификацию основанную на `cookie`. В этом случае, вы можете использовать следующий код для генерации только аутентификацию основанную на `cookie`. В этом случае, вы можете использовать следующий код для генерации
ключа аутентификации для каждого пользователя и хранения его в таблице `user`: ключа аутентификации для каждого пользователя и хранения его в таблице `user`:
@ -141,7 +141,7 @@ class User extends ActiveRecord implements IdentityInterface
> Замечание: Не путайте `identity` класс `User` с классом [[yii\web\User]]. Первый является классом реализующим > Замечание: Не путайте `identity` класс `User` с классом [[yii\web\User]]. Первый является классом реализующим
логику аутентификации пользователя. Он часто реализуется как класс [Active Record](db-active-record.md) связанный логику аутентификации пользователя. Он часто реализуется как класс [Active Record](db-active-record.md) связанный
с некоторым постоянным хранилищем где лежит информация о пользователях. Второй, это класс компонента приложения с некоторым постоянным хранилищем, где лежит информация о пользователях. Второй, это класс компонента приложения,
отвечающий за управление состоянием аутентификации пользователя. отвечающий за управление состоянием аутентификации пользователя.
@ -149,16 +149,16 @@ class User extends ActiveRecord implements IdentityInterface
В основном класс [[yii\web\User]] используют как компонент приложения `user`. В основном класс [[yii\web\User]] используют как компонент приложения `user`.
Можно получить `identity` текущего пользователя используя выражение `Yii::$app->user->identity`. Оно вернёт экземпляр Можно получить `identity` текущего пользователя, используя выражение `Yii::$app->user->identity`. Оно вернёт экземпляр
[[yii\web\User::identityClass|identity class]] представляющий текущего аутентифицированного пользователя, [[yii\web\User::identityClass|identity class]], представляющий текущего аутентифицированного пользователя,
или `null` если текущий пользователь не аутентифицирован (например гость). Следующий код показывает как получить или `null`, если текущий пользователь не аутентифицирован (например гость). Следующий код показывает как получить
другую связанную с аутентификацией информацию из [[yii\web\User]]: другую связанную с аутентификацией информацию из [[yii\web\User]]:
```php ```php
// `identity` текущего пользователя. `Null` если пользователь не аутентифицирован. // `identity` текущего пользователя. `Null`, если пользователь не аутентифицирован.
$identity = Yii::$app->user->identity; $identity = Yii::$app->user->identity;
// ID текущего пользователя. `Null` если пользователь не аутентифицирован. // ID текущего пользователя. `Null`, если пользователь не аутентифицирован.
$id = Yii::$app->user->id; $id = Yii::$app->user->id;
// проверка на то, что текущий пользователь гость (не аутентифицирован) // проверка на то, что текущий пользователь гость (не аутентифицирован)
@ -180,10 +180,10 @@ Yii::$app->user->login($identity);
[[yii\web\User::enableSession|включены]], то `identity` будет сохраняться в сессии, так что состояние [[yii\web\User::enableSession|включены]], то `identity` будет сохраняться в сессии, так что состояние
статуса аутентификации будет поддерживаться на всём протяжении сессии. Если основанный на cookie вход статуса аутентификации будет поддерживаться на всём протяжении сессии. Если основанный на cookie вход
(так называемый "запомни меня" вход) [[yii\web\User::enableAutoLogin|включен]], то `identity` также будет сохранена (так называемый "запомни меня" вход) [[yii\web\User::enableAutoLogin|включен]], то `identity` также будет сохранена
в `cookie` так чтобы статус аутентификации пользователя мог быть восстановлен на протяжении всего времени жизни `cookie`. в `cookie` так чтобы статус аутентификации пользователя может быть восстановлен на протяжении всего времени жизни `cookie`.
Для включения входа основанного на `cookie`, вам нужно установить [[yii\web\User::enableAutoLogin]] в `true` Для включения входа основанного на `cookie`, вам нужно установить [[yii\web\User::enableAutoLogin]] в `true`
в конфигурации приложения. Вы также можете настроить время жизни передав его при вызове метода [[yii\web\User::login()]]. в конфигурации приложения. Вы также можете настроить время жизни, передав его при вызове метода [[yii\web\User::login()]].
Для выхода пользователя, просто вызовите Для выхода пользователя, просто вызовите
@ -193,7 +193,7 @@ Yii::$app->user->logout();
Обратите внимание: выход пользователя имеет смысл только если сессии включены. Метод сбрасывает статус аутентификации Обратите внимание: выход пользователя имеет смысл только если сессии включены. Метод сбрасывает статус аутентификации
сразу и из памяти и из сессии. И по умолчанию, будут также уничтожены *все* сессионные данные пользователя. сразу и из памяти и из сессии. И по умолчанию, будут также уничтожены *все* сессионные данные пользователя.
Если вы хотите сохранить сессионные данные, вы должны вызвать `Yii::$app->user->logout(false)`, вместо этого. Если вы хотите сохранить сессионные данные, вы должны вместо этого вызвать `Yii::$app->user->logout(false)`.
## События аутентификации <span id="auth-events"></span> ## События аутентификации <span id="auth-events"></span>

113
docs/guide-ru/security-authorization.md

@ -10,7 +10,7 @@
Фильтры контроля доступа Фильтры контроля доступа
------------------------ ------------------------
Фильтры контроля доступа (ACF) является простым методом, который лучше всего использовать в приложениях с простым Фильтры контроля доступа (ACF) являются простым методом, который лучше всего использовать в приложениях с простым
контролем доступа. Как указывает его название, ACF это фильтры, который может присоединяться к контроллеру контролем доступа. Как указывает его название, ACF это фильтры, который может присоединяться к контроллеру
или модулю как поведение. ACF проверяет набор [[yii\filters\AccessControl::rules|правил доступа]], чтоб убедится, или модулю как поведение. ACF проверяет набор [[yii\filters\AccessControl::rules|правил доступа]], чтоб убедится,
что пользователь имеет доступ к запрошенной операции. что пользователь имеет доступ к запрошенной операции.
@ -47,7 +47,7 @@ class SiteController extends Controller
} }
``` ```
Код выше показывет ACF прикреплённы через поведение контроллера `site`. Это типичный способ использования фильтра действий. Код выше показывет ACF связанный с контроллером `site` через поведение. Это типичный способ использования фильтров действий.
Параметр `only` указывает, что фильтр ACF нужно применять только к действиям `login`, `logout` и `signup`. Параметр `only` указывает, что фильтр ACF нужно применять только к действиям `login`, `logout` и `signup`.
Параметр `rules` задаёт [[yii\filters\AccessRule|правила доступа]], которые означают следующее: Параметр `rules` задаёт [[yii\filters\AccessRule|правила доступа]], которые означают следующее:
@ -60,50 +60,50 @@ class SiteController extends Controller
Значение опции `allow` выбранного правила указывает авторизовывать пользователя или нет. Если ни одно из правил Значение опции `allow` выбранного правила указывает авторизовывать пользователя или нет. Если ни одно из правил
не совпало, то пользователь считается НЕ авторизованным и ACF останавливает дальнейшее выполнение деиствия. не совпало, то пользователь считается НЕ авторизованным и ACF останавливает дальнейшее выполнение деиствия.
По умолчанию, ACF когда у пользователя отсутствует доступ к текущему действию, делает следующее: По умолчанию, ACF, когда у пользователя отсутствует доступ к текущему действию, делает следующее:
* Если пользователь гость, вызывается [[yii\web\User::loginRequired()]], который перенаправляет браузер на страницу входа. * Если пользователь гость, вызывается [[yii\web\User::loginRequired()]], который перенаправляет браузер на страницу входа.
* Если пользователь авторизован, генерируется исключение [[yii\web\ForbiddenHttpException]]. * Если пользователь авторизован, генерируется исключение [[yii\web\ForbiddenHttpException]].
Вы можете переопределить это поведение настроив свойство [[yii\filters\AccessControl::denyCallback]]: Вы можете переопределить это поведение, настроив свойство [[yii\filters\AccessControl::denyCallback]]:
```php ```php
[ [
'class' => AccessControl::className(), 'class' => AccessControl::className(),
'denyCallback' => function ($rule, $action) { 'denyCallback' => function ($rule, $action) {
throw new \Exception('You are not allowed to access this page'); throw new \Exception('У вас нет доступа к этой странице');
} }
] ]
``` ```
[[yii\filters\AccessRule|Правила доступа]] поддерживает набор свойств. Ниже краткое описание поддерживаемых опций. [[yii\filters\AccessRule|Правила доступа]] поддерживают набор свойств. Ниже краткое описание поддерживаемых опций.
Вы также можете расширить [[yii\filters\AccessRule]], чтоб создать свой собственный класс правил доступа. Вы также можете расширить [[yii\filters\AccessRule]], чтоб создать свой собственный класс правил доступа.
* [[yii\filters\AccessRule::allow|allow]]: указывает, что это "allow" или "deny" правило. * [[yii\filters\AccessRule::allow|allow]]: задаёт какое это правило, "allow" или "deny".
* [[yii\filters\AccessRule::actions|actions]]: указывает какие действия соответствуют этому правилу. * [[yii\filters\AccessRule::actions|actions]]: задаёт действия соответствующие этому правилу.
Это должен быть массив идентификаторов действий. Сравнение регисрозависимо. Если данное свойство пустое или не задано, Значение должно быть массивом идентификаторов действий. Сравнение регисрозависимо. Если свойство пустое или не задано,
говорит что данное правило применяется ко всем действиям. то правило применяется ко всем действиям.
* [[yii\filters\AccessRule::controllers|controllers]]: задаёт контроллеры, которым соответствует данное правило. * [[yii\filters\AccessRule::controllers|controllers]]: задаёт контроллеры, которым соответствует правило.
Это должен быть массив с идентификаторами контроллеров. Сравнение регисрозависимо. Если данное свойство пустое или не задано, Значение должно быть массивом с идентификаторами контроллеров. Сравнение регисрозависимо. Если свойство
то данное правило применяется ко всем действиям. пустое или не задано, то правило применяется ко всем действиям.
* [[yii\filters\AccessRule::roles|roles]]: задаёт роли пользователей соответствующих данному правилу. * [[yii\filters\AccessRule::roles|roles]]: задаёт роли пользователей соответствующих этому правилу.
Распознаются две специальные роли, которые проверяются с помощью [[yii\web\User::isGuest]]: Распознаются две специальные роли, которые проверяются с помощью [[yii\web\User::isGuest]]:
- `?`: соответствует гостевому пользователю (не аутентифицирован) - `?`: соответствует гостевому пользователю (не аутентифицирован)
- `@`: соответствует аутентифицированному пользователю - `@`: соответствует аутентифицированному пользователю
Использование других имён ролей требует RBAC (будет описано дальше), можно будет использовать [[yii\web\User::can()]]. Использование других имён ролей будет приводить к вызову метода [[yii\web\User::can()]], который требует включения
Если данное свойство пустое или не задано, то данное правило применяется ко всем ролям. RBAC (будет описано дальше). Если свойство пустое или не задано, то правило применяется ко всем ролям.
* [[yii\filters\AccessRule::ips|ips]]: задаёт [[yii\web\Request::userIP|клиентские IP адреса]] для которых применяется это правило. * [[yii\filters\AccessRule::ips|ips]]: задаёт [[yii\web\Request::userIP|IP адреса пользователей]], для которых применяется
IP адрес может содержать `*` в конце, так чтоб он соответствовал IP адресу с таким же префиксом. это правило. IP адрес может содержать `*` в конце, так чтобы он соответствовал IP адресу с таким же префиксом.
Для примера, '192.168.*' соответствует всем IP адресам в сегменте '192.168.'. Если данное свойство пустое или не задано, Для примера, '192.168.*' соответствует всем IP адресам в сегменте '192.168.'. Если свойство пустое или не задано,
то данное правило применяется ко всем IP адресам. то правило применяется ко всем IP адресам.
* [[yii\filters\AccessRule::verbs|verbs]]: задаёт http метод (например `GET`, `POST`) соответствующий данному правилу. * [[yii\filters\AccessRule::verbs|verbs]]: задаёт http метод (например `GET`, `POST`) соответствующий правилу.
Сравнение регисронезависимо. Сравнение регисронезависимо.
* [[yii\filters\AccessRule::matchCallback|matchCallback]]: задаёт PHP колбек, который вызывается для определения, * [[yii\filters\AccessRule::matchCallback|matchCallback]]: задаёт PHP колбек, который вызывается для определения,
@ -112,7 +112,7 @@ IP адрес может содержать `*` в конце, так чтоб
* [[yii\filters\AccessRule::denyCallback|denyCallback]]: задаёт PHP колбек, который будет вызван если доступ будет * [[yii\filters\AccessRule::denyCallback|denyCallback]]: задаёт PHP колбек, который будет вызван если доступ будет
запрещён при вызове этого правила. запрещён при вызове этого правила.
Ниже покзан пример, который показывает использование опции `matchCallback`, которая позволяет писать произвольную Ниже покзан пример, показывающий использование опции `matchCallback`, которая позволяет писать произвольную
логику проверки доступа: логику проверки доступа:
```php ```php
@ -152,28 +152,28 @@ class SiteController extends Controller
--------------------------------------- ---------------------------------------
Управление доступом на основе ролей (RBAC) обеспечивает простой, но мощьный централизованный контроль доступа. Управление доступом на основе ролей (RBAC) обеспечивает простой, но мощьный централизованный контроль доступа.
Пожалуйста обратитесь к [Wikipedia](http://en.wikipedia.org/wiki/Role-based_access_control) для получения более Пожалуйста обратитесь к [Wikipedia](https://ru.wikipedia.org/wiki/%D0%A3%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%BE%D0%BC_%D0%BD%D0%B0_%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%B5_%D1%80%D0%BE%D0%BB%D0%B5%D0%B9)
подробного сравнения RBAC с другими более традиционными системами контроля доступа. для получения более подробного сравнения RBAC с другими, более традиционными, системами контроля доступа.
Yii реализует общую иерархическую RBAC, следуя [NIST RBAC model](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf). Yii реализует общую иерархическую RBAC, следуя [NIST RBAC model](http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf).
Обеспечивается функциональность RBAC через [[yii\rbac\ManagerInterface|authManager]] [компонент приложения](structure-application-components.md). Обеспечивается функциональность RBAC через [компонент приложения](structure-application-components.md) [[yii\rbac\ManagerInterface|authManager]].
Использование RBAC состоит из двух частей. Первая часть - это создание RBAC данных авторизации, и вторая часть это Использование RBAC состоит из двух частей. Первая часть - это создание RBAC данных авторизации, и вторая часть - это
использование данных авторизации для проверки доступа в том месте где это нужно. использование данных авторизации для проверки доступа в том месте, где это нужно.
Для облегчения последующего описания, мы сначала введём некоторые основные понятия RBAC. Для облегчения последующего описания, мы сначала введём некоторые основные понятия RBAC.
### Основные концепции ### Основные концепции
Роль представляет собой набор *permissions* (разрешения) (например создание сообщения, обновление сообщения). Роль представляет собой набор разрешений (*permissions*) (например создание сообщения, обновление сообщения).
Роль может быть назначена на одного или многих пользователей. Чтобы проверить, имеет ли пользователь указанные Роль может быть назначена на одного или многих пользователей. Чтобы проверить, имеет ли пользователь указанные
разрешения, мы можем проверить назначена ли пользователю роль, которая содержит данное разрешение. разрешения, мы должны проверить назначена ли пользователю роль, которая содержит данное разрешение.
С каждой ролью или разрешением может быть связано *rule* (правило). Правило представляет собой кусок кода, который будет С каждой ролью или разрешением может быть связано правило (*rule*). Правило представляет собой кусок кода, который будет
выполняться в ходе проверки доступа для определения может ли быть применена соответствующая роль или разрешение выполняться в ходе проверки доступа для определения может ли быть применена соответствующая роль или разрешение
к текущему пользователю. Например, разрешение "обновление поста" может иметь правило, которое проверяет является ли к текущему пользователю. Например, разрешение "обновление поста" может иметь правило, которое проверяет является ли
текущий пользовател автором поста. Во время проверки доступа, если пользователь не является автором поста, он/она будет текущий пользователь автором поста. Во время проверки доступа, если пользователь не является автором поста, он/она будет
считаться не имеющими разрешения "обновление поста". считаться не имеющими разрешения "обновление поста".
И роли и разрешения могут быть организованы в иерархию. В частности роль может содержать другие роли или разрешения; и И роли и разрешения могут быть организованы в иерархию. В частности роль может содержать другие роли или разрешения; и
@ -183,10 +183,11 @@ Yii реализует общую иерархическую RBAC, следуя
### Настройка RBAC Manager ### Настройка RBAC Manager
Перед определением авторизационных данных и проверкой прав доступа, мы должны настроить компонент приложения [[yii\base\Application::authManager|authManager]]. Перед определением авторизационных данных и проверкой прав доступа, мы должны настроить компонент приложения
Yii предоставляет два типа менеджеров авторизации: [[yii\rbac\PhpManager]] и [[yii\rbac\DbManager]]. Первый использует [[yii\base\Application::authManager|authManager]]. Yii предоставляет два типа менеджеров авторизации:
файл с PHP скриптом для хранения данных авторизации, второй сохраняет данные в базе данных. Вы можете использовать [[yii\rbac\PhpManager]] и [[yii\rbac\DbManager]]. Первый использует файл с PHP скриптом для хранения данных авторизации,
первый если ваше приложение не требует слишком динамичным управлением ролями и разрешениями. второй сохраняет данные в базе данных. Вы можете использовать первый если ваше приложение не требует слишком динамичного
управления ролями и разрешениями.
#### настройка authManager с помощью `PhpManager` #### настройка authManager с помощью `PhpManager`
@ -225,14 +226,14 @@ return [
]; ];
``` ```
`DbManager` использует четыре таблицы базы данных для хранения данных: `DbManager` использует четыре таблицы для хранения данных:
- [[yii\rbac\DbManager::$itemTable|itemTable]]: таблица для хранения авторизационных элементов. По умолчанию "auth_item". - [[yii\rbac\DbManager::$itemTable|itemTable]]: таблица для хранения авторизационных элементов. По умолчанию "auth_item".
- [[yii\rbac\DbManager::$itemChildTable|itemChildTable]]: таблица для хранения иерархии элементов. По умолчанию "auth_item_child". - [[yii\rbac\DbManager::$itemChildTable|itemChildTable]]: таблица для хранения иерархии элементов. По умолчанию "auth_item_child".
- [[yii\rbac\DbManager::$assignmentTable|assignmentTable]]: таблица для хранения назначений элементов авторизации. По умолчанию "auth_assignment". - [[yii\rbac\DbManager::$assignmentTable|assignmentTable]]: таблица для хранения назначений элементов авторизации. По умолчанию "auth_assignment".
- [[yii\rbac\DbManager::$ruleTable|ruleTable]]: таблица для хранения правил. По умолчанию "auth_rule". - [[yii\rbac\DbManager::$ruleTable|ruleTable]]: таблица для хранения правил. По умолчанию "auth_rule".
Прежде чем вы начнёте его использовать вам нужно создать эти таблицы в базе данных. Чтобы сделать это, Прежде чем вы начнёте использовать этот менеджер, вам нужно создать таблицы в базе данных. Чтобы сделать это,
вы можете использовать миграцию хранящуюся в файле `@yii/rbac/migrations`: вы можете использовать миграцию хранящуюся в файле `@yii/rbac/migrations`:
`yii migrate --migrationPath=@yii/rbac/migrations` `yii migrate --migrationPath=@yii/rbac/migrations`
@ -241,13 +242,13 @@ return [
### Создание данных авторизации ### Создание данных авторизации
Создание данных авторизации это следущие задачи: Для создания данных авторизации нужно выполнить следущие задачи:
- определение ролей и разрешений; - определение ролей и разрешений;
- установка отношений между ролями и правами доступа; - установка отношений между ролями и правами доступа;
- определение правил; - определение правил;
- связывание правил с ролями и разрешениями; - связывание правил с ролями и разрешениями;
- назначение ролей с пользователями. - назначение ролей пользователям.
В зависимости от требований к гибкости авторизации перечисленные задачи могут быть выполнены разными путями. В зависимости от требований к гибкости авторизации перечисленные задачи могут быть выполнены разными путями.
@ -305,7 +306,7 @@ class RbacController extends Controller
Автор может создавать пост, администратор может обновлять пост и делать всё, что может делать автор. Автор может создавать пост, администратор может обновлять пост и делать всё, что может делать автор.
Если ваше приложение позволяет регистрировать пользователей, то вам необходимо сразу назначать роли этим новым пользователям. Если ваше приложение позволяет регистрировать пользователей, то вам необходимо сразу назначать роли этим новым пользователям.
Например, для того, чтобы все вошедшие пользователи могли стать авторами в расширеном шаблоне проекта вы должны изменить Например, для того, чтобы все вошедшие пользователи могли стать авторами в расширеном шаблоне проекта, вы должны изменить
`frontend\models\SignupForm::signup()` как показано ниже: `frontend\models\SignupForm::signup()` как показано ниже:
```php ```php
@ -338,8 +339,8 @@ public function signup()
### Использование правил ### Использование правил
Как упомянуто выше, правила добавляют дополнительные ограничение на роли и разрешения. Правило это классы, расширяющие Как упомянуто выше, правила добавляют дополнительные ограничения на роли и разрешения. Правила это классы, расширяющие
[[yii\rbac\Rule]]. Он должен реализовывать метод [[yii\rbac\Rule::execute()|execute()]]. В иерархии созданой нами ранее [[yii\rbac\Rule]]. Они должны реализовывать метод [[yii\rbac\Rule::execute()|execute()]]. В иерархии, созданой нами ранее,
автор не можете редактировать свой пост. Давайте исправим это. Во-первых, мы должны создать правило проверяющее, автор не можете редактировать свой пост. Давайте исправим это. Во-первых, мы должны создать правило проверяющее,
что пользователь является автором поста: что пользователь является автором поста:
@ -397,7 +398,7 @@ $auth->addChild($author, $updateOwnPost);
### Проверка доступа ### Проверка доступа
С готовыми данными авторизациями проверка доступа это просто вызов метода [[yii\rbac\ManagerInterface::checkAccess()]]. С готовыми авторизационными данными, проверка доступа - это просто вызов метода [[yii\rbac\ManagerInterface::checkAccess()]].
Так как большинство проверок доступа относятся к текущему пользователю, для удобства Yii предоставляет сокращённый метод Так как большинство проверок доступа относятся к текущему пользователю, для удобства Yii предоставляет сокращённый метод
[[yii\web\User::can()]], который можно использовать как показано ниже: [[yii\web\User::can()]], который можно использовать как показано ниже:
@ -407,12 +408,12 @@ if (\Yii::$app->user->can('createPost')) {
} }
``` ```
Если текущий пользователь Jane с ID=1 мы начнём с `createPost` и попробуем добраться до `Jane`: Если текущий пользователь Jane с ID=1, мы начнём с `createPost` и попробуем добраться до `Jane`:
![Проверка доступа](images/rbac-access-check-1.png "Проверка доступа") ![Проверка доступа](images/rbac-access-check-1.png "Проверка доступа")
Для того чтоб проверить может ли пользователь обновить пост, нам надо передать дополнительный параметр Для того чтоб проверить может ли пользователь обновить пост, нам надо передать дополнительный параметр,
необходимый для правила `AuthorRule` описанного ранее: необходимый для правила `AuthorRule`, описанного ранее:
```php ```php
if (\Yii::$app->user->can('updatePost', ['post' => $post])) { if (\Yii::$app->user->can('updatePost', ['post' => $post])) {
@ -424,9 +425,9 @@ if (\Yii::$app->user->can('updatePost', ['post' => $post])) {
![Проверка доступа](images/rbac-access-check-2.png "Проверка доступа") ![Проверка доступа](images/rbac-access-check-2.png "Проверка доступа")
Мы начинаем с `updatePost` и переходим к `updateOwnPost`. Для того чтоб это произошло правило `AuthorRule` должен вернуть Мы начинаем с `updatePost` и переходим к `updateOwnPost`. Для того чтоб это произошло, правило `AuthorRule` должно вернуть
`true` при вызове метода `execute`. Метод получает `$params` переданный при вызове метода `can`, значение которого равно `true` при вызове метода `execute`. Метод получает `$params` переданный при вызове метода `can`, значение которого равно
`['post' => $post]`. Если всё правильно мы понимаем что `author` привязан к John. `['post' => $post]`. Если всё правильно мы увидим, что `author` привязан к John.
В случае Jane это немного проще, потому что она admin: В случае Jane это немного проще, потому что она admin:
@ -434,18 +435,18 @@ if (\Yii::$app->user->can('updatePost', ['post' => $post])) {
### Использование роли по умолчанию ### Использование роли по умолчанию
Роль по умолчанию это роль, которая *неявно* присваивается *всем* пользователям. Вызов метода Роль по умолчанию - это роль, которая *неявно* присваивается *всем* пользователям. Вызов метода
[[yii\rbac\ManagerInterface::assign()]] не требуется, и авторизационные данные не содержат информации о назначении. [[yii\rbac\ManagerInterface::assign()]] не требуется, и авторизационные данные не содержат информации о назначении.
Роль по умолчанию обычно связывают с правилом определяющим к какой роли принадлежит каждый пользователь. Роль по умолчанию обычно связывают с правилом определяющим к какой роли принадлежит каждый пользователь.
Роли по умолчанию обычно используются в приложениях, которые уже имеют какое-то назначение ролей. Для примера, приложение Роли по умолчанию обычно используются в приложениях, которые уже имеют какое-то описание ролей. Для примера, приложение
может иметь столбец "group" в таблице пользователей и каждый пользователь принадлежит к какой-то группе. Если каждая может иметь столбец "group" в таблице пользователей, и каждый пользователь принадлежит к какой-то группе. Если каждая
группа может быть сопоставлена роли в RBAC, вы можете использовать роль по умолчанию для автоматического назначения группа может быть сопоставлена роли в модели RBAC, вы можете использовать роль по умолчанию для автоматического назначения
каждому пользователю роли RBAC. Давайте используем пример, чтобы понять как это можно сделать. каждому пользователю роли RBAC. Давайте используем пример, чтобы понять как это можно сделать.
Предположим что в таблице пользователей у вам есть столбец `group`, в котором значение 1 представляет группу "администратор", Предположим что в таблице пользователей у вас есть столбец `group`, в котором значение 1 представляет группу "администратор",
а 2 - группу "автор". Вы планируете иметь 2 RBAC роли `admin` и `author` представляющими разрешения для двух а 2 - группу "автор". Вы планируете иметь две RBAC роли `admin` и `author`, представляющие разрешения для двух
соответствующих групп. Вы можете настроить данные роли как показано ниже. соответствующих групп. Вы можете настроить данные роли как показано ниже.
```php ```php
@ -493,7 +494,7 @@ $auth->addChild($admin, $author);
``` ```
Обратите внимание, так как "author" добавлен как дочерняя роль к "admin", следовательно в реализации метода `execute()` Обратите внимание, так как "author" добавлен как дочерняя роль к "admin", следовательно в реализации метода `execute()`
класса правила вы должны учитывать это иерархию. Именно по этому для роли "author" метод `execute()` вернёт истину класса правила вы должны учитывать эту иерархию. Именно по этому для роли "author" метод `execute()` вернёт истину,
если пользователь принадлежит к группам 1 или 2 (это означает, что пользователь находится в группе если пользователь принадлежит к группам 1 или 2 (это означает, что пользователь находится в группе
администраторов или авторов) администраторов или авторов)
@ -512,7 +513,7 @@ return [
]; ];
``` ```
Теперь если вы выполните проверку доступа, для обойх ролей `admin` и `author` будет выполнена проверка правила Теперь, если вы выполните проверку доступа, для обойх ролей `admin` и `author` будет выполнена проверка правила
асоциированного с ними. Если правило вернёт истину, это будет означать что роль применяется к текущему пользователю. асоциированного с ними. Если правило вернёт истину, это будет означать что роль применяется к текущему пользователю.
На основании правила, реализованного выше, если пользователь входит в группу 1 пользователю будет назначена роль `admin`; На основании правила, реализованного выше, если пользователь входит в группу 1 пользователю будет назначена роль `admin`;
и если значение `group` равно 2 будет применена роль `author`. и если значение `group` равно 2 будет применена роль `author`.

177
docs/guide-ru/security-best-practices.md

@ -0,0 +1,177 @@
Лучшие практики безопасности
============================
Ниже мы рассмотрим основные принципы безопасности и опишем, как избежать угроз при разработке на Yii.
Основные принципы
-----------------
Есть два основных принципа безопасности, независимо от того, какое приложение разрабатывается:
1. Фильтрация ввода.
2. Экранирование вывода.
### Фильтрация ввода
Фильтрация ввода означает, что входные данные никогда не должны считаться безопасными и вы всегда должны проверять,
являются ли полученные данные допустимыми. Например, если мы знаем, что сортировка может быть осуществлена только
по трём полям `title`, `created_at` и `status`, и поле может передаваться через ввод пользователем, лучше проверить
значение там, где мы его получили:
```php
$sortBy = $_GET['sort'];
if (!in_array($sortBy, ['title', 'created_at', 'status'])) {
throw new Exception('Invalid sort value.');
}
```
В Yii, вы, скорее всего, будете использовать [валидацию форм](input-validation.md), чтоб делать такие проверки.
### Экранирование вывода
Экранирование вывода означает, что данные в зависимости от контекста должны экранироваться, например в контексте
HTML вы должны экранировать `<`, `>` и похожие специальные символы. В контексте JavaScript или SQL будет другой набор
символов. Так как ручное экранирование черевато ошибками, Yii предоставляет различные утилиты для экранирования в
различных контекстах.
Как избежать SQL-иньекций
-------------------------
SQL-иньекции происходят, когда текст запроса формируется склеиванием неэкранированных строк, как показано ниже:
```php
$username = $_GET['username'];
$sql = "SELECT * FROM user WHERE username = '$username'";
```
Вместо того, чтобы подставлять корректное имя пользователя, злоумышленник может передать вам в приложение что-то вроде
`'; DROP TABLE user; --`.
В результате SQL будет следующий:
```sql
SELECT * FROM user WHERE username = ''; DROP TABLE user; --'
```
Это валидный запрос, который сначала будет искать пользователей с пустым именем, а затем удалит таблицу `user`.
Скорее всего будет сломано приложение и будут потеряны данные (вы ведь делаете регулярное резервное копирование?).
Большинство запросов к базе данных в Yii происходит через [Active Record](db-active-record.md), который правильно
использует подготовленные запросы PDO внутри. При использовании подготовленных запросов невозможно манипулировать
запросом как это показано выше.
Тем не менее, иногда нужны [сырые запросы](db-dao.md) или [построитель запросов](db-query-builder.md). В этом случае
вы должны использовать безопасные способы передачи данных. Если данные используются для сравнения со значением
столбцов предпочтительнее использовать подготовленные запросы:
```php
// query builder
$userIDs = (new Query())
->select('id')
->from('user')
->where('status=:status', [':status' => $status])
->all();
// DAO
$userIDs = $connection
->createCommand('SELECT id FROM user where status=:status')
->bindValues([':status' => $status])
->queryColumn();
```
Если данные используются в качестве имён столбцов или таблиц, то лучший путь - это разрешить только предопределённый
набор значений:
```php
function actionList($orderBy = null)
{
if (!in_array($orderBy, ['name', 'status'])) {
throw new BadRequestHttpException('Only name and status are allowed to order by.')
}
// ...
}
```
Если это невозможно, то имена столбцов и таблиц должны экранироваться. Yii использует специальный синтаксис
для экранирования для всех поддерживаемых баз данных:
```php
$sql = "SELECT COUNT([[$column]]) FROM {{table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();
```
Вы можете получить подробную информацию о синтаксисе в [Экранирование имён таблиц и столбцов](db-dao.md#quoting-table-and-column-names).
Как избежать XSS
----------------
XSS или крос-сайтинговый скриптинг становится возможен, когда не экранированный выходной HTML попадает в браузер.
Например, если пользователь должен ввести свой имя, но вместо `Alexander` он вводит `<script>alert('Hello!');</script>`, то
все страницы, которые его выводят без экранирования, будут выполнять JavaScript `alert('Hello!');`, и в результате
будет выводится окно сообщения в браузере. В зависимости от сайта, вместо невинных скриптов с выводом всплывающего
hello, злоумышленниками могут быть отправлены скрипты, похищающие личные данные пользователей сайта,
либо выполняющие операции от их имени.
В Yii избежать XSS легко. На месте вывода текста необходими выбрать один из двух вариантов:
1. Вы хотите вывести данные в виде обычного текста.
2. Вы хотите вывести данные в виде HTML.
Если вам нужно вывести простой текст, то экранировать лучше следующим образом:
```php
<?= \yii\helpers\Html::encode($username) ?>
```
Если нужно вывести HTML, вам лучше воспользоваться HtmlPurifier:
```php
<?= \yii\helpers\HtmlPurifier::process($description) ?>
```
Обратите внимание, что обработка с помощью HtmlPurifier довольно тяжела, так что неплохо бы задуматься о кешировании.
Как избежать CSRF
-----------------
CSRF - это аббревиатура для межсайтинговой подмены запросов. Идея заключается в том, что многие приложения предполагают,
что запросы, приходящие от браузера, отправляются самим пользователем. Это может быть неправдой.
Например, сайт `an.example.com` имеет URL `/logout`, который, используя простой GET, разлогинивает пользователя. Пока
это запрос выполняется самим пользователем - всё в порядке, но в один прекрасный день злоумышленники размещают код
`<img src="http://an.example.com/logout">` на форуме с большой посещаемостью. Браузер не делает никаких отличий
между запросом изображения и запросом страницы, так что когда пользователь откроет страницу с таким тегом `img`, браузер отправит GET запрос на указанный адрес, и пользователь будет разлогинен.
Вот основная идея. Можно сказать, что в разлогировании пользователя нет ничего серьёзного, но с помощью этой уязвимости, можно выполнять опасные операции. Представьте, что существует страница http://an.example.com/purse/transfer?to=anotherUser&amout=2000, обращение к которой с помощью GET запроса, приводит к перечислению 2000 единиц валюты со счета авторизированного пользователя на счет пользователя с логином anotherUser. Учитывая, что браузер для загрузки контента отправляет GET запросы, можно подумать, что разрешение на выполнение такой операции только POST запросом на 100% обезопасит от проблем. К сожалению. это не совсем правда. Учитывайте, что вместо тега <img>, злоумышленник может внедрить JavaScript код, который будет отправлять нужные POST запросы на этот URL.
Для того, чтоб избежать CSRF вы должны всегда:
1. Следуйте спецификациям HTTP, например запрос GET не должен менять состояние приложения.
2. Держите защиту CSRF в Yii включенной.
Как избежать нежелательного доступа к файлам
--------------------------------------------
По умолчанию, webroot сервера указывает на каталог `web`, где лежит `index.php`. В случае использования виртуального
хостинга, это может быть недостижимо, в конечном итоге весь код, конфиги и логи могут оказаться в webroot сервера.
Если это так, то нужно запретить доступ ко всему, кроме директории `web`. Если на вашем хостинге такое невозможно,
рассмотрите возможность смены хостинга.
Как избежать отладочной информации и утилит в продуктиве
--------------------------------------------------------
В режиме отладки, Yii отображает довольно подробные ошибки, которые полезны во время разработки. Дело в том, что
подробные ошибки удобны для нападающего, так как могут раскрыть структуру базы данных, параметров конфигурации и части
вашего кода. Никогда не запускайте продуктивное приложение с `YII_DEBUG` установленным в `true` в вашем `index.php`.
Вы никогда не должны включать Gii на продуктиве. Он может быть использован для получения информации о структуре
базы данных, кода и может позволить заменить файлы, генерируемые Gii автоматически.
Также следует избегать включения на продуктиве панели отладки, если только в этом нет острой необходимости.
Она раскрывает всё приложение и детали конфигурации. Если вам все таки нужно запустить панель отладки на продуктиве,
проверьте дважды что доступ ограничен только вашими IP-адресами.

152
docs/guide-ru/security-passwords.md

@ -0,0 +1,152 @@
Работа с паролями
=================
> Примечание: этот раздел находится на стадии разработки.
Хорошая безопасность является жизненно важной для жизни и успеха любого приложения.
К сожалению, многие разработчики предпочитают упрощять, когда речь заходит о безопасности,
либо из-за отсутствия понимания, либо потому, что считают реализацию слишком сложной.
Для того, чтобы сделанное вами на Yii приложение было как можно более безопасным, в Yii есть несколько удобных
и простых в использовании функций обеспечения безопасности.
Хеширование и проверка пароля
-----------------------------
Многие разработчики знают, что хранить пароль открытым текстом нельзя, но многие до сих пор считают безопасным
использование для хеширования паролей `md5` или `sha1`. Раньше упомянутых алгоритмов было достаточно, но современное
оборудование позволяет подобрать эти хеши очень быстро, методом простого перебора.
Для того, чтобы обеспечить повышенную безопасность паролей ваших пользователей даже в худшем случае (ваше
приложение взломано), нужно использовать алгоритм шифрования, устоичивый к атаке перебором. Лучший вариант в текущий
момент `bcrypt`. В PHP вы можете использовать хеши `bcrypt` через [функцию crypt](http://php.net/manual/en/function.crypt.php).
Yii обеспечивает две вспомогательные функции, которые упрощают использование функции `crypt` для генерации и проверки
пароля.
Когда пользователь задаёт пароль (например во время регистрации), пароль должен быть захеширован:
```php
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);
```
Хеш можно связать с соответствующим аттрибутом модели, так чтобы он сохранялся в базе для последующего использования.
Когда пользователь попытается войти, отправленый пароль должен быть хеширован и сравнён с ранее сохранённым хешем:
```php
if (Yii::$app->getSecurity()->validatePassword($password, $hash)) {
// всё хорошо, пользователь может войти
} else {
// неправильный пароль
}
```
Генерация псевдослучайных данных
--------------------------------
Псевдослучайные данные полезны во многих ситуациях. Например, для сброса пароля с помощью электронной почты
вам необходимо сгенерировать специальный токен, сохранить его в БД, и отправить по почте конечному пользователю,
который в свою очередь подтвердит им свою личность. Очень важно, чтобы этот маркер был уникальным и сложно
подделываемым и злоумышленник не мог предсказать токен и сбросить пароль пользователя.
Помощник безопасности Yii делает генерацию псевдослучайных данных простой:
```php
$key = Yii::$app->getSecurity()->generateRandomString();
```
Обратите внимание, что у вас должно быть установлено расширение `openssl` для генерации криптографически безопасных данных.
Шифрование и Расшифровка
------------------------
Yii предоставляет удобные вспомогательные функции, которые позволяют шифровать/дешифровать данные, используя секретный ключ.
Данные, переданные в функцию шифрования, могут быть расшифрованы только человеком, имеющим секретный ключ. Например, нам
нужно хранить некоторую информацию в базе данных, но мы должны быть уверены, что только пользователь, который имеет
секретный ключ, сможет посмотреть их (даже если база данных будет скомпрометирована):
```php
// $data и $secretKey передаются из формы
$encryptedData = Yii::$app->getSecurity()->encryptByPassword($data, $secretKey);
// сохраняем $encryptedData в базу данных
```
Позднее, когда пользователь захочет прочитать данные:
```php
// $secretKey получается из формы, $encryptedData получается из базы данных
$data = Yii::$app->getSecurity()->decryptByPassword($encryptedData, $secretKey);
```
Подтверждение целостности данных
--------------------------------
Есть ситуации, в которых вам нужно убедиться, что ваши данные не были подделаны третьей стороной, или как-то повреждены.
Yii обеспечивает простой способ подтверждения целостности данных в виде двух вспомогательных функций.
Префикс данных генерируются из секретного ключа и данных
```php
// $secretKey получается от приложения или от пользователя, $genuineData получаются из надёжного источника
$data = Yii::$app->getSecurity()->hashData($genuineData, $secretKey);
```
Проверка целостности данных
```php
// $secretKey получается от приложения или от пользователя, $data данные полученные из ненадёжного источника
$data = Yii::$app->getSecurity()->validateData($data, $secretKey);
```
todo: предотвращение XSS, CSRF, защита cookie, смотрите руководство 1.1
Вы также можете отключить проверку CSRF для контроллера и/или действия, через настройку его свойства:
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public $enableCsrfValidation = false;
public function actionIndex()
{
// CSRF валидация не будет проводится для этого и других действий
}
}
```
Чтобы отключить проверку CSRF в отдельном действии:
```php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function beforeAction($action)
{
// ...установите здесь `$this->enableCsrfValidation` в зависимости от каких-то условий...
// вызываем родительский метод для проверки CSRF если свойство установлено в `true`
return parent::beforeAction($action);
}
}
```
Безопасные Cookies
------------------
- валидация
- httpOnly по умолчанию
Смотрите также
--------------
- [Безопасность представлений](structure-views.md#security)

2
docs/guide/concept-properties.md

@ -73,4 +73,4 @@ There are several special rules for, and limitations on, the properties defined
* These properties do not support visibility. It makes no difference to the defining getter or setter method if the property is public, protected or private. * These properties do not support visibility. It makes no difference to the defining getter or setter method if the property is public, protected or private.
* The properties can only be defined by *non-static* getters and/or setters. Static methods will not be treated in the same manner. * The properties can only be defined by *non-static* getters and/or setters. Static methods will not be treated in the same manner.
Returning back to the problem described at the beginning of this guide, instead of calling `trim()` everywhere a `label` value is assigned, `trim()` now only needs to be invoked within the setter `setLabel()`. And if a new requirement makes it necesary that the label be initially capitalized, the `setLabel()` method can quickly be modified without touching any other code. The one change will universally affect every assignment to `label`. Returning back to the problem described at the beginning of this guide, instead of calling `trim()` everywhere a `label` value is assigned, `trim()` now only needs to be invoked within the setter `setLabel()`. And if a new requirement makes it necessary that the label be initially capitalized, the `setLabel()` method can quickly be modified without touching any other code. The one change will universally affect every assignment to `label`.

5
docs/guide/security-best-practices.md

@ -139,10 +139,9 @@ from a user browser are made by the user himself. It could be false.
For example, `an.example.com` website has `/logout` URL that, when accessed using a simple GET, logs user out. As long For example, `an.example.com` website has `/logout` URL that, when accessed using a simple GET, logs user out. As long
as it's requested by the user itself everything is OK but one day bad guys are somehow posting as it's requested by the user itself everything is OK but one day bad guys are somehow posting
`<img src="http://an.example.com/logout">` on a forum user visits frequently. Browser doesn't make any difference between `<img src="http://an.example.com/logout">` on a forum user visits frequently. Browser doesn't make any difference between
requesting an image or requesting a page so when user opens a page with such `img` tag he's being logged out from requesting an image or requesting a page so when user opens a page with such `img` tag, the browser will send the GET request to that URL, and the user will be logged out from `an.example.com`.
`an.example.com`.
That's the basic idea. One can say that logging user out is nothing serious. Well, sending POST isn't much trickier. That's the basic idea. One can say that logging user out is nothing serious, but bad guys can do much more, using this idea. Imagine that some website has an URL `http://an.example.com/purse/transfer?to=anotherUser&amout=2000`. Accessing it using GET request, causes transfer of $2000 from authorized user account to user `anotherUser`. We know, that browser will always send GET request to load an image, so we can modify code to accept only POST requests on that URL. Unfortunately, this will not save us, because an attacker can put some JavaScript code instead of `<img>` tag, which allows to send POST requests on that URL.
In order to avoid CSRF you should always: In order to avoid CSRF you should always:

10
docs/internals-ja/git-workflow.md

@ -55,14 +55,16 @@ phpunit をグローバルにインストールしていない場合は、代り
取り組んでいるグループのものだけにテストを限定することが出来ます。 取り組んでいるグループのものだけにテストを限定することが出来ます。
例えば、バリデータと redis のためのテストだけを走らせるためには、`phpunit --group=validators,redis` とします。 例えば、バリデータと redis のためのテストだけを走らせるためには、`phpunit --group=validators,redis` とします。
利用できるグループのリストを取得するためには、`phpunit --groups` を実行してください。 利用できるグループのリストを取得するためには、`phpunit --list-groups` を実行してください。
### エクステンション ### エクステンション
エクステンションに取り組むためには、エクステンションのレポジトリをクローンする必要があります。 エクステンションに取り組むためには、エクステンションのレポジトリをクローンする必要があります。
私たちは、あなたに代ってそれをするコマンドを作っています。 私たちは、あなたに代ってそれをするコマンドを作っています。
php build/build dev/ext <extension-name> ```
php build/build dev/ext <extension-name>
```
ここで `<extension-name>` がエクステンションの名前、例えば `redis` です。 ここで `<extension-name>` がエクステンションの名前、例えば `redis` です。
@ -148,7 +150,7 @@ git add path/to/my/file.php
github があなたのコミットを自動的にチケットとリンクするように、必ず `#XXX` でチケット番号に言及してください。 github があなたのコミットを自動的にチケットとリンクするように、必ず `#XXX` でチケット番号に言及してください。
``` ```
git commit -m "#42 を解決する変更の短い説明をここに入れる" git commit -m "#999 を解決する変更の短い説明をここに入れる"
``` ```
### 7. 最新の Yii コードを upstream からあなたのブランチにプルする ### 7. 最新の Yii コードを upstream からあなたのブランチにプルする
@ -226,7 +228,7 @@ git checkout -b 999-name-of-your-branch-goes-here
/* 魔法を使い、必要なら changelog を更新 */ /* 魔法を使い、必要なら changelog を更新 */
git add path/to/my/file.php git add path/to/my/file.php
git commit -m "A brief description of this change which fixes #42 goes here" git commit -m "A brief description of this change which fixes #999 goes here"
git pull upstream master git pull upstream master
git push -u origin 999-name-of-your-branch-goes-here git push -u origin 999-name-of-your-branch-goes-here
``` ```

3
docs/internals-pt-BR/translation-workflow.md

@ -92,6 +92,7 @@ Regras e Observações
- basic project template — template básico de projetos - basic project template — template básico de projetos
- behaviors — behaviors (comportamentos) - behaviors — behaviors (comportamentos)
- pretty URL — URL amigável (pretty URL) - pretty URL — URL amigável (pretty URL)
- class member variable - atributo da classe
### Termos Sem Tradução ### Termos Sem Tradução
@ -111,3 +112,5 @@ Regras e Observações
- web service - web service
- template - template
- query string - query string
- case-sensitive
- case-insensitive

15
docs/internals-ru/automation.md

@ -0,0 +1,15 @@
Автоматизация
=============
При работе над Yii, некоторые задачи, можно выполнять автоматически:
- Генерация карты классов в файл `classes.php`, который находится в корневой директории фреймворка.
Запустите `./build/build classmap` для его генерации.
- Генерация аннотаций `@property` в файлах классов, описывающих свойства введённые геттерами и сеттерами.
Запустите `./build/build php-doc/property` для их обновления.
- Исправление стиля кодирования и других мелких ошибок в коментариях phpdoc.
Запустите `./build/build php-doc/fix` для их исправления.
Проверьте изменения перед тем как их закомитить, так как могут быть нежелательные изменения, потому что команда не
является совершенной. Вы можете использовать `git add -p` для обзора изменеий.

233
docs/internals-ru/git-workflow.md

@ -0,0 +1,233 @@
Рабочий процесс Git для разработчиков Yii2
==========================================
Итак, вы хотите разрабатывать Yii? Хорошо! Но для того чтоб увеличить шанс принятия ваших изменений,
пожалуйста следуйте следующим шагам. Если вы новичок в git и github, вы можете сначала проверить
[github help](http://help.github.com/), [try git](https://try.github.com) или прочитать о
[внутренней модели данных git](http://nfarina.com/post/9868516270/git-is-simpler).
Подготовка вашего рабочего окружения
------------------------------------
Следующие шаги будут создавать рабочее окружение для Yii, которое вы можете использовать для работы над основным кодом
фреймворка. *Эти шаги будут нужны только в первый раз*.
### 1. [Форкаем](http://help.github.com/fork-a-repo/) репозиторий Yii на github и клонируйте ваш форк в ваше рабочее окружение.
```
git clone git@github.com:YOUR-GITHUB-USERNAME/yii2.git
```
Если у вас есть проблемы с настройкой GIT для работы с GitHub в Linux, или вы получаете ошибку похожую на "Permission Denied
(publickey)", тогда вы должны настроить ваш GIT по [этой инструкции](http://help.github.com/linux-set-up-git/)
### 2. Добавляем главный репозиторий Yii как дополнительный внешний git репозиторий назывемый "upstream"
Перейдите в каталог, куда вы склонировали Yii, как правило "yii2". Затем введите следующую команду:
```
git remote add upstream git://github.com/yiisoft/yii2.git
```
### 3. Настройка тестовой среды
Следующие шаги не обязательны, если вы хотите работать только с переводом или документацией.
- выполните `composer update` для установки зависимостей (если [composer у вас установлен глобально](https://getcomposer.org/doc/00-intro.md#globally)).
- выполните `php build/build dev/app basic` для клонирования базового приложения и установки его зависимостей.
Эта команда установит сторонние пакеты composer обычным образом, но создаст ссылку с репозитория yii2 на только
что загуженный репозиторий. Таким образом у вас будет только один экземпляр кода.
При необходимости делаем тоже самое для приложения advanced: `php build/build dev/app advanced`.
Данная команда также может быть использована для обновления зависимостей, внутри она использует `composer update`.
**Теперь у нас есть рабочая площадка для экспериментов с Yii 2.**
Следующие шаги не обязательны.
### Модульные тесты
Вы можете выполнить модульные тесты с помощью команды `phpunit` в корневой директории приложения. Если у вас phpunit
не установлен глобально, вы можете запустить `php vendor/bin/phpunit`.
Некоторые тесты требуют дополнительно установки и настройки баз данных. Вы можете создать `tests/data/config.local.php`
для переопределения настроек, которые определены в `tests/data/config.php`.
Вы можете ограничить тестирование группой тестов, с которой вы сейчас работаете, например запускать только тесты для
валидаторов и redis. Вы можете получить список доступных групп выполнив `phpunit --list-groups`.
### Расширения
Для работы над расширениями вы можете склонировать репозиторий расширения. Мы сделали команду, которая поможет вам
сделать это:
```
php build/build dev/ext <extension-name>
```
где `<extension-name>` это имя расширения, например `redis`.
Если вы хотите протестировать расширение в одном из шаблонов приложений, просто добавьте его в `composer.json`
приложения, например добавив `"yiisoft/yii2-redis": "*"` в секцию `require` базового приложения.
Запустите `php build/build dev/app basic` для установки расширения и его зависимостей и создания символической
ссылки на `extensions/redis` так чтоб вы работали не папке вендорных пакетов composer, а напрямую в репозитории yii2.
Работа над багами и новыми функциями
------------------------------------
Приготовив вашу среду разработки вы можете начать работу над исправлением багов и разработкой новых функций.
### 1. Убедитесь, что issue создана для того, над чем вы работаете, если потребуется много времени для исправления
Все новые функции и баги должны быть связаны с issue для того, чтоб иметь единое место для обсуждения и документирования.
Пртратьте несколько минут на поиск существующей issue, которая соответствует вашим изменениям. Если вы найдёте её в
списке, то пожалуста откоментируйте, что вы начали над ней работать. Если вы не нашли нужной issue пожалуйста
[создайте новую issue](report-an-issue.md) или создайте сразу запрос на изменения если это простые изменения.
Это позволит команде проверить ваше предложение, и обеспечивать соответствующую обратную связь.
> Для небольших изменении или документации, или простых исправлений, вам нет необходимости создавать issue,
запрос на изменения в этом случае подходит лучше.
### 2. Вытягивание последнего кода из основного репозитория Yii
```
git fetch upstream
```
Вы должны начинать с этого действия работу над каждым новым предложением, убеждайтесь что вы работаете над самой
последней версией кода.
### 3. Создание новой ветки для ваших изменений, основанных на текущем мастере Yii
> Это очень важно, так как вы не сможете отправлять более одного запроса на изменения из вашего репозитория, если
будете использовать ветку master.
Каждая отдельное исправление или изменение должно разрабатываться в своей ветке. Имя ветки должно быть описательным
и начинаться с номера issue, с которым связан ваш код. Если вы не исправляете какой-то конкретный issue, просто
пропустите номер.
Например:
```
git checkout upstream/master
git checkout -b 999-name-of-your-branch-goes-here
```
### 4. Делайте свою магию, пишите ваш код
Убедитесь, что он работает :)
Модульные тесты всегда приветствуются. Протестированный и с хорошим покрытием код значительно упрощает задачу проверки
вашего предложения. Сломанные модульные тесты, как описание проблемы, тоже приветствуются.
### 5. Обновите CHANGELOG
Отредактируйте файл CHANGELOG, включив ваши изменения. Для этого нужно вставить строки в начало файла под заголовком
"Work in progress", строки с описанием изменений должны выглядеть похожими на следующие:
```
Bug #999: a description of the bug fix (Your Name)
Enh #999: a description of the enhancement (Your Name)
```
`#999` это номер issue описывающей `Bug` или `Enh`.
Лог изменений должен быть сгруппирован по типу (`Bug`,`Enh`) и отсортирован по номеру issue.
Для очень маленьких исправлений, например опечаток и изменений документации, нет необходимости обновлять CHANGELOG.
### 6. Фиксация ваших изменений
Добавляем файлы/изменения которые вы хотите зафиксировать в [staging area](http://gitref.org/basic/#add)
```
git add path/to/my/file.php
```
Вы можете использовать опцию `-p` для того, чтоб выбрать, какие изменения вы хотите добавить в коммит.
Фиксируйте ваши изменения с описательным сообщением. Убедитесь что в сообщение есть номер `#XXX`, так github
автоматически свяжет ваш коммит с тикетом:
```
git commit -m "A brief description of this change which fixes #999 goes here"
```
### 7. Получение последнего кода из апстрима Yii в вашу ветку
```
git pull upstream master
```
Это гарантирует, что вы используете самый последний код в вашей ветке перед отправкой запроса на изменения. Если есть
какие-либо конфликты слияния, вы должны исправить их и зафиксировать изменения ещё раз. Это гарантирует, что команда Yii
сможет слить ваши изменения одним кликом.
### 8. Разрешив зависимости, оптравляем код на github
```
git push -u origin 999-name-of-your-branch-goes-here
```
Опция `-u` сохранит указание на ветку в github, чтобы при следующем выполнении `git push`, git знал, куда отправлять
изменения. Это полезно, если вы хотите позже отправлять ещё комиты в этот запрос на слияние.
### 9. Открываем [запрос на слияние](http://help.github.com/send-pull-requests/) в *upstream*.
Перейдите в репозиторий на github и нажмите "Pull Request", выберите ветку справа и введите больше информации
в поле комментариев. Чтобы связать запрос на изменение с issue, добавьте в комментарий `#999` - где 999 это номер issue.
> Обратите внимание, что каждый запрос на слияние должен исправлять единственное изменение. Для множества независимых
изменений, пожалуйста откройте несколько запросов на слияние.
### 10. Проверка вашего кода кем-то
Кто-то будет проверять ваш код, и, возможно, вам будет предложено внести некоторые изменения, если это так, то перейдите
к шагу #6 (вам не надо открывать новый запрос на слияние, если текущий ещё открыт). Если код будет принят, он будет
влит в основную ветку и станет частью следующего релиза Yii. Если нет, не унывайте, разным людям необходимы различные
функции и Yii не может реализовывать всё для всех, ваш код будет ещё доступен на github как ссылка для людей кому он
может пригодится.
### 11. Очистка
После того, как код был принят или отклонён, вы можете удалить ветки, над которыми вы работали в локальном репозитории
и в `origin`.
```
git checkout master
git branch -D 999-name-of-your-branch-goes-here
git push origin --delete 999-name-of-your-branch-goes-here
```
### Примечание:
Для обнаружения регрессии как можно раньше, каждое слияние кодовой базы Yii на github будет подхвачено
[Travis CI](http://travis-ci.org) для автоматического запуска тестов. Люди из *core team* не хотят нагружать
этот сервис, поэтому добавляют текст [`[ci skip]`](http://about.travis-ci.org/docs/user/how-to-skip-a-build/) в описание
запроса на слияние, в следующих ситуациях:
* затронуты только javascript, css файлы или файлы изображений,
* обновление документации,
* изменения затрагивают только строки (например обновление переводов).
Это защитит travis от запуска тестов на изменениях, которые не покрыты тестами.
### Обзор команд (для продвинутых участников)
```
git clone git@github.com:YOUR-GITHUB-USERNAME/yii2.git
git remote add upstream git://github.com/yiisoft/yii2.git
```
```
git fetch upstream
git checkout upstream/master
git checkout -b 999-name-of-your-branch-goes-here
/* ваша магия, обновление changelog если нужно */
git add path/to/my/file.php
git commit -m "A brief description of this change which fixes #999 goes here"
git pull upstream master
git push -u origin 999-name-of-your-branch-goes-here
```

53
docs/internals-ru/view-code-style.md

@ -0,0 +1,53 @@
Стиль кодирования представлений Yii2
====================================
Данный стиль кодирования используется для представлений в ядре Yii 2.x и оффициальных представлениях. Мы не заставляем
вас использовать данный стиль кодирования для ваших приложений. Не стесняйтесь использовать тот стиль, который вам
больше подходит.
```php
<?php
// Открывающий PHP тег должен быть в каждом файле шаблона. Пустая строка после открывающего тега также необходима.
// Описывайте входные переменные, переданные сюда контроллером.
/* @var $this yii\base\View */
/* @var $form yii\widgets\ActiveForm */
/* @var $posts app\models\Post[] */
/* @var $contactMessage app\models\ContactMessage */
// Пустая строка ниже необходима.
// Описание классов с пространствами имён.
use yii\helpers\Html;
use yii\widgets\ActiveForm;
// Пустая строка ниже необходима.
// Установка свойств контекста, вызов сеттеров и другие действия.
$this->title = 'Posts';
?>
<!-- Отдельные блоки PHP являются предпочтительными для foreach, for, if и т.д. -->
<?php foreach ($posts as $post): ?>
<!-- Заметьте здесь есть отступ. -->
<h2><?= Html::encode($post['title']) ?></h2>
<p><?= Html::encode($post['shortDescription']) ?></p>
<!-- `endforeach;`, `endfor;`, `endif;`, и другие должны ипользоваться вместо `}` в случае использования множественных PHP блоков -->
<?php endforeach; ?>
<!-- Описание виджета может быть, а может и не быть, разбито на разных строках. -->
<?php $form = ActiveForm::begin([
'options' => ['id' => 'contact-message-form'],
'fieldConfig' => ['inputOptions' => ['class' => 'common-input']],
]); ?>
<!-- Заметьте здесь есть отступ. -->
<?= $form->field($contactMessage, 'name')->textInput() ?>
<?= $form->field($contactMessage, 'email')->textInput() ?>
<?= $form->field($contactMessage, 'subject')->textInput() ?>
<?= $form->field($contactMessage, 'body')->textArea(['rows' => 6]) ?>
<div class="form-actions">
<?= Html::submitButton('Submit', ['class' => 'common-button']) ?>
</div>
<!-- Завершающий вызов виджета должен быть в индивидуальном PHP теге. -->
<?php ActiveForm::end(); ?>
<!-- Завершающий символ переноса строки обязателен. -->
```

34
docs/internals/git-workflow.md

@ -2,9 +2,9 @@ Git workflow for Yii 2 contributors
=================================== ===================================
So you want to contribute to Yii? Great! But to increase the chances of your changes being accepted quickly, please So you want to contribute to Yii? Great! But to increase the chances of your changes being accepted quickly, please
follow the following steps. If you are new to git follow the following steps. If you are new to Git
and github, you might want to first check out [github help](http://help.github.com/), [try git](https://try.github.com) and GitHub, you might want to first check out [GitHub help](http://help.github.com/), [try Git](https://try.github.com)
or learn something about [git internal data model](http://nfarina.com/post/9868516270/git-is-simpler). or learn something about [Git internal data model](http://nfarina.com/post/9868516270/git-is-simpler).
Prepare your development environment Prepare your development environment
------------------------------------ ------------------------------------
@ -12,14 +12,14 @@ Prepare your development environment
The following steps will create a development environment for Yii, which you can use to work The following steps will create a development environment for Yii, which you can use to work
on the core code of Yii framework. These steps only need to be done the first time you contribute. on the core code of Yii framework. These steps only need to be done the first time you contribute.
### 1. [Fork](http://help.github.com/fork-a-repo/) the Yii repository on github and clone your fork to your development environment ### 1. [Fork](http://help.github.com/fork-a-repo/) the Yii repository on GitHub and clone your fork to your development environment
``` ```
git clone git@github.com:YOUR-GITHUB-USERNAME/yii2.git git clone git@github.com:YOUR-GITHUB-USERNAME/yii2.git
``` ```
If you have trouble setting up GIT with GitHub in Linux, or are getting errors like "Permission Denied (publickey)", If you have trouble setting up Git with GitHub in Linux, or are getting errors like "Permission Denied (publickey)",
then you must [setup your GIT installation to work with GitHub](http://help.github.com/linux-set-up-git/) then you must [setup your Git installation to work with GitHub](http://help.github.com/linux-set-up-git/)
### 2. Add the main Yii repository as an additional git remote called "upstream" ### 2. Add the main Yii repository as an additional git remote called "upstream"
@ -55,13 +55,15 @@ Some tests require additional databases to be set up and configured. You can cre
settings that are configured in `tests/data/config.php`. settings that are configured in `tests/data/config.php`.
You may limit the tests to a group of tests you are working on e.g. to run only tests for the validators and redis You may limit the tests to a group of tests you are working on e.g. to run only tests for the validators and redis
`phpunit --group=validators,redis`. You get the list of available groups by running `phpunit --groups`. `phpunit --group=validators,redis`. You get the list of available groups by running `phpunit --list-groups`.
### Extensions ### Extensions
To work on extensions you have to clone the extension repository. We have created a command that can do this for you: To work on extensions you have to clone the extension repository. We have created a command that can do this for you:
php build/build dev/ext <extension-name> ```
php build/build dev/ext <extension-name>
```
where `<extension-name>` is the name of the extension, e.g. `redis`. where `<extension-name>` is the name of the extension, e.g. `redis`.
@ -141,11 +143,11 @@ git add path/to/my/file.php
You can use the `-p` option to select the changes you want to have in your commit. You can use the `-p` option to select the changes you want to have in your commit.
Commit your changes with a descriptive commit message. Make sure to mention the ticket number with `#XXX` so github will Commit your changes with a descriptive commit message. Make sure to mention the ticket number with `#XXX` so GitHub will
automatically link your commit with the ticket: automatically link your commit with the ticket:
``` ```
git commit -m "A brief description of this change which fixes #42 goes here" git commit -m "A brief description of this change which fixes #999 goes here"
``` ```
### 7. Pull the latest Yii code from upstream into your branch ### 7. Pull the latest Yii code from upstream into your branch
@ -158,19 +160,19 @@ This ensures you have the latest code in your branch before you open your pull r
you should fix them now and commit the changes again. This ensures that it's easy for the Yii team to merge your changes you should fix them now and commit the changes again. This ensures that it's easy for the Yii team to merge your changes
with one click. with one click.
### 8. Having resolved any conflicts, push your code to github ### 8. Having resolved any conflicts, push your code to GitHub
``` ```
git push -u origin 999-name-of-your-branch-goes-here git push -u origin 999-name-of-your-branch-goes-here
``` ```
The `-u` parameter ensures that your branch will now automatically push and pull from the github branch. That means The `-u` parameter ensures that your branch will now automatically push and pull from the GitHub branch. That means
if you type `git push` the next time it will know where to push to. This is useful if you want to later add more commits if you type `git push` the next time it will know where to push to. This is useful if you want to later add more commits
to the pull request. to the pull request.
### 9. Open a [pull request](http://help.github.com/send-pull-requests/) against upstream. ### 9. Open a [pull request](http://help.github.com/send-pull-requests/) against upstream.
Go to your repository on github and click "Pull Request", choose your branch on the right and enter some more details Go to your repository on GitHub and click "Pull Request", choose your branch on the right and enter some more details
in the comment box. To link the pull request to the issue put anywhere in the pull comment `#999` where 999 is the in the comment box. To link the pull request to the issue put anywhere in the pull comment `#999` where 999 is the
issue number. issue number.
@ -181,7 +183,7 @@ issue number.
Someone will review your code, and you might be asked to make some changes, if so go to step #6 (you don't need to open Someone will review your code, and you might be asked to make some changes, if so go to step #6 (you don't need to open
another pull request if your current one is still open). If your code is accepted it will be merged into the main branch another pull request if your current one is still open). If your code is accepted it will be merged into the main branch
and become part of the next Yii release. If not, don't be disheartened, different people need different features and Yii and become part of the next Yii release. If not, don't be disheartened, different people need different features and Yii
can't be everything to everyone, your code will still be available on github as a reference for people who need it. can't be everything to everyone, your code will still be available on GitHub as a reference for people who need it.
### 11. Cleaning it up ### 11. Cleaning it up
@ -196,7 +198,7 @@ git push origin --delete 999-name-of-your-branch-goes-here
### Note: ### Note:
To detect regressions early every merge to the Yii codebase on github will be picked up by To detect regressions early every merge to the Yii codebase on GitHub will be picked up by
[Travis CI](http://travis-ci.org) for an automated testrun. As core team doesn't wish to overtax this service, [Travis CI](http://travis-ci.org) for an automated testrun. As core team doesn't wish to overtax this service,
[`[ci skip]`](http://about.travis-ci.org/docs/user/how-to-skip-a-build/) will be included to the merge description if [`[ci skip]`](http://about.travis-ci.org/docs/user/how-to-skip-a-build/) will be included to the merge description if
the pull request: the pull request:
@ -222,7 +224,7 @@ git checkout -b 999-name-of-your-branch-goes-here
/* do your magic, update changelog if needed */ /* do your magic, update changelog if needed */
git add path/to/my/file.php git add path/to/my/file.php
git commit -m "A brief description of this change which fixes #42 goes here" git commit -m "A brief description of this change which fixes #999 goes here"
git pull upstream master git pull upstream master
git push -u origin 999-name-of-your-branch-goes-here git push -u origin 999-name-of-your-branch-goes-here
``` ```

Loading…
Cancel
Save