Skip to content

Commit ee200f6

Browse files
committed
Added documentation for v6 of admin
Signed-off-by: nati <nati@dotkernel.com>
1 parent fd87b12 commit ee200f6

17 files changed

Lines changed: 769 additions & 0 deletions
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Authorization Guards
2+
3+
The packages responsible for restricting access to certain parts of the application are [dot-rbac-guard](https://github.com/dotkernel/dot-rbac-guard) and [dot-rbac](https://github.com/dotkernel/dot-rbac).
4+
These packages work together to create an infrastructure that is customizable and diversified to manage user access to the platform by specifying the type of role the user has.
5+
6+
The `authorization.global.php` file provides multiple configurations specifying multiple roles as well as the types of permissions to which these roles have access.
7+
8+
```php
9+
//example of a flat RBAC model that specifies two types of roles as well as their permission
10+
'roles' => [
11+
'admin' => [
12+
'permissions' => [
13+
'authenticated',
14+
'edit',
15+
'delete',
16+
//etc..
17+
]
18+
],
19+
'user' => [
20+
'permissions' => [
21+
'authenticated',
22+
//etc..
23+
]
24+
]
25+
]
26+
```
27+
28+
The `authorization-guards.global.php` file defines which permissions are required to access specific route handlers. These permissions must first be declared in the authorization.global.php (dot-rbac) configuration file.
29+
30+
```php
31+
// Example configuration granting access to route handlers based on permissions.
32+
'rules' => [
33+
'admin::admin-login-form' => [],
34+
'admin::admin-login' => [],
35+
'admin::admin-create-form' => ['authenticated'],
36+
'admin::admin-create' => ['authenticated'],
37+
'admin::admin-delete-form' => ['authenticated'],
38+
'admin::admin-delete' => ['authenticated'],
39+
'admin::admin-edit-form' => ['authenticated'],
40+
'admin::admin-edit' => ['authenticated'],
41+
]
42+
```
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Fixtures
2+
3+
> Fixtures are used to seed the database with initial values and should only be executed ONCE each, after migrating the database.
4+
5+
Seeding the database is done with the help of our custom package `dotkernel/dot-data-fixtures` built on top of `doctrine/data-fixtures`.
6+
See below on how to use our CLI command for listing and executing Doctrine data fixtures.
7+
8+
## Working with fixtures
9+
10+
You can find an example of a fixtures class in `src/Core/src/App/src/Fixture/AdminLoader.php`.
11+
12+
To list all the available fixtures by order of execution run:
13+
14+
```shell
15+
php bin/doctrine fixtures:list
16+
```
17+
18+
To execute all fixtures run:
19+
20+
```shell
21+
php bin/doctrine fixtures:execute
22+
```
23+
24+
To execute a specific fixture, use its class name, like in this example:
25+
26+
```shell
27+
php bin/doctrine fixtures:execute --class=AdminLoader
28+
```
29+
30+
Fixtures can and should be ordered to ensure database consistency.
31+
More on ordering fixtures can be found here :
32+
https://www.doctrine-project.org/projects/doctrine-data-fixtures/en/latest/how-to/fixture-ordering.html#fixture-ordering
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Creating migrations
2+
3+
Migrations are used to create and/or edit the database structure.
4+
To generate a new migration file, use this command:
5+
6+
```shell
7+
php vendor/bin/doctrine-migrations migrations:generate
8+
```
9+
10+
It creates a PHP file like this one `src/Core/src/App/src/Migration/Version20240627134952.php` that can then be edited in the IDE.
11+
You can add new queries in:
12+
13+
- `public function up` - these are executed when the migration is run.
14+
- `public function down` - these are optional queries that undo the above changes.
15+
16+
## Example
17+
18+
This example creates a new column named `test`.
19+
Add this in `public function up`:
20+
21+
```shell
22+
$this->addSql('ALTER TABLE admin ADD test VARCHAR(255) NOT NULL');
23+
```
24+
25+
And its opposite in `public function down`:
26+
27+
```shell
28+
$this->addSql('ALTER TABLE admin DROP test');
29+
```

docs/book/v6/how-to/csrf.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# CSRF protection in forms
2+
3+
A Cross-Site Request Forgery (CSRF) attack is a type of security vulnerability that tricks a user into performing
4+
actions on a web application in which they are authenticated, without their knowledge or consent.
5+
6+
Web applications can protect users against these types of attacks by implementing CSRF tokens in their forms which are
7+
known only to the application that generated them and must be included when submitting forms. With each visit, a new
8+
CSRF token is added to the form so tokens are not reusable between forms. Missing to provide a valid CSRF token will
9+
result in a form validation error.
10+
11+
## Implement CSRF protection
12+
13+
Implementing CSRF protection requires three steps:
14+
15+
- create new field using [laminas/laminas-form](https://github.com/laminas/laminas-form)'s [CSRF](https://github.com/laminas/laminas-form/blob/3.21.x/src/Element/Csrf.php) element
16+
- validate new field using [laminas/laminas-session](https://github.com/laminas/laminas-session)'s
17+
[CSRF](https://github.com/laminas/laminas-session/blob/2.22.x/src/Validator/Csrf.php) validator
18+
- render field using [laminas/laminas-form](https://github.com/laminas/laminas-form)'s [FormElement](https://github.com/laminas/laminas-form/blob/3.21.x/src/View/Helper/FormElement.php) helper
19+
20+
### Create field
21+
22+
Open the form's PHP class and append the following code to the method that initializes the fields (usually `init`):
23+
24+
```php
25+
$this->add(
26+
(new Csrf('exampleCsrf'))
27+
->setOptions([
28+
'csrf_options' => ['timeout' => 3600, 'session' => new Container()],
29+
])
30+
->setAttribute('required', true)
31+
);
32+
```
33+
34+
where `exampleCsrf` should be a suggestive name that describes the purpose of the field (example: `forgotPasswordCsrf`).
35+
36+
### Validate field
37+
38+
Open the InputFilter that validates the form fields and append the following code to the method that initializes the
39+
fields (usually `init`):
40+
41+
```php
42+
$this->add(new CsrfInput('exampleCsrf'));
43+
```
44+
45+
where `exampleCsrf` must match the CSRF field's name in the form.
46+
47+
> Don't forget to modify both occurrences in this file.
48+
49+
> Make sure that you validate the form using its `isValid` method in the handler/controller where it is submitted.
50+
51+
### Render field
52+
53+
Open the template that renders your form and add the following code somewhere between the form's opening and closing
54+
tags:
55+
56+
```text
57+
{{ formElement(form.get('exampleCsrf')) }}
58+
```
59+
60+
## Test the implementation
61+
62+
Access your form from the browser and view its source. You should see a new hidden field, called `exampleCsrf` (or
63+
however you named it). After filling out the form, submitting it should work as before.
64+
65+
In order to make sure that the new CSRF field works as expected, you can inspect the form using your browser's
66+
`Developer tools` and modify its value in any way. Submitting a filled out form should result in a validation error:
67+
68+
> This field is required and cannot be empty.
69+
70+
71+
### Timeout
72+
73+
Note the `timeout` option in your PHP form's `exampleCsrf` field, with its default value set to **3600**. This
74+
represents the value in seconds for how long the token is valid. Submitting a form that has been rendered for longer
75+
than this value will result in a validation error:
76+
77+
> Invalid CSRF.
78+
79+
You can modify the value of `timeout` in each form, but the default value should work in most cases.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Dependency Injection
2+
3+
Dependency injection is a design pattern used in software development to implement inversion of control.
4+
In simpler terms, it's the act of providing dependencies for an object during instantiation.
5+
6+
In PHP, dependency injection can be implemented in various ways, including through constructor injection, setter injection and property injection.
7+
8+
Dotkernel Admin, through its [dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package focuses only on constructor injection.
9+
10+
## Usage
11+
12+
**Dotkernel Admin** comes out of the box with the [dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package, which provides all the functionality injecting dependencies into any object you want.
13+
14+
`dot-dependency-injection` determines the dependencies by looking at the `#[Inject]` attribute, added to the constructor of a class.
15+
Each dependency is specified as a separate parameter of the `#[Inject]` attribute.
16+
17+
For our example we will inject `RouterInterface` and `AuthenticationServiceInterface` dependencies into `GetAccountLogoutHandler`.
18+
19+
```php
20+
use Dot\DependencyInjection\Attribute\Inject;
21+
22+
class GetAccountLogoutHandler implements RequestHandlerInterface
23+
{
24+
#[Inject(
25+
RouterInterface::class,
26+
AuthenticationServiceInterface::class,
27+
)]
28+
public function __construct(
29+
protected RouterInterface $router,
30+
protected AuthenticationServiceInterface $authenticationService,
31+
) {
32+
}
33+
}
34+
```
35+
36+
> If your class needs the value of a specific configuration key, you can specify the path using dot notation: `config.example`
37+
38+
The next step is to register the class in the `ConfigProvider` under `factories` using
39+
`Dot\DependencyInjection\Factory\AttributedServiceFactory::class`.
40+
41+
```php
42+
public function getDependencies(): array
43+
{
44+
return [
45+
'factories' => [
46+
GetAccountLogoutHandler::class => AttributedServiceFactory::class,
47+
]
48+
];
49+
}
50+
```
51+
52+
That's it.
53+
When your object is instantiated from the container, it will automatically have its dependencies resolved.
54+
55+
> Dependencies injection is available to any object within Dotkernel Admin.
56+
> For example, you can inject dependencies in a service, a handler and so on, simply by registering them in the `ConfigProvider`.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# NPM Commands
2+
3+
To install dependencies into the `node_modules` directory run this command.
4+
5+
```shell
6+
npm install
7+
```
8+
9+
> If `npm install` fails, this could be caused by user permissions of npm.
10+
> The recommended way to install npm is through `Node Version Manager`.
11+
12+
The watch command compiles the components then monitors the files for changes and recompiles them.
13+
14+
```shell
15+
npm run watch
16+
```
17+
18+
After all updates are done, this command compiles the assets locally, minifies them and makes them ready for production.
19+
20+
```shell
21+
npm run prod
22+
```
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Composer Installation of Packages
2+
3+
Composer is required to install Dotkernel Admin. You can install Composer from the [official site](https://getcomposer.org/).
4+
5+
> First make sure that you have navigated your command prompt to the folder where you copied the files in the previous step.
6+
7+
## Install dependencies
8+
9+
Run this command in the command prompt.
10+
11+
> Use the **CLI** in order to ensure interactivity for proper configuration.
12+
13+
```shell
14+
composer install
15+
```
16+
17+
You should see this text below, along with a long list of packages to be installed instead of the `[...]`.
18+
In this example there are 171 packages, though the number can change in future updates.
19+
You will find the packages in the `vendor` folder.
20+
21+
```shell
22+
No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
23+
Loading composer repositories with package information
24+
Updating dependencies
25+
Lock file operations: 171 installs, 0 updates, 0 removals
26+
[...]
27+
Writing lock file
28+
Installing dependencies from lock file (including require-dev)
29+
Package operations: 171 installs, 0 updates, 0 removals
30+
[...]
31+
```
32+
33+
The setup script prompts for some configuration settings, for example the lines below:
34+
35+
```shell
36+
Please select which config file you wish to inject 'Laminas\Validator\ConfigProvider' into:
37+
[0] Do not inject
38+
[1] config/config.php
39+
Make your selection (default is 1):
40+
```
41+
42+
Type `0` to select `[0] Do not inject`.
43+
44+
> We choose `0` because Dotkernel includes its own ConfigProvider which already contains the prompted configurations.
45+
> If you choose `[1] config/config.php`, an extra `ConfigProvider` will be injected.
46+
47+
The next question is:
48+
49+
`Remember this option for other packages of the same type? (y/N)`
50+
51+
Type `y` here, and hit `enter` to complete this stage.
52+
53+
## Development mode
54+
55+
If you're installing the project for development, make sure you have development mode enabled, by running:
56+
57+
```shell
58+
composer development-enable
59+
```
60+
61+
You can disable development mode by running:
62+
63+
```shell
64+
composer development-disable
65+
```
66+
67+
You can check if you have development mode enabled by running:
68+
69+
```shell
70+
composer development-status
71+
```
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Configuration Files
2+
3+
## Mail
4+
5+
> If you intend to send emails from your Frontend, make sure to fill in SMTP connection params.
6+
> This will be covered in the next section.
7+
8+
> **optional**: in order to run/create tests, duplicate `config/autoload/local.test.php.dist` as `config/autoload/local.test.php`
9+
> this creates a new in-memory database that your tests will run on.
10+
>
11+
If you want your application to send mail, add valid credentials to the following keys in `config/autoload/mail.global.php`
12+
13+
Under `message_options` key:
14+
15+
- `from` - email address that will send emails (required)
16+
- `from_name` - organization name for signing sent emails (optional)
17+
18+
Under `smtp_options` key:
19+
20+
- `host` - hostname or IP address of the mail server (required)
21+
- `connection_config` - add the `username` and `password` keys (required)
22+
23+
In `config/autoload/local.php` edit the key `contact` => `message_receivers` => `to` with *string* values for emails that should receive contact messages.
24+
25+
> **Please add at least 1 email address in order for contact message to reach someone**
26+
27+
Also feel free to add as many CCs as you require under the `contact` => `message_receivers` => `cc` key.

0 commit comments

Comments
 (0)