Skip to content

Commit a593ff3

Browse files
authored
Merge pull request #15 from PopNatanael/main
Added documentation for admin v6
2 parents fd87b12 + c2e81f9 commit a593ff3

18 files changed

+799
-1
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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). 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.
4+
5+
The `authorization.global.php` file provides multiple configurations specifying multiple roles as well as the types of permissions to which these roles have access.
6+
7+
```php
8+
//example of a flat RBAC model that specifies two types of roles as well as their permission
9+
'roles' => [
10+
'admin' => [
11+
'permissions' => [
12+
'authenticated',
13+
'edit',
14+
'delete',
15+
//etc..
16+
]
17+
],
18+
'user' => [
19+
'permissions' => [
20+
'authenticated',
21+
//etc..
22+
]
23+
]
24+
]
25+
```
26+
27+
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.
28+
29+
```php
30+
// Example configuration granting access to route handlers based on permissions.
31+
'rules' => [
32+
'admin::admin-login-form' => [],
33+
'admin::admin-login' => [],
34+
'admin::admin-create-form' => ['authenticated'],
35+
'admin::admin-create' => ['authenticated'],
36+
'admin::admin-delete-form' => ['authenticated'],
37+
'admin::admin-delete' => ['authenticated'],
38+
'admin::admin-edit-form' => ['authenticated'],
39+
'admin::admin-edit' => ['authenticated'],
40+
]
41+
```
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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`. See below on how to use our CLI command for listing and executing Doctrine data fixtures.
6+
7+
## Working with fixtures
8+
9+
You can find an example of a fixtures class in `src/Core/src/App/src/Fixture/AdminLoader.php`.
10+
11+
To list all the available fixtures by order of execution run:
12+
13+
```shell
14+
php ./bin/doctrine fixtures:list
15+
```
16+
17+
To execute all fixtures run:
18+
19+
```shell
20+
php ./bin/doctrine fixtures:execute
21+
```
22+
23+
To execute a specific fixture, use its class name, like in this example:
24+
25+
```shell
26+
php ./bin/doctrine fixtures:execute --class=AdminLoader
27+
```
28+
29+
Fixtures can and should be ordered to ensure database consistency.
30+
More on ordering fixtures can be found here :
31+
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: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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 \Laminas\Form\Element\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 \Admin\App\InputFilter\Input\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 tags:
54+
55+
```text
56+
{{ formElement(form.get('exampleCsrf')) }}
57+
```
58+
59+
## Test the implementation
60+
61+
Access your form from the browser and view its source. You should see a new hidden field, called `exampleCsrf` (or however you named it). After filling out the form, submitting it should work as before.
62+
63+
In order to make sure that the new CSRF field works as expected, you can inspect the form using your browser's `Developer tools` and modify its value in any way. Submitting a filled out form should result in a validation error:
64+
65+
> This field is required and cannot be empty.
66+
67+
### Timeout
68+
69+
Note the `timeout` option in your PHP form's `exampleCsrf` field, with its default value set to **3600**. This represents the value in seconds for how long the token is valid. Submitting a form that has been rendered for longer than this value will result in a validation error:
70+
71+
> Invalid CSRF.
72+
73+
You can modify the value of `timeout` in each form, but the default value should work in most cases.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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 `Dot\DependencyInjection\Factory\AttributedServiceFactory::class`.
39+
40+
```php
41+
public function getDependencies(): array
42+
{
43+
return [
44+
'factories' => [
45+
GetAccountLogoutHandler::class => AttributedServiceFactory::class,
46+
]
47+
];
48+
}
49+
```
50+
51+
That's it.
52+
When your object is instantiated from the container, it will automatically have its dependencies resolved.
53+
54+
> Dependencies injection is available to any object within Dotkernel Admin.
55+
> 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: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
```text
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+
```text
50+
Remember this option for other packages of the same type? (y/N)
51+
```
52+
53+
Type `y` here, and hit `enter` to complete this stage.
54+
55+
## Development mode
56+
57+
If you're installing the project for development, make sure you have development mode enabled, by running:
58+
59+
```shell
60+
composer development-enable
61+
```
62+
63+
You can disable development mode by running:
64+
65+
```shell
66+
composer development-disable
67+
```
68+
69+
You can check if you have development mode enabled by running:
70+
71+
```shell
72+
composer development-status
73+
```
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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` this creates a new in-memory database that your tests will run on.
9+
10+
If you want your application to send mail, add valid credentials to the following keys in `config/autoload/mail.global.php`
11+
12+
Under `message_options` key:
13+
14+
- `from` - email address that will send emails (required)
15+
- `from_name` - organization name for signing sent emails (optional)
16+
17+
> **Please add at least 1 email address in order for contact message to reach someone**
18+
19+
Also feel free to add as many CCs as you require under the `dot_mail` => `default` => `message_options` => `cc` key.

0 commit comments

Comments
 (0)