upd: error:2.0 | add: api:3.0 | add: database:3.0

This commit is contained in:
xdrm-brackets 2017-12-10 21:45:08 +01:00
parent 317d6c7fb2
commit 410db63941
26 changed files with 7188 additions and 25 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/.gtm/

View File

@ -57,6 +57,7 @@ xdrm-framework is based on `all in config` so you will have this structure :
> version 2.0 - [documentation](/notice/api/2.0.md)
> version 2.2 - [documentation](/notice/api/2.2.md)
> version 3.0 - [documentation](/notice/api/3.0.md)
#### 3.2 Log - multilog system

View File

@ -38,6 +38,14 @@
"http": [
"1.0"
]
},
"3.0": {
"error": [
"2.0"
],
"http": [
"1.0"
]
}
},
"db-schema": {
@ -69,19 +77,30 @@
"error": [
"2.0"
]
},
"3.0": {
"error": [
"2.0"
]
}
},
},
"lightdb": {
"1.0": []
},
"router": {
"1.0": [],
"2.0": []
},
"token": {
"0.9": []
}
},
"installed": {
"db-schema": "1.0",
"database": "2.0",
"error": "2.0"
"api": "2.2",
"error": "2.0",
"http": "1.0",
"router": "2.0",
"database": "2.0"
}
}

454
notice/api/3.0.md Normal file
View File

@ -0,0 +1,454 @@
```yaml
module: api
version: 3.0
requires:
- http: 1.0
- error: 2.0
```
Links
====
[**I.** Overview](#i-overview)
- [**1** Introduction & features](#1-introduction--features)
- [**2** Basic knowledge](#2-basic-knowledge)
[**II.** Usage](#ii-usage)
- [**1** Setup](#1-setup)
- [**2** Php requirements](#2-php-requirements)
- [**3** From php internally](#3-from-php-internally)
- [**4** From HTTP requests](#4-from-http-requests)
[**III.** Configuration](#iii-configuration)
- [**1** Basic usage](#1-basic-usage)
- [**2** Advanced usage](#2-advanced-usage)
[**IV.** Implementation](#iv-implementation)
- [**1** Permissions : AuthSystem](#1-permissions--authsystem)
- [**2** Modules & methods](#2-modules--methods)
- [**3** Automatic type check](#3-automatic-type-check)
[**V.** Class documentation](#v-class-documentation)
- [**1** Request](#1-request)
- [**2** Response](#2-response)
- [**3** AuthSystem](#4-authsystem)
- [**4** Checker](#4-checker)
- [**5** ModuleFactory](#4-modulefactory)
> # **I.** Overview
> ## **1** Introduction & features
The `api` package (v2.2) allows you to easily create and manage an API. It could be used for an HTTP API (REST, or other kind), or you can use it as an internal core for your system.
The aim of this package is to make your life easier working with APIs or internal delegation. The only things you have to do is to implement your processes and edit the configuration, the package will do the rest.
Things you have to do :
- implement your processes (obviously)
- implement your authentication system (cf. [AuthSystem](#1-permissions--authsystem))
- edit the configuration file (cf. [configuration](#iii-configuration))
Things you **don't have** to do :
- input type check (cf. [Checker](#4-checker))
- API multiple permission management
- optional or required inputs
- before and after scripts
- catch both in-URL and `multipart/form-data` input
> ## **2** Basic knowledge
The API is based over a 2-level delegation structure :
1. `module` which is a set of methods
2. `method` which have input, output, permissions, and is bound to a function
So each of your functionalities must have a `method` name and be inside a `module`.
<u>Example:</u>
* the module `article` contains methods:
* `read` with argument `article_id` (to identify the wanted article)
* `write` with arguments `title` and `body` (data to write into the new created article)
* `edit` with arguments `article_id` and `body` (to identify and replace the body)
* `delete` with argument `article_id` (to identify which article to delete)
If you want to delete the article of id `52`, you must request `article/delete` passing `article_id`=`52`.
> # **II.** Usage
> ## **1** Setup
In order to make the API work, you have to :
1. Edit the configuration file according to your needs (cf. [configuration](#iii-configuration))
2. Implement the Authentication System to manage permissions (cf. [AuthSystem](#1-permissions--authsystem))
3. Implement the code of the methods according to the configuration
> ## **2** Php requirements
> ### 1) include the `autoloader` file
```php
<?php require_once '../autoloader.php';
```
> ### 2) load useful classes
```php
// for API use
use \api\core\Request;
use \api\core\Response;
// for error handling
use \error\core\Err;
```
> ## **3** From php internally
> ### 1) create a request
```php
// creates a request for the module {module} and its method {method} with params
$request = new Request('{module}/{method}', [
'param1' => 10,
'param2' => 'somevalue'
]);
```
> ### 2) catch possible errors (optional)
```php
// if error is not Err::Success
if( $request->error->get() !== Err::Success )
'do something';
```
> ### 3) execute the request and catch response
```php
$response = $request->dispatch();
```
> ### 4) catch response errors (optional)
```php
// if error is not Err::Success
if( $response->error->get() !== Err::Success )
'do something';
```
> ### 5) catch response output
```php
// fetch all outputs
$output = $response->getAll();
// fetch specific output
$specific = $response->get('someOutputName');
```
> ## **4** From HTTP requests
In order to setup an automatic bound from HTTP requests to API directly, you must use a **router**.
> ### 1) Format url so it must begin with `/{module}/{method}`
```php
// let's suppose the url is `/api/{module}/{method}`
$url = '/api/somemodule/somemethod/1/2/';
$uri = substr($url, strlen('/api'));
// $uri = /somemodule/somemethod/1/2/
```
> ### 2) give the url to the HTTP manager
```php
// create request from HTTP data
$request = Request::remote($url);
// execute request and catch response
// note that request errors will propagate through response
$response = $request->dispatch();
// return response as HTTP body
die( $response->serialize() );
```
Then can handle various kinds of URL :
- request and parameters can be in URL (separated by `/`)
- request and parameters can be in `multipart/form-data` or `x-www-form-urlencoded`
- request and parameters of both URL, post data, and form-data are caught
### The following examples can work :
> 1. `http://www.host.com/{module}/{method}/`
```json
"post-data": {
"param1": "{value1}",
"param2": "{value2}"
}
```
> 2. `http://www.host.com/{module}/{method}/{param1}/{param2}`
```json
"post-data": {}
```
> 3. `http://www.host.com/apiOrParentUrl/`
```json
"post-data": {
"module": "{module}",
"method": "{method}",
"param1": "{value1}",
"param2": "{value2}"
}
```
> 4. `http://www.host.com/apiOrParentUrl/{value1}/{value2}`
```json
"post-data": {
"module": "{module}",
"method": "{method}",
}
```
> # **III.** Configuration
```json
{
"{module_name}": {
"{http_method}::{method_name}": {
"description": "{method_description}",
"permissions": ["{method_perm}"],
"options": { "download": "{is_downloadable}" },
"parameters": {
"{name_param}": { "description": "{desc_param}", "type": "{type_param}", "optional": "{is_optional}" }
},
"output": {
"{name_output}": { "description": "{desc_output}", "type": "{type_output}" }
}
}
}
}
```
|variable|description|exemple|
|-------|-------|------|
|`{module_name}`|alphanumeric module name|"publications"|
|`{http_method}`|uppercase HTTP method|"POST"|
|`{method_name}`|alphanumeric method name|"article"|
|`{method_description}`|textual description|"Returns a specific article"|
|`{method_perm}`|permission array|`["poster", "admin", "user"]`|
|`{is_downloadable}`|If you want this method to return a file|`true`, `false`|
|`{name_param}`|Your param's name _*_|"id_article"|
|`{desc_param}`|Your param's description|"Wanted article's id"|
|`{type_param}`|Your param's type (cf. Checker)|"Wanted article's type"|
|`{is_optional}`|Whether to make your param _required_|`true`, `false`|
|`{name_output}`|Your output's name|"article"|
|`{desc_output}`|Your output's description|"Article content"|
_*_ If you want URL (GET) parameters, the {param_name} must be `URL_0`, `URL_1` and so on according to the index wanted in the URL.
> `api/module/method/URL_0/URL_1/URL_2/`
> # **IV.** Implementation
> ## **1** Permissions : AuthSystem
In order to implement your _Authentification System_ you have to implement the **interface** `AuthSystem` located in `/build/api/core/AuthSystem`.
You must register your custom authentification system before each api call with :
```php
// let's suppose your auth system class is "AuthSystemDefault"
\api\core\Request::setAuthSystem(new AuthSystemDefault);
```
> ## **2** Modules & methods
### Module implementation
Each module's implementation is represented as a **file** so as a **class** located in `/build/api/module/`. In order for the autoloader to work, you must name the **file** the same name as the **class**.
### Method implementation
Each method is represented as a method in its module's class.
### Input arguments
Arguments are passed to the method as a single argument which an associative array according to the documentation.
_Notes_:
* Optional parameters if not given are set to `null`
* parameters of type `FILE` are given by reference but the use is the same as normal parameters
* URL parameters are called `URL_0`, `URL_1` and so on according to their order.
### Ouput required
You must return an associative array containing at least the field `error` containing an instance of `/api/core/Error`, then you can add whatever you want to return in the array.
If you don't return the 'error' field, by default it is set to `new Error(Err::Success)`.
> # **V.** Class documentation
> ## **1** Request
### Attributes
The attribute `error` will contain the current `Error` instance.
```php
<?php
public $error;
```
### Methods
Creates a new `Request` object, you must give it a path following the pattern "module/method", the params must be an associative array. Note that the path can be inside the `$params` variable.
It checks missing params and each needed params' type according to the **Checker** implementation (cf. [Checker](#4-checker)). It also checks the permissions you have according to the **AuthSystem** implementation (cf. [AuthSystem](#1-permissions--authsystem)).
```php
<?php
public function __construct(String $path, Array $params) : Request;
```
Creates a new `Request` object but from the URL. It will seek for the *path* in the URL, then in the data. (it will call itself the **\_\_construct()** method).
```php
<?php
public static function remote(String $url, Array $data) : Request;
```
Registers the **AuthSystem** you want, must be done before any construction.
```php
<?php
public static function setAuthSystem(Request $instance) : bool;
```
Executes the current `Request` object and returns a `Response` object.
```php
<?php
public function dispatch() : Response;
```
Same as `dispatch()` but manages the **download** option (cf. [Configuration](#iii-configuration)). It will use 2 of the parameters you must return on success : `body`, and `headers`. The first one must contain the content of the file to create, the second the headers in an associative array.
The call will become the file itself.
Note: If the `HTTP_X_REQUESTED_WITH` header is present, it will create the downloadable file as **/tmp/download_{some\_hash}** and return a normal `Response` object with the field `link` containing the file absolute path.
```php
<?php
public function download() : null;
public function download() : Response; // if called by Ajax
```
> ## **2** Response
### Attributes
The attribute `error` will contain the current `Error` instance.
```php
<?php
public $error;
```
### Methods
Returns an associative array containing the whole response data (excluding the error).
```php
<?php
public function getAll() : Array;
```
Returns only the field from the response data (if it exists).
```php
<?php
public function get(String $key) : mixed; // on success
public function get(String $key) : null; // on error
```
Sets the `HTTP_CODE` according to the `Error` argument, also it sets the header for **application/json**.
It can be used for simple API response, it will add the *"error"* and *"ErrorDescription"* fields to the data and set the headers so you can display the result of the API call.
```php
<?php
public function serialize() : String;
```
> ## **4** Checker
`Checker` checks the input values according to the type given in the configuration.
The default types below are available in the default package.
To add a new type, just open the file `/build/api/Checker.php` and add an entry in the `switch` statement.
### Default types
|Type|Example|Description|
|---|---|---|
|`mixed`|`[9,"a"]`, `"a"`|Any content (can be simple or complex)|
|`id`|`10`, `"23"`|Positive integer number between `0` and `2147483647`|
|`numeric`|`-10.2`, `"23"`|Any number, `null` and the string `"null"`|
|`text`|`"Hello!"`|String that can be of any length (even empty)|
|`hash`|`"4612473aa81f93a878674f9ebffa8d63a1b51ea28dcdcdb1e89eb512aae9b77e"`|String with a length of 40 or 64, containing only hexadecimal characters|
|`alphanumeric`|`"abc029.-sd9"`|String containing only alphanumeric, ___, _-_, and _._ characters|
|`letters`|`"abc -sd"`|String containing only letters, _-_, and space characters|
|`mail`|`"a.b@c.def"`|Valid email address|
|`number`|`0102030405`|Phone number, following formats allowed : `06`, `+336`, `+33 6`|
|`array`|`[1, 3]`|Non-empty array|
|`object`|_works only within php_|Non-empty object|
|`boolean`|`true`, `false`|Boolean|
|`varchar(a,b)`|`"Hello!"`|String with a length between `a` and `b` (included)|
|`varchar(a,b,c)`|`"abc"`|String with a length between `a` and `b` (included) and matching the `c` type|
### Complex type : chainable array
|Type|Sub-Type|Description|
|---|---|---|
|`array<a>`|`a`|Array containing only entries matching the type `a`|
> **Note:** It is possible to chain `array` type as many as needed.
**Ex.:** `array<array<id>>` - Will match array only containing arrays that only contains `id` entries.
> ## **5** Advanced
### Before and After scripts
Each time a **method** is called, the api **creates an instance** from the class, and after the execution, the class is **destroyed**. So you can implement the methods `__construct` and `__destruct` to add before and after scripts.

View File

@ -9,12 +9,12 @@ Overview
----
> ### 1. Introduction
The `orm` package allows you to simplify SQL requests through php objects. You will never have to use SQL code anymore.
The `orm` package allows you to simplify SQL requests through php chain-methods. You will never have to use SQL code anymore.
> ### 2. Setup
In order for the orm to work, you will ne to configure the `database` driver according to your database credentials and information.
In order for the orm to work, you will have to configure the `database` driver according to your database credentials and information.
> ### 3. Features
@ -49,7 +49,7 @@ Specification
Usage
----
> ### (1) Loader
> #### [1] Loader
```php
<?php
@ -59,9 +59,9 @@ Usage
use \orm\core\Rows;
```
> ### (2) SELECT queries
> #### [2] SELECT queries
> #### (2.1) Single Table
> ##### (2.1) Single Table
```php
<?php
@ -79,7 +79,7 @@ Usage
```
> #### (2.3) Select
> ##### (2.3) Select
```php
<?php
@ -92,7 +92,7 @@ Usage
->fetch();
```
> #### (2.4) Order by
> ##### (2.4) Order by
```php
<?php
@ -141,11 +141,11 @@ The where clause uses one of php's magic functions (\_\_call). So the name of th
You can refer to the following examples:
|Field|condition|
|Field|Method name|
|---|---|
|username|`whereUsername`|
|id_user|`whereIdUser`|
|aaa_bb_c_ddd|`aaaBbCDdd`|
|aaa_bb_c_ddd|`whereAaaBbCDdd`|
```php
<?php
@ -155,4 +155,160 @@ You can refer to the following examples:
->whereUsername('someusername') // if username is equal to 'someusername'
->whereMail(['somemail', Rows::COND_EQUAL]) // same as previous line (explicit here)
->fetch();
```
Request examples
----
> ##### `1. Select all`
```sql
SELECT *
FROM user_table
```
```php
<?php
$rows = Table::get('user_table')
->select('*')
->fetch();
```
> ##### `2. Normal select`
```sql
SELECT id_user, username, mail
FROM user_table
```
```php
<?php
$rows = Table::get('user_table')
->select('id_user')
->select('username')
->select('mail')
->fetch();
```
> ##### `3. Select distinct`
```sql
SELECT DISTINCT id_user, -- distinct
username,
mail
FROM user_table
```
```php
<?php
$rows = Table::get('user_table')
->select('id_user', null, true) // 2nd arg is for aggregation functions
->select('username')
->select('mail')
->fetch();
```
> ##### `4. Aggregation functions`
```sql
SELECT id_post,
count(nb_view)
FROM posts
```
```php
<?php
$rows = Table::get('posts')
->select('id_post')
->select('nb_view', Rows::SEL_COUNT)
->fetch();
```
> ##### `5. Select as (alias)`
```sql
SELECT id_post,
count(nb_view) as NB_COUNT
FROM posts
```
```php
<?php
$rows = Table::get('posts')
->select('id_post')
->select('nb_view', Rows::SEL_COUNT, null, 'NB_COUNT')
->fetch();
```
> ##### `6. Single PRIMARY KEY condition`
```sql
SELECT *
FROM posts
WHERE id_post = 10
```
```php
<?php
$rows = Table::get('posts')
->select('*')
->whereId(10)
->fetch();
```
> ##### `7. Composite PRIMARY KEY condition`
```sql
SELECT *
FROM posts
WHERE id_post = 10 -- primary key (field 1)
AND id_user = 11 -- primary key (field 2)
```
```php
<?php
$rows = Table::get('posts')
->select('*')
->whereId([10, 11])
->fetch();
```
> ##### `8. Condition types`
```sql
SELECT *
FROM complex_table
WHERE a = 10
AND b <> 11
AND c < 12
AND d > 13
AND e <= 14
AND f >= 15
AND g LIKE '%16%'
AND h IN (2, 4, 6, 8)
```
```php
<?php
$rows = Table::get('complex_table')
->select('*')
->whereA( 10 )
->whereB( [11, Rows::COND_NOTEQ] )
->whereC( [12, Rows::COND_INF] )
->whereD( [13, Rows::COND_SUP] )
->whereE( [14, Rows::COND_INFEQ] )
->whereF( [15, Rows::COND_SUPEQ] )
->whereG( ['%16%', Rows::COND_LIKE] )
->whereH( [[2, 4, 6, 8], Rows::COND_IN] )
->fetch();
```

309
notice/token/0.9.md Normal file
View File

@ -0,0 +1,309 @@
```yaml
module: token
version: 0.9
```
Overview
----
> ### 1. Introduction
The `token` package features the `TreeToken`. It allows securing PHP sessions and children instances.
> ### 3. Features
PHP SESSION
- Prevent XSS (_PHPSESSID_ theft)
- Each PHP load has a single-use token
- that checks that last call was yours
- that unsets the session if someone theft your _PHPSESSID_
- Manage `INSERT INTO` queries
- Manage `DELETE` queries
Specification
- Fetches the whole schema specification (foreign keys, primary keys, etc)
- Manage `SELECT *`
- Manage composite `PRIMARY KEY`
- Manage `WHERE` conditions (_=_, _<>_, _<_, _>_, _>=_, _<=_, _LIKE_, _IN_)
- Manage aggregation functions (_AVG()_, _SUM()_, _MAX()_, _MIN()_, _COUNT()_, *GROUP_CONCAT()*)
- Manage `ORDER BY` ordering
- Manage `SELECT DISTINCT` specification (_ASC_, _DESC_)
- Inserting multiple rows at once
- Automatically select the **PRIMARY KEY(S)**
- Manage joined tables
- Manage `fetch` and `fetchAll`
- Manage `NULL` keyword
- Manage booleans
- Manage inserting the `DEFAULT` value
- Manage format beautifying (numbers as numbers, same for booleans, null)
Usage
----
> #### [1] Loader
```php
<?php
require_once __ROOT__.'/autoloader.php';
use \orm\core\Table;
use \orm\core\Rows;
```
> #### [2] SELECT queries
> ##### (2.1) Single Table
```php
<?php
// All matching rows
Table::get('table_name')
->select('*')
->fetch();
// First row only
Table::get('table_name')
->select('*')
->unique()
->fetch();
```
> ##### (2.3) Select
```php
<?php
Table::get('table_name')
->select('field_1')
->select('field_2')
/// ...
->select('field_N')
->fetch();
```
> ##### (2.4) Order by
```php
<?php
// Ascending order of the field `field_name`
Table::get('table_name')
->orderby('field_name', Rows::ORDER_ASC)
->fetch();
// Descending order of the field `field_name`
Table::get('table_name')
->orderby('field_name', Rows::ORDER_DESC)
->fetch();
```
> #### (2.5) WhereId
It will match the corresponding `PRIMARY KEY` of the table, if it is a composed key (multiple fields) instead of giving an argument, give an array for each in the order displayed in _phpmyadmin_ or you mysql viewer.
```php
<?php
// PRIMARY KEY => `id_user`
Table::get('user')
->select('*') // select all fields
->whereId(12) // if id_user is equal to 12
->fetch(); // fetch matching rows
// PRIMARY KEYS => `username` + `mail`
Table::get('user')
->select('*') // select all fields
->whereId([12, 'sample@mail.com'])
// if `id_user` is equal to 12
// AND `mail` is equal to 'sample@mail.com'
->fetch(); // fetch matching rows
```
The available condition operators are listed in the [constants](todo) section.
Note: `Rows::COND_EQUAL` is set by default if missing
> #### (2.6) Where clause
The where clause uses one of php's magic functions (\_\_call). So the name of the method you call will contain the field of the condition. But you must use the correct case, removing '\_' and setting the next character to upper case. The rest will be forced to lower case.
You can refer to the following examples:
|Field|Method name|
|---|---|
|username|`whereUsername`|
|id_user|`whereIdUser`|
|aaa_bb_c_ddd|`whereAaaBbCDdd`|
```php
<?php
Table::get('user')
->select('*')
->whereUsername('someusername') // if username is equal to 'someusername'
->whereMail(['somemail', Rows::COND_EQUAL]) // same as previous line (explicit here)
->fetch();
```
Request examples
----
> ##### `1. Select all`
```sql
SELECT *
FROM user_table
```
```php
<?php
$rows = Table::get('user_table')
->select('*')
->fetch();
```
> ##### `2. Normal select`
```sql
SELECT id_user, username, mail
FROM user_table
```
```php
<?php
$rows = Table::get('user_table')
->select('id_user')
->select('username')
->select('mail')
->fetch();
```
> ##### `3. Select distinct`
```sql
SELECT DISTINCT id_user, -- distinct
username,
mail
FROM user_table
```
```php
<?php
$rows = Table::get('user_table')
->select('id_user', null, true) // 2nd arg is for aggregation functions
->select('username')
->select('mail')
->fetch();
```
> ##### `4. Aggregation functions`
```sql
SELECT id_post,
count(nb_view)
FROM posts
```
```php
<?php
$rows = Table::get('posts')
->select('id_post')
->select('nb_view', Rows::SEL_COUNT)
->fetch();
```
> ##### `5. Select as (alias)`
```sql
SELECT id_post,
count(nb_view) as NB_COUNT
FROM posts
```
```php
<?php
$rows = Table::get('posts')
->select('id_post')
->select('nb_view', Rows::SEL_COUNT, null, 'NB_COUNT')
->fetch();
```
> ##### `6. Single PRIMARY KEY condition`
```sql
SELECT *
FROM posts
WHERE id_post = 10
```
```php
<?php
$rows = Table::get('posts')
->select('*')
->whereId(10)
->fetch();
```
> ##### `7. Composite PRIMARY KEY condition`
```sql
SELECT *
FROM posts
WHERE id_post = 10 -- primary key (field 1)
AND id_user = 11 -- primary key (field 2)
```
```php
<?php
$rows = Table::get('posts')
->select('*')
->whereId([10, 11])
->fetch();
```
> ##### `8. Condition types`
```sql
SELECT *
FROM complex_table
WHERE a = 10
AND b <> 11
AND c < 12
AND d > 13
AND e <= 14
AND f >= 15
AND g LIKE '%16%'
AND h IN (2, 4, 6, 8)
```
```php
<?php
$rows = Table::get('complex_table')
->select('*')
->whereA( 10 )
->whereB( [11, Rows::COND_NOTEQ] )
->whereC( [12, Rows::COND_INF] )
->whereD( [13, Rows::COND_SUP] )
->whereE( [14, Rows::COND_INFEQ] )
->whereF( [15, Rows::COND_SUPEQ] )
->whereG( ['%16%', Rows::COND_LIKE] )
->whereH( [[2, 4, 6, 8], Rows::COND_IN] )
->fetch();
```

View File

@ -0,0 +1,747 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="149.81798mm"
height="129.68071mm"
viewBox="0 0 530.8511 459.49858"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="child-normal.svg"
inkscape:export-filename="/home/xdrm-brackets/Desktop/MTI/EN/api.png"
inkscape:export-xdpi="200"
inkscape:export-ydpi="200">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient4721">
<stop
style="stop-color:#00f06d;stop-opacity:1"
offset="0"
id="stop4723" />
<stop
style="stop-color:#00b1c0;stop-opacity:1"
offset="1"
id="stop4725" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient4727"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient5230"
gradientUnits="userSpaceOnUse"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient12483"
gradientUnits="userSpaceOnUse"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient12531"
gradientUnits="userSpaceOnUse"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.5291466"
inkscape:cx="300.62853"
inkscape:cy="109.20759"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1056"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-134.11541,-132.00727)">
<g
id="g4347"
transform="translate(274.24477,41.559116)">
<g
id="server_2_"
transform="translate(206.42857,54.285714)">
<g
id="bottom_lines">
<rect
y="84"
x="34"
width="10"
id="right"
height="3"
style="fill:#22313f" />
<rect
y="84"
x="83.900002"
width="10"
id="left"
height="3"
style="fill:#22313f" />
</g>
<g
id="_x30_2_1_">
<rect
y="61"
x="34"
width="60"
id="line"
height="3"
style="fill:#e6e6e6" />
<path
id="bg_1_"
d="m 95,84 -62,0 c -2.2,0 -4,-1.8 -4,-4 l 0,-12 c 0,-2.2 1.8,-4 4,-4 l 62,0 c 2.2,0 4,1.8 4,4 l 0,12 c 0,2.2 -1.8,4 -4,4 z"
inkscape:connector-curvature="0"
style="fill:#cdcdcd;fill-opacity:1" />
<circle
r="3"
id="green_1_"
cy="74"
cx="90.900002"
style="fill:#26a65b" />
<circle
r="3"
id="red_1_"
cy="74"
cx="81.900002"
style="fill:#cf000f" />
<g
id="lines_1_">
<rect
y="69"
x="34"
width="3"
id="line_6_"
height="10"
style="fill:#e6e6e6" />
<rect
y="69"
x="40"
width="3"
id="line_5_"
height="10"
style="fill:#e6e6e6" />
<rect
y="69"
x="46"
width="3"
id="line_4_"
height="10"
style="fill:#e6e6e6" />
</g>
</g>
<g
id="_x30_1">
<path
id="bg"
d="m 95,61 -62,0 c -2.2,0 -4,-1.8 -4,-4 l 0,-12 c 0,-2.2 1.8,-4 4,-4 l 62,0 c 2.2,0 4,1.8 4,4 l 0,12 c 0,2.2 -1.8,4 -4,4 z"
inkscape:connector-curvature="0"
style="fill:#cdcdcd;fill-opacity:1" />
<circle
r="3"
id="green"
cy="51"
cx="90.900002"
style="fill:#26a65b" />
<circle
r="3"
id="red"
cy="51"
cx="81.900002"
style="fill:#cf000f" />
<g
id="lines">
<rect
y="46"
x="34"
width="3"
id="line_3_"
height="10"
style="fill:#e6e6e6" />
<rect
y="46"
x="40"
width="3"
id="line_2_"
height="10"
style="fill:#e6e6e6" />
<rect
y="46"
x="46"
width="3"
id="line_1_"
height="10"
style="fill:#e6e6e6" />
</g>
</g>
</g>
</g>
<path
inkscape:connector-curvature="0"
id="path5002"
d="m 544.67383,188.79102 0,402.71484 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
<path
inkscape:connector-curvature="0"
id="path4410"
d="m 173.57227,188.79102 0,372.71484 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
<g
id="g4453">
<path
id="path4451"
d="m 519.64062,212.86631 5.9375,-5.9375 -336.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<text
sodipodi:linespacing="125%"
id="text4421"
y="200.53732"
x="295.17606"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="200.53732"
x="295.17606"
id="tspan4423"
sodipodi:role="line">PHPSESSID@A + REQUEST</tspan></text>
</g>
<g
id="g4458"
transform="translate(0,-34)">
<path
id="path4417"
d="m 526.78516,269.6431 -336.42774,0 5.9375,5.9375"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="305.85938"
y="265.52719"
id="text4425"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4427"
x="305.85938"
y="265.52719">token@1 + RESPONSE</tspan></text>
</g>
<g
id="g5107">
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 519.64062,312.86631 5.9375,-5.9375 -336.42773,0"
id="path4484" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="267.77963"
y="300.53732"
id="text4486"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4488"
x="267.77963"
y="300.53732">PHPSESSID@A + token@1 + REQUEST</tspan></text>
</g>
<g
id="g5112">
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 526.78516,335.6431 -336.42774,0 5.9375,5.9375"
id="path4496" />
<text
sodipodi:linespacing="125%"
id="text4498"
y="331.52719"
x="305.85931"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="331.52719"
x="305.85931"
id="tspan4500"
sodipodi:role="line">token@2 + RESPONSE</tspan></text>
</g>
<g
id="g5324">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="547.93054"
y="237.79166"
id="text4421-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4423-6"
x="547.93054"
y="237.79166">session@1</tspan></text>
<g
transform="matrix(0.2200785,0,0,0.2200785,496.02255,102.12705)"
id="g4729">
<circle
style="fill:url(#linearGradient4727);fill-opacity:1"
cx="347.52115"
cy="485.22617"
r="60.285717"
id="circle4705" />
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
id="path4707" />
</g>
<text
sodipodi:linespacing="125%"
id="text5260"
y="203.79166"
x="591.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="203.79166"
x="591.93054"
id="tspan5262"
sodipodi:role="line">PHPSESSID: <tspan
id="tspan5295"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
y="215.38036"
x="591.93054"
sodipodi:role="line"
id="tspan5264">TOKEN: <tspan
id="tspan5297"
style="fill:#00f887;fill-opacity:1">init</tspan></tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#5b5b5b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="249.84848"
y="-355.30606"
id="text4749"
sodipodi:linespacing="125%"
transform="matrix(0,1,-1,0,0,0)"
inkscape:transform-center-x="-4.6428571"
inkscape:transform-center-y="6.0714374"><tspan
sodipodi:role="line"
id="tspan4751"
x="249.84848"
y="-355.30606"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#5b5b5b;fill-opacity:1">...</tspan></text>
<g
transform="matrix(0.06927375,0,0,0.06927375,511.66135,272.54384)"
id="g4753" />
<g
id="g5028">
<g
transform="matrix(0.75876954,0,0,0.75876954,41.870715,44.107742)"
id="g4441">
<g
id="g4214"
transform="translate(109.57143,84.84483)">
<path
id="path4200"
d="M 18,91 18,36.5 C 18,33.2 20.7,31 24,31 l 80,0 c 3.3,0 6,2.2 6,5.5 l 0,54.5"
inkscape:connector-curvature="0"
style="fill:#3e3e42" />
<path
id="path4202"
d="m 12,92.5 0,1 c 0,2.2 1.8,4.5 4,4.5 l 96,0 c 2.2,0 4,-2.3 4,-4.5 l 0,-1 C 116,91.4 115.1,91 114,91 L 14,91 c -1.1,0 -2,0.4 -2,1.5 z"
inkscape:connector-curvature="0"
style="fill:#d2d2d6" />
<rect
id="rect4204"
y="36"
x="23"
width="82"
height="50"
style="fill:#57575e" />
<path
id="path4206"
d="m 76,94 -24,0 c -1.1,0 -2,-1.4 -2,-2.5 l 0,-0.5 28,0 0,0.5 c 0,1.1 -0.9,2.5 -2,2.5 z"
inkscape:connector-curvature="0"
style="fill:#a6a6ad" />
</g>
</g>
<text
sodipodi:linespacing="125%"
id="text4818"
y="164.78575"
x="164.10817"
style="font-style:normal;font-weight:normal;font-size:27.95645332px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#ffffff;fill-opacity:1"
y="164.78575"
x="164.10817"
id="tspan4820"
sodipodi:role="line">A</tspan></text>
</g>
<g
id="g5088" />
<g
id="g5336">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="591.93054"
y="307.79166"
id="text5266"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5268"
x="591.93054"
y="307.79166">PHPSESSID: <tspan
id="tspan5299"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
id="tspan5270"
sodipodi:role="line"
x="591.93054"
y="319.38037">TOKEN: <tspan
id="tspan5301"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text5220"
y="337.79166"
x="547.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="337.79166"
x="547.93054"
id="tspan5222"
sodipodi:role="line">session@1</tspan></text>
<g
id="g5224"
transform="matrix(0.2200785,0,0,0.2200785,496.02255,202.12705)">
<circle
id="circle5226"
r="60.285717"
cy="485.22617"
cx="347.52115"
style="fill:url(#linearGradient5230);fill-opacity:1" />
<path
id="path5228"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
</g>
</g>
<path
sodipodi:nodetypes="ccc"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 247.0319,408.82914 0,162.71484 z"
id="path12441"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path12443"
d="m 228.93967,381.80494 -54.71484,0 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
<g
id="g12409"
transform="matrix(0.39835721,0,0,0.39835721,221.53704,357.34682)">
<g
id="g12411">
<g
id="g12413">
<circle
id="circle12415"
style="fill:#f0db4f"
r="50"
cy="64"
cx="64" />
</g>
</g>
<g
id="Layer_1_1_">
<g
id="g12418">
<g
id="g12420">
<path
id="path12422"
style="fill:#323330"
d="m 48.4,44.6 8.7,0 0,24.5 C 57.1,80.1 51.8,84 43.4,84 41.3,84 38.7,83.7 37,83.1 L 38,76 c 1.2,0.4 2.8,0.7 4.5,0.7 3.7,0 6,-1.7 6,-7.6 l -0.1,-24.5 0,0 z"
inkscape:connector-curvature="0" />
<path
id="path12424"
style="fill:#323330"
d="m 64.8,74.4 c 2.3,1.2 6,2.4 9.7,2.4 4,0 6.1,-1.7 6.1,-4.3 0,-2.4 -1.8,-3.8 -6.5,-5.4 C 67.7,64.8 63.4,61.2 63.4,55.5 63.4,49 69,44 78.1,44 c 4.4,0 7.6,0.9 9.9,2 l -2,7 c -1.5,-0.7 -4.3,-1.8 -8,-1.8 -3.8,0 -5.6,1.8 -5.6,3.7 0,2.5 2.1,3.6 7.2,5.5 6.8,2.5 10,6.1 10,11.6 0,6.5 -4.9,12 -15.6,12 -4.4,0 -8.8,-1.2 -11,-2.4 l 1.8,-7.2 z"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</g>
<g
id="g12445"
transform="translate(74,120)">
<path
id="path12447"
d="m 451.64062,312.86631 5.9375,-5.9375 -268.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
sodipodi:linespacing="125%"
id="text12449"
y="300.53732"
x="232.77956"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="300.53732"
x="232.77956"
id="tspan12451"
sodipodi:role="line">PHPSESSID@A + token@2 + REQUEST</tspan></text>
</g>
<g
id="g12453"
transform="translate(74,120)">
<path
id="path12455"
d="m 456.78516,335.6431 -266.42774,0 5.9375,5.9375"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="266.43207"
y="331.52719"
id="text12457"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12459"
x="266.43207"
y="331.52719">token@2.1 + RESPONSE</tspan></text>
</g>
<g
id="g12461"
transform="translate(0,120)">
<text
sodipodi:linespacing="125%"
id="text12463"
y="301.79166"
x="591.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="301.79166"
x="591.93054"
id="tspan12465"
sodipodi:role="line">PHPSESSID: <tspan
style="fill:#00f887;fill-opacity:1"
id="tspan12467">ok</tspan></tspan><tspan
y="313.38037"
x="591.93054"
sodipodi:role="line"
id="tspan12469">TOKEN: <tspan
style="fill:#00f887;fill-opacity:1"
id="tspan12471">ok</tspan></tspan><tspan
y="324.96906"
x="591.93054"
sodipodi:role="line"
id="tspan12485">SUBTOKEN: <tspan
style="fill:#00f887;fill-opacity:1"
id="tspan12487">ok</tspan></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="547.93054"
y="337.79166"
id="text12473"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12475"
x="547.93054"
y="337.79166">session@1</tspan></text>
<g
transform="matrix(0.2200785,0,0,0.2200785,496.02255,202.12705)"
id="g12477">
<circle
style="fill:url(#linearGradient12483);fill-opacity:1"
cx="347.52115"
cy="485.22617"
r="60.285717"
id="circle12479" />
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
id="path12481" />
</g>
</g>
<g
transform="translate(74,236)"
id="g12489">
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 451.64062,312.86631 5.9375,-5.9375 -268.42773,0"
id="path12491" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="229.35237"
y="300.53732"
id="text12493"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12495"
x="229.35237"
y="300.53732">PHPSESSID@A + token@2.1 + REQUEST</tspan></text>
</g>
<g
transform="translate(74,236)"
id="g12497">
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 456.78516,335.6431 -266.42774,0 5.9375,5.9375"
id="path12499" />
<text
sodipodi:linespacing="125%"
id="text12501"
y="331.52719"
x="266.43207"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="331.52719"
x="266.43207"
id="tspan12503"
sodipodi:role="line">token@2.2 + RESPONSE</tspan></text>
</g>
<g
transform="translate(0,236)"
id="g12505">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="591.93054"
y="301.79166"
id="text12507"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12509"
x="591.93054"
y="301.79166">PHPSESSID: <tspan
id="tspan12511"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
id="tspan12513"
sodipodi:role="line"
x="591.93054"
y="313.38037">TOKEN: <tspan
id="tspan12515"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
id="tspan12517"
sodipodi:role="line"
x="591.93054"
y="324.96906">SUBTOKEN: <tspan
id="tspan12519"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text12521"
y="337.79166"
x="547.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="337.79166"
x="547.93054"
id="tspan12523"
sodipodi:role="line">session@1</tspan></text>
<g
id="g12525"
transform="matrix(0.2200785,0,0,0.2200785,496.02255,202.12705)">
<circle
id="circle12527"
r="60.285717"
cy="485.22617"
cx="347.52115"
style="fill:url(#linearGradient12531);fill-opacity:1" />
<path
id="path12529"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
</g>
</g>
<text
inkscape:transform-center-y="6.0714374"
inkscape:transform-center-x="-4.6428571"
transform="matrix(0,1,-1,0,0,0)"
sodipodi:linespacing="125%"
id="text12533"
y="-394.75775"
x="474.86197"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#5b5b5b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#5b5b5b;fill-opacity:1"
y="-394.75775"
x="474.86197"
id="tspan12535"
sodipodi:role="line">...</tspan></text>
</g>
<style
id="style4287"
type="text/css">
.st0{fill:#E5E5E5;}
.st1{fill:#231F20;}
.st2{fill:#FFFFFF;}
</style>
</svg>

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,473 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="149.81798mm"
height="61.94738mm"
viewBox="0 0 530.8511 219.49859"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="parent-normal.svg"
inkscape:export-filename="/home/xdrm-brackets/Desktop/MTI/EN/api.png"
inkscape:export-xdpi="200"
inkscape:export-ydpi="200">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient4721">
<stop
style="stop-color:#00f06d;stop-opacity:1"
offset="0"
id="stop4723" />
<stop
style="stop-color:#00b1c0;stop-opacity:1"
offset="1"
id="stop4725" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient4727"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient5230"
gradientUnits="userSpaceOnUse"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.1625398"
inkscape:cx="101.50732"
inkscape:cy="3.4259355"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1056"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-134.11541,-132.00727)">
<g
id="g4347"
transform="translate(274.24477,41.559116)">
<g
id="server_2_"
transform="translate(206.42857,54.285714)">
<g
id="bottom_lines">
<rect
y="84"
x="34"
width="10"
id="right"
height="3"
style="fill:#22313f" />
<rect
y="84"
x="83.900002"
width="10"
id="left"
height="3"
style="fill:#22313f" />
</g>
<g
id="_x30_2_1_">
<rect
y="61"
x="34"
width="60"
id="line"
height="3"
style="fill:#e6e6e6" />
<path
id="bg_1_"
d="m 95,84 -62,0 c -2.2,0 -4,-1.8 -4,-4 l 0,-12 c 0,-2.2 1.8,-4 4,-4 l 62,0 c 2.2,0 4,1.8 4,4 l 0,12 c 0,2.2 -1.8,4 -4,4 z"
inkscape:connector-curvature="0"
style="fill:#cdcdcd;fill-opacity:1" />
<circle
r="3"
id="green_1_"
cy="74"
cx="90.900002"
style="fill:#26a65b" />
<circle
r="3"
id="red_1_"
cy="74"
cx="81.900002"
style="fill:#cf000f" />
<g
id="lines_1_">
<rect
y="69"
x="34"
width="3"
id="line_6_"
height="10"
style="fill:#e6e6e6" />
<rect
y="69"
x="40"
width="3"
id="line_5_"
height="10"
style="fill:#e6e6e6" />
<rect
y="69"
x="46"
width="3"
id="line_4_"
height="10"
style="fill:#e6e6e6" />
</g>
</g>
<g
id="_x30_1">
<path
id="bg"
d="m 95,61 -62,0 c -2.2,0 -4,-1.8 -4,-4 l 0,-12 c 0,-2.2 1.8,-4 4,-4 l 62,0 c 2.2,0 4,1.8 4,4 l 0,12 c 0,2.2 -1.8,4 -4,4 z"
inkscape:connector-curvature="0"
style="fill:#cdcdcd;fill-opacity:1" />
<circle
r="3"
id="green"
cy="51"
cx="90.900002"
style="fill:#26a65b" />
<circle
r="3"
id="red"
cy="51"
cx="81.900002"
style="fill:#cf000f" />
<g
id="lines">
<rect
y="46"
x="34"
width="3"
id="line_3_"
height="10"
style="fill:#e6e6e6" />
<rect
y="46"
x="40"
width="3"
id="line_2_"
height="10"
style="fill:#e6e6e6" />
<rect
y="46"
x="46"
width="3"
id="line_1_"
height="10"
style="fill:#e6e6e6" />
</g>
</g>
</g>
</g>
<path
inkscape:connector-curvature="0"
id="path5002"
d="m 544.67383,188.79102 0,162.71484 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
<path
inkscape:connector-curvature="0"
id="path4410"
d="m 173.57227,188.79102 0,162.71484 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
<g
id="g4453">
<path
id="path4451"
d="m 519.64062,212.86631 5.9375,-5.9375 -336.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<text
sodipodi:linespacing="125%"
id="text4421"
y="200.53732"
x="295.17606"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="200.53732"
x="295.17606"
id="tspan4423"
sodipodi:role="line">PHPSESSID@A + REQUEST</tspan></text>
</g>
<g
id="g4458"
transform="translate(0,-34)">
<path
id="path4417"
d="m 526.78516,269.6431 -336.42774,0 5.9375,5.9375"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="305.85938"
y="265.52719"
id="text4425"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4427"
x="305.85938"
y="265.52719">token@1 + RESPONSE</tspan></text>
</g>
<g
id="g5107">
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 519.64062,312.86631 5.9375,-5.9375 -336.42773,0"
id="path4484" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="267.77963"
y="300.53732"
id="text4486"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4488"
x="267.77963"
y="300.53732">PHPSESSID@A + token@1 + REQUEST</tspan></text>
</g>
<g
id="g5112">
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 526.78516,335.6431 -336.42774,0 5.9375,5.9375"
id="path4496" />
<text
sodipodi:linespacing="125%"
id="text4498"
y="331.52719"
x="305.85931"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="331.52719"
x="305.85931"
id="tspan4500"
sodipodi:role="line">token@2 + RESPONSE</tspan></text>
</g>
<g
id="g5324">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="547.93054"
y="237.79166"
id="text4421-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4423-6"
x="547.93054"
y="237.79166">session@1</tspan></text>
<g
transform="matrix(0.2200785,0,0,0.2200785,496.02255,102.12705)"
id="g4729">
<circle
style="fill:url(#linearGradient4727);fill-opacity:1"
cx="347.52115"
cy="485.22617"
r="60.285717"
id="circle4705" />
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
id="path4707" />
</g>
<text
sodipodi:linespacing="125%"
id="text5260"
y="203.79166"
x="591.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="203.79166"
x="591.93054"
id="tspan5262"
sodipodi:role="line">PHPSESSID: <tspan
id="tspan5295"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
y="215.38036"
x="591.93054"
sodipodi:role="line"
id="tspan5264">TOKEN: <tspan
id="tspan5297"
style="fill:#00f887;fill-opacity:1">init</tspan></tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#5b5b5b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="249.84848"
y="-355.30606"
id="text4749"
sodipodi:linespacing="125%"
transform="matrix(0,1,-1,0,0,0)"
inkscape:transform-center-x="-4.6428571"
inkscape:transform-center-y="6.0714374"><tspan
sodipodi:role="line"
id="tspan4751"
x="249.84848"
y="-355.30606"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#5b5b5b;fill-opacity:1">...</tspan></text>
<g
transform="matrix(0.06927375,0,0,0.06927375,511.66135,272.54384)"
id="g4753" />
<g
id="g5028">
<g
transform="matrix(0.75876954,0,0,0.75876954,41.870715,44.107742)"
id="g4441">
<g
id="g4214"
transform="translate(109.57143,84.84483)">
<path
id="path4200"
d="M 18,91 18,36.5 C 18,33.2 20.7,31 24,31 l 80,0 c 3.3,0 6,2.2 6,5.5 l 0,54.5"
inkscape:connector-curvature="0"
style="fill:#3e3e42" />
<path
id="path4202"
d="m 12,92.5 0,1 c 0,2.2 1.8,4.5 4,4.5 l 96,0 c 2.2,0 4,-2.3 4,-4.5 l 0,-1 C 116,91.4 115.1,91 114,91 L 14,91 c -1.1,0 -2,0.4 -2,1.5 z"
inkscape:connector-curvature="0"
style="fill:#d2d2d6" />
<rect
id="rect4204"
y="36"
x="23"
width="82"
height="50"
style="fill:#57575e" />
<path
id="path4206"
d="m 76,94 -24,0 c -1.1,0 -2,-1.4 -2,-2.5 l 0,-0.5 28,0 0,0.5 c 0,1.1 -0.9,2.5 -2,2.5 z"
inkscape:connector-curvature="0"
style="fill:#a6a6ad" />
</g>
</g>
<text
sodipodi:linespacing="125%"
id="text4818"
y="164.78575"
x="164.10817"
style="font-style:normal;font-weight:normal;font-size:27.95645332px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#ffffff;fill-opacity:1"
y="164.78575"
x="164.10817"
id="tspan4820"
sodipodi:role="line">A</tspan></text>
</g>
<g
id="g5088" />
<g
id="g5336">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="591.93054"
y="307.79166"
id="text5266"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5268"
x="591.93054"
y="307.79166">PHPSESSID: <tspan
id="tspan5299"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
id="tspan5270"
sodipodi:role="line"
x="591.93054"
y="319.38037">TOKEN: <tspan
id="tspan5301"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text5220"
y="337.79166"
x="547.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="337.79166"
x="547.93054"
id="tspan5222"
sodipodi:role="line">session@1</tspan></text>
<g
id="g5224"
transform="matrix(0.2200785,0,0,0.2200785,496.02255,202.12705)">
<circle
id="circle5226"
r="60.285717"
cy="485.22617"
cx="347.52115"
style="fill:url(#linearGradient5230);fill-opacity:1" />
<path
id="path5228"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
</g>
</g>
</g>
<style
id="style4287"
type="text/css">
.st0{fill:#E5E5E5;}
.st1{fill:#231F20;}
.st2{fill:#FFFFFF;}
</style>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -0,0 +1,756 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="155.55685mm"
height="135.32516mm"
viewBox="0 0 551.1857 479.49862"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="parent-xss-no-token.svg"
inkscape:export-filename="/home/xdrm-brackets/Desktop/MTI/EN/api.png"
inkscape:export-xdpi="200"
inkscape:export-ydpi="200">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient5203">
<stop
style="stop-color:#fe3f00;stop-opacity:1"
offset="0"
id="stop5205" />
<stop
style="stop-color:#b02b00;stop-opacity:1"
offset="1"
id="stop5207" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4721">
<stop
style="stop-color:#00f06d;stop-opacity:1"
offset="0"
id="stop4723" />
<stop
style="stop-color:#00b1c0;stop-opacity:1"
offset="1"
id="stop4725" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient4727"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5203"
id="linearGradient5209"
x1="76.771591"
y1="79.223305"
x2="458.46191"
y2="488.33508"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient5230"
gradientUnits="userSpaceOnUse"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient5398"
gradientUnits="userSpaceOnUse"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.1625398"
inkscape:cx="214.12676"
inkscape:cy="124.87851"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1056"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-134.11541,-132.00727)">
<g
id="g4347"
transform="translate(274.24477,41.559116)">
<g
id="server_2_"
transform="translate(206.42857,54.285714)">
<g
id="bottom_lines">
<rect
y="84"
x="34"
width="10"
id="right"
height="3"
style="fill:#22313f" />
<rect
y="84"
x="83.900002"
width="10"
id="left"
height="3"
style="fill:#22313f" />
</g>
<g
id="_x30_2_1_">
<rect
y="61"
x="34"
width="60"
id="line"
height="3"
style="fill:#e6e6e6" />
<path
id="bg_1_"
d="m 95,84 -62,0 c -2.2,0 -4,-1.8 -4,-4 l 0,-12 c 0,-2.2 1.8,-4 4,-4 l 62,0 c 2.2,0 4,1.8 4,4 l 0,12 c 0,2.2 -1.8,4 -4,4 z"
inkscape:connector-curvature="0"
style="fill:#cdcdcd;fill-opacity:1" />
<circle
r="3"
id="green_1_"
cy="74"
cx="90.900002"
style="fill:#26a65b" />
<circle
r="3"
id="red_1_"
cy="74"
cx="81.900002"
style="fill:#cf000f" />
<g
id="lines_1_">
<rect
y="69"
x="34"
width="3"
id="line_6_"
height="10"
style="fill:#e6e6e6" />
<rect
y="69"
x="40"
width="3"
id="line_5_"
height="10"
style="fill:#e6e6e6" />
<rect
y="69"
x="46"
width="3"
id="line_4_"
height="10"
style="fill:#e6e6e6" />
</g>
</g>
<g
id="_x30_1">
<path
id="bg"
d="m 95,61 -62,0 c -2.2,0 -4,-1.8 -4,-4 l 0,-12 c 0,-2.2 1.8,-4 4,-4 l 62,0 c 2.2,0 4,1.8 4,4 l 0,12 c 0,2.2 -1.8,4 -4,4 z"
inkscape:connector-curvature="0"
style="fill:#cdcdcd;fill-opacity:1" />
<circle
r="3"
id="green"
cy="51"
cx="90.900002"
style="fill:#26a65b" />
<circle
r="3"
id="red"
cy="51"
cx="81.900002"
style="fill:#cf000f" />
<g
id="lines">
<rect
y="46"
x="34"
width="3"
id="line_3_"
height="10"
style="fill:#e6e6e6" />
<rect
y="46"
x="40"
width="3"
id="line_2_"
height="10"
style="fill:#e6e6e6" />
<rect
y="46"
x="46"
width="3"
id="line_1_"
height="10"
style="fill:#e6e6e6" />
</g>
</g>
</g>
</g>
<path
inkscape:connector-curvature="0"
id="path5002"
d="m 544.67383,188.79102 0,422.71484 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
<path
inkscape:connector-curvature="0"
id="path4410"
d="m 173.57227,188.79102 0,422.71484 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
<g
id="g4453">
<path
id="path4451"
d="m 519.64062,212.86631 5.9375,-5.9375 -336.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<text
sodipodi:linespacing="125%"
id="text4421"
y="200.53732"
x="295.17606"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="200.53732"
x="295.17606"
id="tspan4423"
sodipodi:role="line">PHPSESSID@A + REQUEST</tspan></text>
</g>
<g
id="g4458"
transform="translate(0,-34)">
<path
id="path4417"
d="m 526.78516,269.6431 -336.42774,0 5.9375,5.9375"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="305.85938"
y="265.52719"
id="text4425"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4427"
x="305.85938"
y="265.52719">token@1 + RESPONSE</tspan></text>
</g>
<g
id="g5107">
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 519.64062,312.86631 5.9375,-5.9375 -336.42773,0"
id="path4484" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="267.77963"
y="300.53732"
id="text4486"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4488"
x="267.77963"
y="300.53732">PHPSESSID@A + token@1 + REQUEST</tspan></text>
</g>
<g
id="g5112">
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 526.78516,335.6431 -336.42774,0 5.9375,5.9375"
id="path4496" />
<text
sodipodi:linespacing="125%"
id="text4498"
y="331.52719"
x="305.85931"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="331.52719"
x="305.85931"
id="tspan4500"
sodipodi:role="line">token@2 + RESPONSE</tspan></text>
</g>
<g
id="g5324">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="547.93054"
y="237.79166"
id="text4421-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4423-6"
x="547.93054"
y="237.79166">session@1</tspan></text>
<g
transform="matrix(0.2200785,0,0,0.2200785,496.02255,102.12705)"
id="g4729">
<circle
style="fill:url(#linearGradient4727);fill-opacity:1"
cx="347.52115"
cy="485.22617"
r="60.285717"
id="circle4705" />
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
id="path4707" />
</g>
<text
sodipodi:linespacing="125%"
id="text5260"
y="203.79166"
x="591.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="203.79166"
x="591.93054"
id="tspan5262"
sodipodi:role="line">PHPSESSID: <tspan
id="tspan5295"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
y="215.38036"
x="591.93054"
sodipodi:role="line"
id="tspan5264">TOKEN: <tspan
id="tspan5297"
style="fill:#00f887;fill-opacity:1">init</tspan></tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#5b5b5b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="249.84848"
y="-355.30606"
id="text4749"
sodipodi:linespacing="125%"
transform="matrix(0,1,-1,0,0,0)"
inkscape:transform-center-x="-4.6428571"
inkscape:transform-center-y="6.0714374"><tspan
sodipodi:role="line"
id="tspan4751"
x="249.84848"
y="-355.30606"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#5b5b5b;fill-opacity:1">...</tspan></text>
<g
transform="matrix(0.06927375,0,0,0.06927375,511.66135,272.54384)"
id="g4753" />
<g
id="g5028">
<g
transform="matrix(0.75876954,0,0,0.75876954,41.870715,44.107742)"
id="g4441">
<g
id="g4214"
transform="translate(109.57143,84.84483)">
<path
id="path4200"
d="M 18,91 18,36.5 C 18,33.2 20.7,31 24,31 l 80,0 c 3.3,0 6,2.2 6,5.5 l 0,54.5"
inkscape:connector-curvature="0"
style="fill:#3e3e42" />
<path
id="path4202"
d="m 12,92.5 0,1 c 0,2.2 1.8,4.5 4,4.5 l 96,0 c 2.2,0 4,-2.3 4,-4.5 l 0,-1 C 116,91.4 115.1,91 114,91 L 14,91 c -1.1,0 -2,0.4 -2,1.5 z"
inkscape:connector-curvature="0"
style="fill:#d2d2d6" />
<rect
id="rect4204"
y="36"
x="23"
width="82"
height="50"
style="fill:#57575e" />
<path
id="path4206"
d="m 76,94 -24,0 c -1.1,0 -2,-1.4 -2,-2.5 l 0,-0.5 28,0 0,0.5 c 0,1.1 -0.9,2.5 -2,2.5 z"
inkscape:connector-curvature="0"
style="fill:#a6a6ad" />
</g>
</g>
<text
sodipodi:linespacing="125%"
id="text4818"
y="164.78575"
x="164.10817"
style="font-style:normal;font-weight:normal;font-size:27.95645332px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#ffffff;fill-opacity:1"
y="164.78575"
x="164.10817"
id="tspan4820"
sodipodi:role="line">A</tspan></text>
</g>
<g
id="g5038"
transform="translate(180,246)">
<g
id="g5040"
transform="matrix(0.75876954,0,0,0.75876954,41.870715,44.107742)">
<g
transform="translate(109.57143,84.84483)"
id="g5042">
<path
style="fill:#3e3e42"
inkscape:connector-curvature="0"
d="M 18,91 18,36.5 C 18,33.2 20.7,31 24,31 l 80,0 c 3.3,0 6,2.2 6,5.5 l 0,54.5"
id="path5044" />
<path
style="fill:#d2d2d6"
inkscape:connector-curvature="0"
d="m 12,92.5 0,1 c 0,2.2 1.8,4.5 4,4.5 l 96,0 c 2.2,0 4,-2.3 4,-4.5 l 0,-1 C 116,91.4 115.1,91 114,91 L 14,91 c -1.1,0 -2,0.4 -2,1.5 z"
id="path5046" />
<rect
style="fill:#57575e"
height="50"
width="82"
x="23"
y="36"
id="rect5048" />
<path
style="fill:#a6a6ad"
inkscape:connector-curvature="0"
d="m 76,94 -24,0 c -1.1,0 -2,-1.4 -2,-2.5 l 0,-0.5 28,0 0,0.5 c 0,1.1 -0.9,2.5 -2,2.5 z"
id="path5050" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:27.95645332px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="163.95441"
y="164.78575"
id="text5052"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5054"
x="163.95441"
y="164.78575"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#ffffff;fill-opacity:1">B</tspan></text>
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 353.57227,438.79102 0,74.71484 z"
id="path5056"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<g
id="g5088" />
<g
id="g5102"
transform="translate(0,6)">
<path
id="path5058"
d="m 327.64062,458.50782 5.9375,-5.9375 -144.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
sodipodi:linespacing="125%"
id="text5084"
y="447.88287"
x="215.48849"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="447.88287"
x="215.48849"
id="tspan5086"
sodipodi:role="line">stole PHPSESSID@A</tspan></text>
</g>
<g
id="g5117"
transform="translate(180,6)">
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 340.78516,451.6431 -150.42774,0 5.9375,5.9375"
id="path5119" />
<text
sodipodi:linespacing="125%"
id="text5121"
y="446.53455"
x="202.17596"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="446.53455"
x="202.17596"
id="tspan5123"
sodipodi:role="line">PHPSESSID@A + REQUEST</tspan></text>
</g>
<g
transform="translate(180,12)"
id="g5125">
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 337.64062,474.50782 5.9375,-5.9375 -154.42773,0"
id="path5127" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="232.96899"
y="463.88287"
id="text5129"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5131"
x="232.96899"
y="463.88287">PHPSESSID@A</tspan></text>
</g>
<g
id="g5336">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="591.93054"
y="307.79166"
id="text5266"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5268"
x="591.93054"
y="307.79166">PHPSESSID: <tspan
id="tspan5299"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
id="tspan5270"
sodipodi:role="line"
x="591.93054"
y="319.38037">TOKEN: <tspan
id="tspan5301"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text5220"
y="337.79166"
x="547.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="337.79166"
x="547.93054"
id="tspan5222"
sodipodi:role="line">session@1</tspan></text>
<g
id="g5224"
transform="matrix(0.2200785,0,0,0.2200785,496.02255,202.12705)">
<circle
id="circle5226"
r="60.285717"
cy="485.22617"
cx="347.52115"
style="fill:url(#linearGradient5230);fill-opacity:1" />
<path
id="path5228"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
</g>
</g>
<g
id="g5348"
transform="translate(0,-16)">
<g
transform="matrix(0.04903609,0,0,0.04903609,559.32115,456.81804)"
id="g5199">
<circle
style="fill:url(#linearGradient5209);fill-opacity:1"
cx="256"
cy="256"
r="256"
id="circle5189" />
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="M 268.7,256 388.3,136.4 c 3.2,-3.2 3.2,-8.3 0,-11.4 -3.2,-3.2 -8.3,-3.2 -11.4,0 L 257.2,244.6 135.1,122.5 c -3.2,-3.2 -8.3,-3.2 -11.4,0 -3.2,3.2 -3.2,8.3 0,11.4 L 245.8,256 123.7,378.1 c -3.2,3.2 -3.2,8.3 0,11.4 1.6,1.6 3.7,2.4 5.7,2.4 2.1,0 4.1,-0.8 5.7,-2.4 L 257.2,267.4 376.8,387 c 1.6,1.6 3.7,2.4 5.7,2.4 2.1,0 4.1,-0.8 5.7,-2.4 3.2,-3.2 3.2,-8.3 0,-11.4 L 268.7,256 Z"
id="path5191" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="547.93054"
y="497.79166"
id="text5313"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5315"
x="547.93054"
y="497.79166">session@2</tspan></text>
<text
sodipodi:linespacing="125%"
id="text5283"
y="467.79166"
x="591.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="467.79166"
x="591.93054"
id="tspan5285"
sodipodi:role="line">PHPSESSID: <tspan
id="tspan5303"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
y="479.38037"
x="591.93054"
sodipodi:role="line"
id="tspan5287">TOKEN: <tspan
id="tspan5311"
style="fill:#ff450f;fill-opacity:1">missing</tspan></tspan></text>
</g>
<g
id="g5360"
transform="translate(0,240)">
<path
id="path5362"
d="m 519.64062,312.86631 5.9375,-5.9375 -336.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<text
sodipodi:linespacing="125%"
id="text5364"
y="300.53732"
x="267.77963"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="300.53732"
x="267.77963"
id="tspan5366"
sodipodi:role="line">PHPSESSID@A + token@2 + REQUEST</tspan></text>
</g>
<g
id="g5368"
transform="translate(0,240)">
<path
id="path5370"
d="m 526.78516,335.6431 -336.42774,0 5.9375,5.9375"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="305.85931"
y="331.52719"
id="text5372"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5374"
x="305.85931"
y="331.52719">token@3 + RESPONSE</tspan></text>
</g>
<g
id="g5376"
transform="translate(0,240)">
<text
sodipodi:linespacing="125%"
id="text5378"
y="307.79166"
x="591.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="307.79166"
x="591.93054"
id="tspan5380"
sodipodi:role="line">PHPSESSID: <tspan
style="fill:#ff450f;fill-opacity:1"
id="tspan5400">unset</tspan></tspan><tspan
y="319.38037"
x="591.93054"
sodipodi:role="line"
id="tspan5384">TOKEN: <tspan
style="fill:#00f887;fill-opacity:1"
id="tspan5386">ok</tspan></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="547.93054"
y="337.79166"
id="text5388"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5390"
x="547.93054"
y="337.79166">session@3</tspan></text>
<g
transform="matrix(0.2200785,0,0,0.2200785,496.02255,202.12705)"
id="g5392">
<circle
style="fill:url(#linearGradient5398);fill-opacity:1"
cx="347.52115"
cy="485.22617"
r="60.285717"
id="circle5394" />
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
id="path5396" />
</g>
</g>
</g>
<style
id="style4287"
type="text/css">
.st0{fill:#E5E5E5;}
.st1{fill:#231F20;}
.st2{fill:#FFFFFF;}
</style>
</svg>

After

Width:  |  Height:  |  Size: 29 KiB

895
notice/token/parent-xss.svg Normal file
View File

@ -0,0 +1,895 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="163.37073mm"
height="163.54738mm"
viewBox="0 0 578.87265 579.49859"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="parent-xss.svg"
inkscape:export-filename="/home/xdrm-brackets/Desktop/MTI/EN/api.png"
inkscape:export-xdpi="200"
inkscape:export-ydpi="200">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient4721">
<stop
style="stop-color:#00f06d;stop-opacity:1"
offset="0"
id="stop4723" />
<stop
style="stop-color:#00b1c0;stop-opacity:1"
offset="1"
id="stop4725" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient4727"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient5230"
gradientUnits="userSpaceOnUse"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4721"
id="linearGradient5398-6"
gradientUnits="userSpaceOnUse"
x1="277.63901"
y1="411.99011"
x2="399.72568"
y2="536.74396" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5203"
id="linearGradient5209"
x1="76.771591"
y1="79.223305"
x2="458.46191"
y2="488.33508"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
id="linearGradient5203">
<stop
style="stop-color:#fe3f00;stop-opacity:1"
offset="0"
id="stop5205" />
<stop
style="stop-color:#b02b00;stop-opacity:1"
offset="1"
id="stop5207" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5203"
id="linearGradient11401"
gradientUnits="userSpaceOnUse"
x1="76.771591"
y1="79.223305"
x2="458.46191"
y2="488.33508" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.1625398"
inkscape:cx="339.1003"
inkscape:cy="133.08646"
inkscape:document-units="px"
inkscape:current-layer="g11379"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1056"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-134.11544,-132.00727)">
<g
id="g4347"
transform="translate(314.24477,41.559116)">
<g
id="server_2_"
transform="translate(206.42857,54.285714)">
<g
id="bottom_lines">
<rect
y="84"
x="34"
width="10"
id="right"
height="3"
style="fill:#22313f" />
<rect
y="84"
x="83.900002"
width="10"
id="left"
height="3"
style="fill:#22313f" />
</g>
<g
id="_x30_2_1_">
<rect
y="61"
x="34"
width="60"
id="line"
height="3"
style="fill:#e6e6e6" />
<path
id="bg_1_"
d="m 95,84 -62,0 c -2.2,0 -4,-1.8 -4,-4 l 0,-12 c 0,-2.2 1.8,-4 4,-4 l 62,0 c 2.2,0 4,1.8 4,4 l 0,12 c 0,2.2 -1.8,4 -4,4 z"
inkscape:connector-curvature="0"
style="fill:#cdcdcd;fill-opacity:1" />
<circle
r="3"
id="green_1_"
cy="74"
cx="90.900002"
style="fill:#26a65b" />
<circle
r="3"
id="red_1_"
cy="74"
cx="81.900002"
style="fill:#cf000f" />
<g
id="lines_1_">
<rect
y="69"
x="34"
width="3"
id="line_6_"
height="10"
style="fill:#e6e6e6" />
<rect
y="69"
x="40"
width="3"
id="line_5_"
height="10"
style="fill:#e6e6e6" />
<rect
y="69"
x="46"
width="3"
id="line_4_"
height="10"
style="fill:#e6e6e6" />
</g>
</g>
<g
id="_x30_1">
<path
id="bg"
d="m 95,61 -62,0 c -2.2,0 -4,-1.8 -4,-4 l 0,-12 c 0,-2.2 1.8,-4 4,-4 l 62,0 c 2.2,0 4,1.8 4,4 l 0,12 c 0,2.2 -1.8,4 -4,4 z"
inkscape:connector-curvature="0"
style="fill:#cdcdcd;fill-opacity:1" />
<circle
r="3"
id="green"
cy="51"
cx="90.900002"
style="fill:#26a65b" />
<circle
r="3"
id="red"
cy="51"
cx="81.900002"
style="fill:#cf000f" />
<g
id="lines">
<rect
y="46"
x="34"
width="3"
id="line_3_"
height="10"
style="fill:#e6e6e6" />
<rect
y="46"
x="40"
width="3"
id="line_2_"
height="10"
style="fill:#e6e6e6" />
<rect
y="46"
x="46"
width="3"
id="line_1_"
height="10"
style="fill:#e6e6e6" />
</g>
</g>
</g>
</g>
<path
inkscape:connector-curvature="0"
id="path5002"
d="m 584.67383,188.79102 0,522.71484 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
<path
inkscape:connector-curvature="0"
id="path4410"
d="m 173.57227,188.79102 0,522.71484 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
<g
id="g4453">
<path
id="path4451"
d="m 559.64062,212.86631 5.9375,-5.9375 -376.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
sodipodi:linespacing="125%"
id="text4421"
y="200.53732"
x="315.17596"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="200.53732"
x="315.17596"
id="tspan4423"
sodipodi:role="line">PHPSESSID@A + REQUEST</tspan></text>
</g>
<g
id="g4458"
transform="translate(0,-34)">
<path
id="path4417"
d="m 566.78516,269.6431 -376.42774,0 5.9375,5.9375"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="325.85931"
y="265.52719"
id="text4425"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4427"
x="325.85931"
y="265.52719">token@1 + RESPONSE</tspan></text>
</g>
<g
id="g5107">
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 559.64062,312.86631 5.9375,-5.9375 -376.42773,0"
id="path4484"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="287.77954"
y="300.53732"
id="text4486"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4488"
x="287.77954"
y="300.53732">PHPSESSID@A + token@1 + REQUEST</tspan></text>
</g>
<g
id="g5112">
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 566.78516,335.6431 -376.42774,0 5.9375,5.9375"
id="path4496"
sodipodi:nodetypes="ccc" />
<text
sodipodi:linespacing="125%"
id="text4498"
y="331.52719"
x="325.85931"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="331.52719"
x="325.85931"
id="tspan4500"
sodipodi:role="line">token@2 + RESPONSE</tspan></text>
</g>
<g
id="g5324"
transform="translate(40,0)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="547.93054"
y="237.79166"
id="text4421-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4423-6"
x="547.93054"
y="237.79166">session@1</tspan></text>
<g
transform="matrix(0.2200785,0,0,0.2200785,496.02255,102.12705)"
id="g4729">
<circle
style="fill:url(#linearGradient4727);fill-opacity:1"
cx="347.52115"
cy="485.22617"
r="60.285717"
id="circle4705" />
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
id="path4707" />
</g>
<text
sodipodi:linespacing="125%"
id="text5260"
y="203.79166"
x="591.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="203.79166"
x="591.93054"
id="tspan5262"
sodipodi:role="line">PHPSESSID: <tspan
id="tspan5295"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
y="215.38036"
x="591.93054"
sodipodi:role="line"
id="tspan5264">TOKEN: <tspan
id="tspan5297"
style="fill:#00f887;fill-opacity:1">init</tspan></tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#5b5b5b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="249.84848"
y="-375.75775"
id="text4749"
sodipodi:linespacing="125%"
transform="matrix(0,1,-1,0,0,0)"
inkscape:transform-center-x="-4.6428571"
inkscape:transform-center-y="6.0714374"><tspan
sodipodi:role="line"
id="tspan4751"
x="249.84848"
y="-375.75775"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#5b5b5b;fill-opacity:1">...</tspan></text>
<g
transform="matrix(0.06927375,0,0,0.06927375,511.66135,272.54384)"
id="g4753" />
<g
id="g5028">
<g
transform="matrix(0.75876954,0,0,0.75876954,41.870715,44.107742)"
id="g4441">
<g
id="g4214"
transform="translate(109.57143,84.84483)">
<path
id="path4200"
d="M 18,91 18,36.5 C 18,33.2 20.7,31 24,31 l 80,0 c 3.3,0 6,2.2 6,5.5 l 0,54.5"
inkscape:connector-curvature="0"
style="fill:#3e3e42" />
<path
id="path4202"
d="m 12,92.5 0,1 c 0,2.2 1.8,4.5 4,4.5 l 96,0 c 2.2,0 4,-2.3 4,-4.5 l 0,-1 C 116,91.4 115.1,91 114,91 L 14,91 c -1.1,0 -2,0.4 -2,1.5 z"
inkscape:connector-curvature="0"
style="fill:#d2d2d6" />
<rect
id="rect4204"
y="36"
x="23"
width="82"
height="50"
style="fill:#57575e" />
<path
id="path4206"
d="m 76,94 -24,0 c -1.1,0 -2,-1.4 -2,-2.5 l 0,-0.5 28,0 0,0.5 c 0,1.1 -0.9,2.5 -2,2.5 z"
inkscape:connector-curvature="0"
style="fill:#a6a6ad" />
</g>
</g>
<text
sodipodi:linespacing="125%"
id="text4818"
y="164.78575"
x="164.10817"
style="font-style:normal;font-weight:normal;font-size:27.95645332px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#ffffff;fill-opacity:1"
y="164.78575"
x="164.10817"
id="tspan4820"
sodipodi:role="line">A</tspan></text>
</g>
<g
id="g5038"
transform="translate(180,246)">
<g
id="g5040"
transform="matrix(0.75876954,0,0,0.75876954,41.870715,44.107742)">
<g
transform="translate(109.57143,84.84483)"
id="g5042">
<path
style="fill:#3e3e42"
inkscape:connector-curvature="0"
d="M 18,91 18,36.5 C 18,33.2 20.7,31 24,31 l 80,0 c 3.3,0 6,2.2 6,5.5 l 0,54.5"
id="path5044" />
<path
style="fill:#d2d2d6"
inkscape:connector-curvature="0"
d="m 12,92.5 0,1 c 0,2.2 1.8,4.5 4,4.5 l 96,0 c 2.2,0 4,-2.3 4,-4.5 l 0,-1 C 116,91.4 115.1,91 114,91 L 14,91 c -1.1,0 -2,0.4 -2,1.5 z"
id="path5046" />
<rect
style="fill:#57575e"
height="50"
width="82"
x="23"
y="36"
id="rect5048" />
<path
style="fill:#a6a6ad"
inkscape:connector-curvature="0"
d="m 76,94 -24,0 c -1.1,0 -2,-1.4 -2,-2.5 l 0,-0.5 28,0 0,0.5 c 0,1.1 -0.9,2.5 -2,2.5 z"
id="path5050" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:27.95645332px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="163.95441"
y="164.78575"
id="text5052"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5054"
x="163.95441"
y="164.78575"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Lato;-inkscape-font-specification:Lato;fill:#ffffff;fill-opacity:1">B</tspan></text>
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 353.57227,438.79102 0,84.71484 z"
id="path5056"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<g
id="g5088" />
<g
id="g5102"
transform="translate(0,6)">
<path
id="path5058"
d="m 327.64062,458.50782 5.9375,-5.9375 -144.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
sodipodi:linespacing="125%"
id="text5084"
y="447.88287"
x="188.52213"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="447.88287"
x="188.52213"
id="tspan5086"
sodipodi:role="line">stole PHPSESSID@A + token@2</tspan></text>
</g>
<g
id="g5117"
transform="translate(180,6)">
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 380.78516,451.6431 -190.42774,0 5.9375,5.9375"
id="path5119" />
<text
sodipodi:linespacing="125%"
id="text5121"
y="446.53455"
x="194.77956"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="446.53455"
x="194.77956"
id="tspan5123"
sodipodi:role="line">PHPSESSID@A + token@2 + <tspan
style="fill:#ff1414;fill-opacity:1"
id="tspan11413">REQUEST</tspan></tspan></text>
</g>
<g
transform="translate(180,12)"
id="g5125">
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 377.64062,474.50782 5.9375,-5.9375 -194.42773,0"
id="path5127" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="252.96899"
y="463.88287"
id="text5129"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5131"
x="252.96899"
y="463.88287">PHPSESSID@A</tspan></text>
</g>
<g
id="g5336"
transform="translate(40,0)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="591.93054"
y="307.79166"
id="text5266"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5268"
x="591.93054"
y="307.79166">PHPSESSID: <tspan
id="tspan5299"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
id="tspan5270"
sodipodi:role="line"
x="591.93054"
y="319.38037">TOKEN: <tspan
id="tspan5301"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text5220"
y="337.79166"
x="547.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="337.79166"
x="547.93054"
id="tspan5222"
sodipodi:role="line">session@1</tspan></text>
<g
id="g5224"
transform="matrix(0.2200785,0,0,0.2200785,496.02255,202.12705)">
<circle
id="circle5226"
r="60.285717"
cy="485.22617"
cx="347.52115"
style="fill:url(#linearGradient5230);fill-opacity:1" />
<path
id="path5228"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
</g>
</g>
<g
id="g5348"
transform="translate(40,-16)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="547.93054"
y="497.79166"
id="text5313"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5315"
x="547.93054"
y="497.79166">session@1</tspan></text>
<text
sodipodi:linespacing="125%"
id="text5283"
y="467.79166"
x="591.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="467.79166"
x="591.93054"
id="tspan5285"
sodipodi:role="line">PHPSESSID: <tspan
id="tspan5303"
style="fill:#00f887;fill-opacity:1">ok</tspan></tspan><tspan
y="479.38037"
x="591.93054"
sodipodi:role="line"
id="tspan5287">TOKEN: <tspan
style="fill:#00f887;fill-opacity:1"
id="tspan6457">ok</tspan></tspan></text>
<g
transform="matrix(0.2200785,0,0,0.2200785,495.39246,362.58343)"
id="g5392-1">
<circle
style="fill:url(#linearGradient5398-6);fill-opacity:1"
cx="347.52115"
cy="485.22617"
r="60.285717"
id="circle5394-2" />
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="m 375.54458,461.20607 -42.57678,42.57678 -13.47009,-13.44654 c -1.01261,-1.01261 -2.6375,-1.01261 -3.62656,0 -1.01262,1.01261 -1.01262,2.6375 0,3.62657 l 15.28337,15.28337 c 0.49453,0.49453 1.1539,0.75357 1.81328,0.75357 0.65937,0 1.31875,-0.25904 1.81328,-0.75357 l 44.39007,-44.39007 c 1.01261,-1.01261 1.01261,-2.6375 0,-3.62656 -1.01261,-1.01262 -2.6375,-1.01262 -3.62657,-0.0236 z"
id="path5396-7" />
</g>
</g>
<g
id="g5360"
transform="translate(0,250)">
<path
id="path5362"
d="m 559.64062,312.86631 5.9375,-5.9375 -376.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
sodipodi:linespacing="125%"
id="text5364"
y="300.53732"
x="287.77954"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="300.53732"
x="287.77954"
id="tspan5366"
sodipodi:role="line">PHPSESSID@A + token@2 + REQUEST</tspan></text>
</g>
<g
id="g5368"
transform="translate(0,250)">
<path
id="path5370"
d="m 566.78516,335.6431 -376.42774,0 5.9375,5.9375"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="325.85931"
y="331.52719"
id="text5372"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5374"
x="325.85931"
y="331.52719">token@3 + RESPONSE</tspan></text>
</g>
<g
id="g5376"
transform="translate(40,250)">
<text
sodipodi:linespacing="125%"
id="text5378"
y="307.79166"
x="591.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="307.79166"
x="591.93054"
id="tspan5380"
sodipodi:role="line">PHPSESSID: <tspan
style="fill:#00f887;fill-opacity:1"
id="tspan6493">ok</tspan></tspan><tspan
y="319.38037"
x="591.93054"
sodipodi:role="line"
id="tspan5384">TOKEN: <tspan
style="fill:#ff450f;fill-opacity:1"
id="tspan6491">error</tspan></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="547.93054"
y="337.79166"
id="text5388"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5390"
x="547.93054"
y="337.79166">session@2</tspan></text>
<g
transform="matrix(0.04903608,0,0,0.04903609,559.95125,296.36166)"
id="g5199">
<circle
style="fill:url(#linearGradient5209);fill-opacity:1"
cx="256"
cy="256"
r="256"
id="circle5189" />
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="M 268.7,256 388.3,136.4 c 3.2,-3.2 3.2,-8.3 0,-11.4 -3.2,-3.2 -8.3,-3.2 -11.4,0 L 257.2,244.6 135.1,122.5 c -3.2,-3.2 -8.3,-3.2 -11.4,0 -3.2,3.2 -3.2,8.3 0,11.4 L 245.8,256 123.7,378.1 c -3.2,3.2 -3.2,8.3 0,11.4 1.6,1.6 3.7,2.4 5.7,2.4 2.1,0 4.1,-0.8 5.7,-2.4 L 257.2,267.4 376.8,387 c 1.6,1.6 3.7,2.4 5.7,2.4 2.1,0 4.1,-0.8 5.7,-2.4 3.2,-3.2 3.2,-8.3 0,-11.4 L 268.7,256 Z"
id="path5191" />
</g>
</g>
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path11361"
d="m 353.57227,608.79102 0,74.71484 z"
style="fill:none;fill-rule:evenodd;stroke:#939393;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
transform="translate(180,176)"
id="g11363">
<path
id="path11365"
d="m 380.78516,451.6431 -190.42774,0 5.9375,5.9375"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="235.52562"
y="446.53455"
id="text11367"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan11369"
x="235.52562"
y="446.53455">token@3 + REQUEST</tspan></text>
</g>
<g
id="g11371"
transform="translate(180,182)">
<path
id="path11373"
d="m 377.64062,474.50782 5.9375,-5.9375 -194.42773,0"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
sodipodi:linespacing="125%"
id="text11375"
y="463.88287"
x="252.96899"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="463.88287"
x="252.96899"
id="tspan11377"
sodipodi:role="line">PHPSESSID@A</tspan></text>
</g>
<g
transform="translate(40,316)"
id="g11379">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="591.93054"
y="307.79166"
id="text11381"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan11383"
x="591.93054"
y="307.79166">PHPSESSID: <tspan
style="fill:#ff450f;fill-opacity:1"
id="tspan11417">unset</tspan></tspan><tspan
id="tspan11387"
sodipodi:role="line"
x="591.93054"
y="319.38037">TOKEN: <tspan
style="fill:#00f887;fill-opacity:1"
id="tspan11419">ok</tspan></tspan></text>
<text
sodipodi:linespacing="125%"
id="text11391"
y="337.79166"
x="547.93054"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="337.79166"
x="547.93054"
id="tspan11393"
sodipodi:role="line">session@3</tspan></text>
<g
id="g11395"
transform="matrix(0.04903608,0,0,0.04903609,559.95125,296.36166)">
<circle
id="circle11397"
r="256"
cy="256"
cx="256"
style="fill:url(#linearGradient11401);fill-opacity:1" />
<path
id="path11399"
d="M 268.7,256 388.3,136.4 c 3.2,-3.2 3.2,-8.3 0,-11.4 -3.2,-3.2 -8.3,-3.2 -11.4,0 L 257.2,244.6 135.1,122.5 c -3.2,-3.2 -8.3,-3.2 -11.4,0 -3.2,3.2 -3.2,8.3 0,11.4 L 245.8,256 123.7,378.1 c -3.2,3.2 -3.2,8.3 0,11.4 1.6,1.6 3.7,2.4 5.7,2.4 2.1,0 4.1,-0.8 5.7,-2.4 L 257.2,267.4 376.8,387 c 1.6,1.6 3.7,2.4 5.7,2.4 2.1,0 4.1,-0.8 5.7,-2.4 3.2,-3.2 3.2,-8.3 0,-11.4 L 268.7,256 Z"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
</g>
</g>
<g
transform="translate(180,56)"
id="g11403">
<path
id="path11405"
d="m 380.78516,451.6431 -190.42774,0 5.9375,5.9375"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:9.27096367px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="232.85931"
y="446.53455"
id="text11407"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan11409"
x="232.85931"
y="446.53455">token@3 + <tspan
style="fill:#ff1414;fill-opacity:1"
id="tspan11415">RESPONSE</tspan></tspan></text>
</g>
</g>
<style
id="style4287"
type="text/css">
.st0{fill:#E5E5E5;}
.st1{fill:#231F20;}
.st2{fill:#FFFFFF;}
</style>
</svg>

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -1,5 +1,14 @@
<?php
/**************************
* API Request *
* 08-12-2016 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace api\core;
use \database\core\DatabaseDriver;
use \api\core\AuthSystem;
@ -407,7 +416,7 @@
// On recupere les données de la regex
$module = $matches[1];
$method = __HTTP_METHOD__.'::'.$matches[2];
$method = __HTTP_METHOD__.':'.$matches[2];
/* [2] Verification de l'existence du module (conf)

29
src/packages/api/3.0/core/AuthSystem.php vendored Executable file
View File

@ -0,0 +1,29 @@
<?php
/**************************
* API AuthSystem *
* 08-12-2016 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace api\core;
use \error\core\Err;
use \error\core\Error;
interface AuthSystem{
/* VERIFICATION DES ACCES EN FONCTION DE PERMISSIONS ATTENDUES
*
* @expected<array> Liste des permissions attendues
*
* @return error<Error> Erreur associée à la permission (Success/PermissionError/TokenError/etc)
*
*/
public static function permission($expected);
}
?>

159
src/packages/api/3.0/core/Checker.php vendored Executable file
View File

@ -0,0 +1,159 @@
<?php
/**************************
* API Checker *
* 08-12-2016 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace api\core;
class Checker{
/* VERIFICATIONS DES TYPES UTILES GENERIQUES
*
* @type<String> Type que l'on veut verifier
* @value<mixed*> Valeur a verifier
*
* @return match<Boolean> Retourne si oui ou non la valeur @value est du bon type @type
*
*/
public static function run($type, $value){
$checker = true;
/* [0] On verifie que $value n'est pas nul
=========================================================*/
if( is_null($value) ) return false;
/* [1] Si de type VARCHAR(min, max, flags)
=========================================================*/
if( preg_match('/^varchar\((\d+), ?(\d+)((?:, ?\w+)+)?\)$/', $type, $match) ){
// On recupere la taille min
$min = (int) $match[1];
// On recupere la taille max
$max = (int) $match[2];
// On recupere le sous-type si défini
$flags = isset($match[3]) ? explode(',', substr($match[3], 1)) : null;
// On effectue la verification de taille
$lenCheck = $checker && is_string($value) && strlen($value) <= $max && strlen($value) >= $min;
// On vérifie les FLAGS s'il est donné
if( is_array($flags) )
foreach( $flags as $flag )
$lenCheck = $lenCheck && self::run($flag, $value);
return $lenCheck;
}
/* [2] Si de type ARRAY(type_elements)
=========================================================*/
if( preg_match('/^array<(.+)>$/', $type, $match) ){
// Si c'est pas un tableau on retourne une erreur
if( !is_array($value) )
return false;
$elements_type = $match[1];
// On verifie le type pour chaque element
foreach($value as $element)
// Si erreur dans au moins 1 element, on retourne que c'est incorrect
if( !self::run($elements_type, trim($element) ) )
return false;
// Si aucune erreur, on retourne que tout est bon
return true;
}
/* [n] Sinon, tous les autres types definis
=========================================================*/
switch($type){
// Quoi que ce soit
case 'mixed':
return $checker && !is_null($value);
break;
// Entier positif (id dans BDD)
case 'id':
return $checker && is_numeric($value) && $value <= 2147483647 && $value >= 0;
break;
// String quelconque (peut etre vide)
case 'text':
return $checker && is_string($value);
// Adresse mail (255 caracteres max)
case 'mail':
return $checker && is_string($value) && strlen($value) <= 50 && preg_match('/^[\w\.-]+@[\w\.-]+\.[a-z]{2,4}$/i', $value);
break;
// Hash sha1/md5
case 'hash':
return $checker && is_string($value) && preg_match('/^[\da-f]{128}$/', $value);
break;
case 'alphanumeric':
return $checker && is_string($value) && preg_match('/^[\w\.-]+$/ui', $value);
break;
case 'letters':
return $checker && is_string($value) && preg_match('/^[a-z -]+$/i', $value);
break;
case 'status':
return $checker && is_numeric($value) && floor($value) == $value && $value >= 0 && $value <= 100;
break;
// Tableau non vide
case 'array':
return $checker && is_array($value) && count($value) > 0;
break;
// Boolean
case 'boolean':
return $checker && is_bool($value);
break;
// Objet non vide
case 'object':
return $checker && is_object($value) && count((array) $value) > 0;
break;
// Chaine JSON (on vérifie via le parser)
case 'json':
return $checker && is_string($value) && json_decode($value, true) !== NULL;
break;
case 'numeric':
return $checker && (is_numeric($value) || $value == null || $value == 'null');
break;
case "float":
return $checker && is_float($value);
break;
default:
return false;
break;
}
return $checker;
}
}
?>

53
src/packages/api/3.0/core/Loader.php vendored Executable file
View File

@ -0,0 +1,53 @@
<?php
/**************************
* API Loader *
* 18-07-2017 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace api\core;
use \error\core\Error;
use \error\core\Err;
use \http\core\HttpRequest;
use \api\core\Request;
class Loader{
/* (1) Build an API Request from the HTTP Request
*
* @uri<String> URI
*
* @return outName<outType> outDesc
*
---------------------------------------------------------*/
public static function remote($uri){
/* (1) Fetch HttpRequest correct data
---------------------------------------------------------*/
/* (1) Parse HttpRequest data because php doesn't parse it for non-POST HTTP method */
$httprequest = new HttpRequest();
/* (2) For later use -> replace default @_POST global */
$_POST = $httprequest->POST();
/* (3) Get @data from @_POST values */
$data = $_POST;
/* (2) Build request
---------------------------------------------------------*/
return new Request($uri, $data);
}
}

45
src/packages/api/3.0/core/ModuleFactory.php vendored Executable file
View File

@ -0,0 +1,45 @@
<?php
/**************************
* API ModuleFactory *
* 08-12-2016 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace api\core;
class ModuleFactory{
/* INSTANCIE UN MODULE
*
* @module<String> Nom du module
* @arguments<Array> [OPTIONNEL] Arguments à passer au constructeur
*
* @return instance<Module> Instance du module en question
*
*/
public static function getModule($module, $arguments=[]){
/* (1) On gère les arguments */
$arguments = is_array($arguments) ? $arguments : [];
/* (2) On transforme @module en namespace */
$module_ns = str_replace('/', '\\', $module);
/* (1) On vérifie que la classe existe */
if( !file_exists(__BUILD__."/api/module/$module.php") )
return false;
/* (2) On récupère la classe */
$class_name = "\\api\\module\\$module_ns";
/* (3) On retourne une instance */
return new $class_name($arguments);
}
}

620
src/packages/api/3.0/core/Request.php vendored Executable file
View File

@ -0,0 +1,620 @@
<?php
namespace api\core;
use \database\core\DatabaseDriver;
use \api\core\AuthSystem;
use \api\core\ModuleFactory;
use \error\core\Error;
use \error\core\Err;
class Request{
// Constantes
public static function config_path(){ return __ROOT__.'/config/modules.json'; }
private static $default_options = [ 'download' => false ];
private static $authsystem = null;
// liste des methodes HTTP autorisées
private static $allowed_http_methods = [ "GET", "POST", "PUT", "DELETE" ];
// Attributs prives utiles (initialisation)
private $path; // chemin de base (uri)
private $raw_params; // paramètres reçus
private $params; // paramètres donnés à la fonction
private $schema; // schema configuration
private $options; // options
private $http_method; // methode HTTP appelante
// Contiendra la reponse a la requete
public $answer;
// Contiendra l'etat de la requete
public $error;
/* (0) Constructeur d'une requete de module
*
* @uri<String> URI relative de l'appel
* @param<Array> Tableau associatif contenant les parametres utiles au traitement
* @forced_method<String> Méthode demandée (optionnel)
*
* @return instance<Request> Instance crée
*
---------------------------------------------------------*/
public function __construct($uri=null, $params=null, $forced_method=null){
return $this->buildRequestObject($uri, $params, $forced_method);
}
/* (1) Constructeur d'une requete de module (delegation)
*
* @uri<String> URI relative de l'appel
* @param<Array> Tableau associatif contenant les parametres utiles au traitement
* @forced_method<String> Méthode demandée (optionnel)
*
* @return status<Boolean> Retourne si oui ou non tout s'est bien passe
*
---------------------------------------------------------*/
private function buildRequestObject($uri=null, $params=null, $forced_method=null){
/* (1) Initialisation
---------------------------------------------------------*/
/* (1) Erreur par défaut */
$this->error = new Error(Err::Success);
/* (2) Si pas parametre manquant, on quitte */
if( $uri == null )
return $this->error->set(Err::MissingPath);
/* (2) On met a jour la configuration
---------------------------------------------------------*/
/* (1) Build from configuration */
$this->buildConfig();
/* (2) Dispatch if error */
if( $this->error->get() != Err::Success )
return;
/* (3) Verification des types des parametres
---------------------------------------------------------*/
/* (1) Si path est une <string> */
if( !is_string($uri) ) // Si le type est incorrect
return $this->error->set(Err::WrongPathModule);
/* (2) Formattage @params en tableau */
$this->raw_params = (is_array($params)) ? $params : [];
/* (3) On définit en constante la méthode HTTP */
if( !isset($_SERVER['REQUEST_METHOD']) && !is_string($forced_method) )
return $this->error->set(Err::UnknownHttpMethod);
$this->http_method = is_string($forced_method) ? strtoupper($forced_method) : strtoupper($_SERVER['REQUEST_METHOD']);
/* (4) Verification du chemin (existence module+methode)
---------------------------------------------------------*/
if( !$this->checkURI($uri) ) // Verification de la coherence du chemin + attribution
return false; // checkURI() sets the error itself
/* (5) Verification des permissions
---------------------------------------------------------*/
if( !$this->checkPermission() ) // Si on a pas les droits
return false; // checkPermission() sets the error itself
/* (6) Verification des parametres (si @type est defini)
---------------------------------------------------------*/
if( !$this->checkParams() ) // Verification de tous les types
return false; // checkParams() sets the error itself
/* (7) Récupèration des options
---------------------------------------------------------*/
$this->buildOptions();
/* (8) Construction de l'objet (add http method to params)
---------------------------------------------------------*/
$this->params['HTTP_METHOD'] = $this->http_method;
$this->error->set(Err::Success);
return true; // On retourne que tout s'est bien passe
}
/* (2) Definit le systeme d'authentification
*
* @instance<AuthSystem> Instance de type AuthSystem
*
* @return success<Boolean> Whether the AuthSystem is valid or not
*
---------------------------------------------------------*/
public static function setAuthSystem($instance=null){
/* (1) Check instance type */
if( !($instance instanceof AuthSystem) )
return false;
/* (2) Store instance */
self::$authsystem = $instance;
return true;
}
/* (3) Construction du schéma à partir de la configuration
*
---------------------------------------------------------*/
private function buildConfig(){
/* (1) Access file content
---------------------------------------------------------*/
/* (1) Vérification existence fichier config */
if( !file_exists(self::config_path()) )
return $this->error->set(Err::UnreachableResource);
/* (2) Lecture fichier config */
$conf = @file_get_contents(self::config_path());
/* (3) Si erreur lecture */
if( $conf === false )
return $this->error->set(Err::UnreachableResource);
/* (4) Parsage json */
$this->schema['raw'] = json_decode( $conf, true );
/* (5) Gestion de l'erreur de parsage */
if( $this->schema['raw'] == null )
return $this->error->set(Err::ParsingFailed, 'json');
/* (2) Construction des outils d'accès
---------------------------------------------------------*/
/* (1) Initialisation */
$this->schema['index'] = [];
/* (2) Pour chaque chemin */
foreach($this->schema['raw'] as $path=>$methods){
/* (2.1) Pour chaque méthode */
foreach($methods as $method=>$data){
/* (2.1.1) Suppression si pas dans les méthodes autorisées */
if( !in_array($method, self::$allowed_http_methods) ){
unset($this->schema[$path][$method]);
continue;
}
/* (2.1.2) Création de l'index pour le chemin si n'existe pas déja */
if( !isset($this->schema['index'][$path]) )
$this->schema['index'][$path] = [];
/* (2.1.3) Ajout de la méthode à l'index */
$this->schema['index'][$path][] = $method;
}
}
}
/* (4) Verification du format et de la coherence du chemin specifie
*
* @path<String> String correspondant au chemin de delegation ("module/methode")
*
* @return validity<Boolean> Retourne si oui ou non l'objet est correct
*
---------------------------------------------------------*/
private function checkURI($uri){
/* (1) Verification format general
---------------------------------------------------------*/
/* (1) If wrong format -> exit */
if( !preg_match('@^\w+(\/\w+)*\/?$@', $uri, $matches) )
return $this->error->set(Err::WrongPathModule);
/* (2) Verification de l'existence du chemin (conf)
---------------------------------------------------------*/
/* (1) Check if begins with each indexed @path */
$exists_size = 0;
$path = null;
foreach($this->schema['index'] as $key=>$void){
$match_size = strlen($key);
/* (1.1) Look for the longer match */
if( $match_size > $exists_size && substr($uri, 0, $match_size) == $key ){
$exists_size = $match_size;
$path = $key;
}
}
/* (2) If @path not found -> exit */
if( is_null($path) )
return $this->error->set(Err::UnknownModule);
/* (3) Extract URI parameters
---------------------------------------------------------*/
/* (1) Extract URI string after @path */
$uri_end = substr($uri, $exists_size);
/* (2) If invalid format, return error */
if( !preg_match('@^((?:\/[^\/]+)*)\/?$@', $uri_end, $uri_match) )
return $this->error->set(Err::InvalidURI);
/* (3) Add each URI parameter to the parameter store */
$uri_args = array_slice( explode('/', $uri_match[1]), 1);
foreach($uri_args as $index=>$value)
$this->raw_params["URL$index"] = $value;
/* (4) Verification de l'existence de la methode (conf)
---------------------------------------------------------*/
/* (1) Check if HTTP method is in allowed methods */
if( !in_array($this->http_method, self::$allowed_http_methods) )
return $this->error->set(Err::UnknownHttpMethod, $this->http_method);
/* (2) Check if HTTP method is defined for this @path */
if( !in_array($this->http_method, $this->schema['index'][$path]) )
return $this->error->set(Err::UnknownMethod, $this->http_method);
/* (5) Enregistrement du chemin et renvoi de SUCCESS
---------------------------------------------------------*/
$this->path = [
'path'=> $path,
'method'=> $this->http_method
];
return true;
}
/* (5) Retourne si on a la permission d'executer cette methode
*
* @return permission<bool> Retourne si on a les droits ou pas pour executer cette methode
*
---------------------------------------------------------*/
private function checkPermission(){
/* (1) On recupere les informations utiles
---------------------------------------------------------*/
// On recupere le nom de la methode
$method = $this->schema['raw'][$this->path['path']][$this->path['method']];
// Si aucune permission n'est definie
if( !isset($method['permissions']) || !is_array($method['permissions']) || count($method['permissions']) < 1 )
return true;
/* (2) Vérification des permissions et de l'authentification
---------------------------------------------------------*/
// if no AuthSystem set up, use the default one
if( !is_object(self::$authsystem) || !self::$authsystem instanceof AuthSystem ){
// try to load default AuthSystem
if( !file_exists(__BUILD__.'/api/core/AuthSystemDefault.php') )
return $this->error->set(Err::UnreachableResource);
// load default AuthSystem class
$classname = '\\api\\core\\AuthSystemDefault';
self::$authsystem = new $classname();
}
// Check permission using user-implemented AuthSystem
$granted = self::$authsystem::permission( $method['permissions'] );
/* (1) On retourne FAUX si aucun droit n'a ete trouve */
if( $granted->get() !== Err::Success ){
$this->error = $granted;
return false;
}
/* On retourne VRAI si la permission est ok */
return true;
}
/* (6) Verification du type des parametres envoyes
*
* @return correct<bool> Retourne si oui ou non les parametres ont le bon type
*
---------------------------------------------------------*/
private function checkParams(){
/* (1) On verifie qu'il ne manque aucun parametre
---------------------------------------------------------*/
/* (1) Si @params n'est pas un tableau */
if( !is_array($this->raw_params) )
return $this->error->set(Err::MissingParam);
/* (2) On récupère les données de la méthode */
$method = $this->schema['raw'][$this->path['path']][$this->path['method']];
/* (3) Si pas 'parameters' dans la config */
if( !isset($method['parameters']) || !is_array($method['parameters']) )
return $this->error->set(Err::ConfigError);
/* (2) Si le type est defini, pour chaque param, on teste
---------------------------------------------------------*/
foreach($method['parameters'] as $name=>$config){
/* (2.1) Vérification des données
---------------------------------------------------------*/
/* (1) Si @name n'est pas une string */
if( !is_string($name) )
return $this->error->set(Err::ConfigError);
/* (2) Si @config n'est pas un tableau */
if( !is_array($config) )
return $this->error->set(Err::ConfigError);
/* (3) So @config['type] manquant ou incorrect */
if( !isset($config['type']) || !is_string($config['type']) )
return $this->error->set(Err::ConfigError);
/* (2.2) Gestion des spécifications
---------------------------------------------------------*/
/* (1) On récupère le paramètre RENAME */
$rename = $name;
if( isset($config['rename']) && is_string($config['rename']) && preg_match('@^\w+$@', $config['rename']) )
$rename = $config['rename'];
/* (1) On récupère si le paramètre est optionnel ou pas */
$optional = isset($config['optional']) && $config['optional'] === true;
/* (2) Si de type 'FILE' + fichier existe => on enregistre la ref. */
if( $config['type'] == 'FILE' && isset($_FILES[$name]) )
$this->params[$rename] = &$_FILES[$name];
/* (3) Si param obligatoire et manquant -> erreur */
if( !isset($this->raw_params[$name]) && !$optional )
return $this->error->set(Err::MissingParam, $name);
/* (2.3) Gestion des valeurs
---------------------------------------------------------*/
/* (1) Si le paramètre est optionnel et manquant */
if( $optional && !isset($this->raw_params[$name]) ){
// On le crée le param optionnel avec la valeur NULL
$this->params[$rename] = null;
/* (2) Si le paramètre est renseigné (sauf FILE) */
}elseif( $config['type'] != 'FILE'){
// Si la verification est fausse, on retourne faux
if( !Checker::run($config['type'], $this->raw_params[$name]) )
return $this->error->set(Err::WrongParam, $name, $config['type']);
// Sinon, on ajoute aux params qu'on enverra à l'appel
else
$this->params[$rename] = $this->raw_params[$name];
}
}
/* (3) Gestion du retour, si tout s'est bien passe
---------------------------------------------------------*/
return true;
}
/* (7) Ajout des options a partir de la configuration
*
* @return correct<bool> Retourne FAUS en cas d'erreur
*
---------------------------------------------------------*/
private function buildOptions(){
/* (1) On récupère les options de la méthode en cours
---------------------------------------------------------*/
$method = $this->schema['raw'][$this->path['path']][$this->path['method']];
/* (1) Si 'option' n'est pas défini (ou incorrect), on met les valeurs par défaut */
if( !isset($method['options']) || !is_array($method['options']) )
return true;
/* (2) Par défaut on définit les options par défaut */
$this->options = self::$default_options;
/* (3) On récupère les options données */
$options = $method['options'];
/* (2) Gestion des différentes options
---------------------------------------------------------*/
foreach($options as $option=>$value){
/* (1) On ne prend en compte l'option que si elle est dans les options par défaut */
if( !isset(self::$default_options[$option]) )
continue;
/* (2) Le type de la valeur doit être le même que celui de la valeur par défaut */
if( gettype($value) != gettype(self::$default_options[$option]) )
continue;
/* (3) Si tout est bon, on définit la valeur */
$this->options[$option] = $value;
}
return true;
}
/* (8) Execute le traitement associe et remplie la reponse
*
* @return answer<Response> Retourne une reponse de type <Response> si tout s'est bien passe
*
---------------------------------------------------------*/
public function dispatch(){
/* (1) On verifie qu'aucune erreur n'a ete signalee
---------------------------------------------------------*/
if( $this->error->get() !== Err::Success ) // si il y a une erreur
return new Response($this->error); // on la passe a la reponse
/* (2) On essaie d'instancier le module
---------------------------------------------------------*/
$instance = ModuleFactory::getModule($this->path['path']);
if( $instance instanceof Error ){
$this->error->set(Err::UncallableModule, $this->path['path']);
return new Response($this->error);
}
/* (3) On verifie que la methode est amorcable
---------------------------------------------------------*/
if( !is_callable([$instance, $this->path['method']]) ){
$this->error->set(Err::UncallableMethod, $this->path['method']);
return new Response($this->error);
}
/* (4) On amorce la methode
---------------------------------------------------------*/
/* (1) On lance la fonction */
$returned = call_user_func( [$instance, $this->path['method']], $this->params );
/* (2) On appelle le destructeur (si défini) */
$instance = null;
/* (5) Gestion de la reponse
---------------------------------------------------------*/
/* (1) S'il s'agit d'un téléchargement -> on dispatch */
if( $this->options['download'] === true )
return $this->download();
/* (2) On construit la réponse avec l'erreur */
$response = new Response($this->error);
/* (3) On ajoute les données */
$response->appendAll($returned);
/* (4) On retourne la réponse */
return $response;
}
/* EXECUTE LE TRAITEMENT ASSOCIE ET RENVOIE UN FICHIER AVEC LE HEADER ET LE BODY SPECIFIE
*
*/
public function download(){
/* (1) Vérification des erreurs et paramètres
---------------------------------------------------------*/
/* (1) Si retourne 'error' et n'est pas SUCCESS -> error */
if( isset($returned['error']) && $returned['error'] instanceof Error && $returned['error']->get() != Err::Success ){
$this->error = $returned['error'];
return new Response($this->error);
}
/* (2) Vérification du contenu, si pas défini */
if( !isset($returned['body']) ){
$this->error->set(Err::MissingBody);
return new Response($this->error);
}
/* (3) Si @headers n'est pas défini on met par défaut */
if( !isset($returned['headers']) || !is_array($returned['headers']) ){
$this->error->set(Err::MissingHeaders);
return new Response($this->error);
}
/* (4) Détermine si téléchargement AJAX/DIRECT */
$from_ajax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
/* (2) Gestion du téléchargement direct (HTTP)
---------------------------------------------------------*/
if( !$from_ajax ){
/* (1) On définit les headers */
foreach($returned['headers'] as $header=>$value)
header($header.': '.$value);
/* (2) On affiche le contenu */
echo $returned['body'];
return true;
}
/* (3) Gestion du téléchargement différé (AJAX)
---------------------------------------------------------*/
/* (1) On génère les noms de fichiers utiles */
$target_fname = '/tmp/download_'.uniqid().'.php'; // cible
$buffer_fname = __ROOT__.'/tmp/content_'.uniqid().'.php'; // buffer
/* (2) On écrit le BODY dans un fichier buffer */
$buffer_file = fopen($buffer_fname, 'w');
fwrite($buffer_file, $returned['body']);
fclose($buffer_file);
/* (3) On crée le fichier cible */
$target_fnameroot = __PUBLIC__.$target_fname;
$taret_file = fopen($target_fnameroot, 'w');
fwrite($taret_file, '<?php'.PHP_EOL);
/* (4) Script qui écrira les headers */
foreach($returned['headers'] as $header=>$value)
fwrite($taret_file, "header(\"$header: $value\");".PHP_EOL);
/* (5) Script qui écrira le contenu du buffer */
chmod($buffer_fname, 0775);
fwrite($taret_file, "readfile('$buffer_fname');".PHP_EOL);
/* (6) Script qui supprimera les fichiers: buffer+target */
fwrite($taret_file, "unlink('$buffer_fname');".PHP_EOL);
fwrite($taret_file, "unlink(__FILE__);".PHP_EOL);
fwrite($taret_file, '?>'.PHP_EOL);
/* (7) On ferme le fichier cible */
fclose($taret_file);
chmod($target_fnameroot, 0775);
/* (8) On envoie la réponse contenant le lien du fichier cible */
$response = new Response($this->error);
$response->append('link', $target_fname);
return $response;
}
}
?>

133
src/packages/api/3.0/core/Response.php vendored Executable file
View File

@ -0,0 +1,133 @@
<?php
/**************************
* API Response *
* 08-12-2016 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace api\core;
use \error\core\Error;
use \error\core\Err;
class Response{
// Attributs prives utiles (initialisation)
private $data;
public $error;
/* CONSTRUCTEUR D'UNE REPONSE DE MODULE
*
* @error<ModuleError> Erreur passee par la requete (si existe)
*
*/
public function __construct($error=null){
if( !( $error instanceof Error ) )
$error = new Error(Err::Success);
$this->data = [];
$this->error = $error;
}
/* AJOUTE UNE DONNEE A LA REPONSE
*
* @key<String> Le nom de la valeur a ajouter
* @value<mixed*> La valeur a ajouter
*
*/
public function append($key, $value){
// Ajoute une entree pour la cle @key et de valeur @value
$this->data[$key] = $value;
return $this;
}
/* AJOUTE TOUTES LES DONNEES A LA REPONSE
*
* @dataset<Array> Le tableau associatif correspondant a la reponse
*
*/
public function appendAll($dataset){
// Si ce n'est pas un tableau, on ne fais rien
if( !is_array($dataset) )
return $this;
// Si une valeur contient une erreur
if( array_key_exists('error', $dataset) && $dataset['error'] instanceof Error){
// On definit cette erreur
$this->error = $dataset['error'];
// On enleve cette entree des donnees
unset($dataset['error']);
}
// Ajoute une entree pour la cle @key et de valeur @value
$this->data = $dataset;
return $this;
}
/* RECUPERE UNE DONNEE DE LA REPONSE
*
* @key<String> Le nom de la valeur a recuperer
*
* @return value<mixed*> La valeur a cette cle
* @return error<null> Retourne NULL si aucune valeur pour cette cle
*
*/
public function get($key){
// Si la valeur de cle @key n'existe pas, on retourne NULL
if( !isset($this->data[$key]) )
return null;
// Sinon, on retourne la valeur associee
return $this->data[$key];
}
/* RECUPERE TOUTES LES DONNEES DE LA REPONSE
*
* @return data<Array> Les donnees de la reponse
*
*/
public function getAll(){
// Sinon, on retourne la valeur associee
return $this->data;
}
/* SERIALISATION A PARTIR DES DONNEES
*
* @return json<String> Retourne les donnees serialisees
*
*/
public function serialize(){
// Code Http
$this->error->setHttpCode();
// Type de contenu
header('Content-Type: application/json; charset=utf-8');
// On rajoute l'erreur au message
$returnData = array_merge([
'error' => $this->error->get(),
'ErrorDescription' => $this->error->explicit()
],
$this->data
);
return json_encode($returnData);
}
}
?>

View File

@ -0,0 +1,197 @@
<?php
/**************************
* DatabaseDriver *
* 08-04-2016 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace database\core;
use \error\core\Error;
use \error\core\Err;
class DatabaseDriver{
/* STATIC ATTRIBUTES */
private static function conf(){
// YOUR CONFIGURATION BEHIND
$path = __CONFIG__.'/database-driver.json';
/* (1) Checks the file */
if( !is_file($path) )
return [];
/* (2) Checks json */
$parsed = json_decode( file_get_contents($path), true );
if( !is_array($parsed) )
return [];
/* (3) Returns configuration */
return $parsed;
}
private static $path; // Databases configurations files
private static $config; // PDO configurations
private static $instance = []; // Database driver instance list
public $error;
/* ATTRIBUTES */
private $host;
private $dbname;
private $username;
private $password;
private $pdo;
/* CONSTRUCTOR OF A DATABASE DRIVER
*
* @host<String> Database Server's host
* @dbname<String> Database name
* @username<String> Database username
* @password<String> Database password
*
*/
private function __construct($host, $dbname, $username, $password){
/* (2) Stores configuration */
$this->host = $host;
$this->dbname = $dbname;
$this->username = $username;
$this->password = $password;
try{
$this->pdo = new \PDO('mysql:host='.$this->host.';dbname='.$this->dbname, $this->username, $this->password, [
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_TIMEOUT => 5
]);
// On signale que tout s'est bien passe
$this->error = new Error(Err::Success);
}catch(Exception $e){
// On signale qu'il y a une erreur
$this->error = new Error(Err::PDOConnection);
}
}
/************************************************
**** Multiton Management (static) ****
************************************************/
/* ADDS A NEW CONNECTION
*
* @label<String> [optional] Database Label
*
* @return status<Boolean> If added successfully
*
*/
private static function add($label=null){
$conf = self::conf();
/* [1] Default values
=========================================================*/
/* (1) If label isn't given */
is_null($label) && ($label = 'default');
/* (2) If label and no path */
if( $label !== 'default' && !isset($conf[$label]) )
return false;
/* [3] Instanciates the driver
=========================================================*/
try{
/* (1) If local -> instanciates with local configuration */
// if( !checkdnsrr($_SERVER['SERVER_NAME'], 'NS') )
self::$instance[$label] = new DatabaseDriver($conf[$label]['local']['host'], $conf[$label]['local']['dbname'], $conf[$label]['local']['user'], $conf[$label]['local']['password']);
/* (2) If Remote -> instanciates with Remote configuration */
// else
// self::$instance[$label] = new DatabaseDriver($conf[$label]['remote']['host'], $conf[$label]['remote']['dbname'], $conf[$label]['remote']['user'], $conf[$label]['remote']['password']);
return true;
}catch(\Exception $e){
/* (3) If fails */
return false;
}
}
/* GET A DATABASE DRIVER INSTANCE
*
* @label<String> [optional] Driver's label
*
* @return driver<Database> Multiton
*
*/
public static function get($label=null){
$conf = self::conf();
/* [1] Checks arguments
=========================================================*/
/* (1) Label default value */
is_null($label) && ($label = 'default');
/* (2) If no label, or unknown label */
if( is_null($label) || !isset(self::$instance[$label]) ){
/* (2.1) Try to add the configuration if exists */
if( isset($conf[$label]) ){
self::add($label);
return self::get($label);
}
throw new \Exception('Database @label is incorrect.');
}
/* [2] Returns instance
=========================================================*/
return self::$instance[$label];
}
/** retourne la connection statique
* @param null $label
* @return \PDO
*/
public static function getPDO($label=null){
$instance = self::get($label);
return $instance->pdo;
}
public function pdo(){
return $this->pdo;
}
public function getConfig(){
return [
'host' => $this->host,
'dbname' => $this->dbname,
'username' => $this->username
];
}
}
?>

79
src/packages/database/3.0/core/Repo.php vendored Normal file
View File

@ -0,0 +1,79 @@
<?php
/**************************
* Repo *
* 24-11-2017 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace database\core;
use \error\core\Error;
use \error\core\Err;
class Repo{
/* (1) Driver
---------------------------------------------------------*/
private static $driver = null;
public static function setDriver(DatabaseDriver $driver){ self::$driver = $driver; }
public static function request(String $repo=null, String $method=null){
/* (1) Check arguments
---------------------------------------------------------*/
/* (1) Check @repo */
if( !is_string($repo) || strlen($repo) < 1 )
throw new \Exception("@repo is not a non-empty string");
/* (2) Check @method */
if( !is_string($method) || strlen($method) < 1 )
throw new \Exception("@method is not a non-empty string");
/* (3) Check class path */
$class_path = "\\database\\repo\\$repo";
if( !\class_exists($class_path) )
throw new \Exception("Repo class '$class_path' cannot be found");
/* (2) Call the method
---------------------------------------------------------*/
/* (1) Create the instance (pre-script) */
$instance = new $class_path();
/* (2) Check extends Repo_i */
if( !( $instance instanceof Repo_i ) )
throw new \Exception("Repo class '$class_path' must extends Repo_i");
/* (3) Bind pdo instance */
\call_user_func([$instance, 'setPDO'], self::$driver->pdo());
/* (3) Check if the method exists */
if( !\method_exists($instance, $method) )
throw new \Exception("Repo '$repo' has no public method '$method'");
/* (4) Fetch response (send arguments as well) */
$response = call_user_func_array([$instance, $method], array_slice(func_get_args(), 2));
/* (5) Call post-script */
$instance = null;
/* (6) Dispatch response */
return $response;
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace database\core;
class Repo_i{
/**
* @var \PDO
*/
protected $pdo = null;
public function setPDO( \PDO $pdo){
$this->pdo = $pdo;
}
}

View File

@ -63,6 +63,8 @@
const WrongParam = 17;
/* (12) Erreur dans le traitement */
const ModuleError = 18;
/* (13) URI Invalide */
const InvalidURI = 19;
/* [5] Database
@ -70,40 +72,50 @@
/* (1) Base de données
---------------------------------------------------------*/
/* (1) Erreur lors de la creation d'un objet PDO (connection) */
const PDOConnection = 19;
const PDOConnection = 20;
/* (2) Repositories
---------------------------------------------------------*/
/* (1) Verification de la coherence du chemin (existe dans la conf) */
const WrongPathRepo = 20;
const WrongPathRepo = 21;
/* (2) Module non specifie dans la conf */
const UnknownRepo = 21;
const UnknownRepo = 22;
/* (3) Erreur dans le traitement */
const RepoError = 22;
const RepoError = 23;
/* (3) ORM
---------------------------------------------------------*/
/* (1) Table n'existe pas */
const UnknownTable = 23;
const UnknownTable = 24;
/* (2) Pas permissions de lire le schéma */
const NotAllowedSchema = 24;
const NotAllowedSchema = 25;
/* [6] Erreurs diverses
=========================================================*/
/* (1) Aucune donnée trouvée */
const NoMatchFound = 25;
const NoMatchFound = 26;
/* (2) Mauvais chemin de template */
const UnknownTemplate = 26;
const UnknownTemplate = 27;
/* (3) géolocalisation échouée */
const UnknownAddress = 27;
const UnknownAddress = 28;
/* (4) Erreur inconnue */
const UnknownError = 28;
const UnknownError = 29;
/* (5) Entrée existante */
const AlreadyExists = 30;
/* (6) Corps manquant */
const MissingBody = 31;
/* (7) Header manquant */
const MissingHeaders = 32;
}
?>

View File

@ -78,6 +78,7 @@
case Err::MissingParam: return $this->MissingParam(); break;
case Err::WrongParam: return $this->WrongParam(); break;
case Err::ModuleError: return $this->ModuleError(); break;
case Err::InvalidURI: return $this->InvalidURI(); break;
case Err::PDOConnection: return $this->PDOConnection(); break;
case Err::WrongPathRepo: return $this->WrongPathRepo(); break;
case Err::UnknownRepo: return $this->UnknownRepo(); break;
@ -88,6 +89,9 @@
case Err::UnknownTemplate: return $this->UnknownTemplate(); break;
case Err::UnknownAddress: return $this->UnknownAddress(); break;
case Err::UnknownError: return $this->UnknownError(); break;
case Err::AlreadyExists: return $this->AlreadyExists(); break;
case Err::MissingBody: return $this->MissingBody(); break;
case Err::MissingHeaders: return $this->MissingHeaders(); break;
default: return $this->UnknownDebugError(); break;
}
@ -110,7 +114,10 @@
}private function TokenError(){
return 'bad or expired token';
}private function PermissionError(){
return 'permission error';
if( count($this->arguments) > 0 )
return "missing permission: '".$this->arguments[0]."'";
else
return 'permission error';
}private function DisabledModule(){
return 'disabled module';
}private function MissingPath(){
@ -155,7 +162,12 @@
else
return 'wrong param';
}private function ModuleError(){
return 'module error';
if( count($this->arguments) > 0 )
return 'module error: \''.$this->arguments[0].'\'';
else
return 'module error';
}private function InvalidURI(){
return 'invalid URI';
}private function PDOConnection(){
return 'database error';
}private function WrongPathRepo(){
@ -176,6 +188,12 @@
return 'unknown';
}private function UnknownError(){
return 'unknown error';
}private function AlreadyExists(){
return 'item already exists';
}private function MissingBody(){
return 'body is missing';
}private function MissingHeaders(){
return 'headers are missing';
}private function UnknownDebugError(){
return 'unknown debug error';
}

1121
src/packages/orm/0.8.3/core/Rows.php vendored Executable file

File diff suppressed because it is too large Load Diff

385
src/packages/orm/0.8.3/core/SQLBuilder.php vendored Executable file
View File

@ -0,0 +1,385 @@
<?php
namespace orm\core;
use \database\core\DatabaseDriver;
use \orm\core\Rows;
class SQLBuilder{
/* CONSTRUIT LA REQUETE FORMATTEE "SELECT" AVEC UNE LISTE DE CHAMPS
*
* @sqlFields<Array> Liste de champs : [table => field => [func, alias] ]
*
* @return sql<Array> Renvoie un tableau formatté
*
*/
public static function SELECT($sqlFields){
return $sqlFields;
}
/* CONSTRUIT LA REQUETE FORMATTEE "ORDER BY" AVEC UNE LISTE DE CHAMPS
*
* @tables<Array> Liste de champs : [table => fields]
*
* @return sql<Array> Renvoie un tableau formatté
*
*/
public static function ORDERBY($tables){
return $tables;
}
/* CONSTRUIT LA REQUETE FORMATTEE "GROUP BY" AVEC UNE LISTE DE CHAMPS
*
* @tables<Array> Liste de champs : [table => fields]
*
* @return sql<Array> Renvoie un tableau formatté
*
*/
public static function GROUPBY($tables){
return $tables;
}
/* CONSTRUIT LA REQUETE FORMATTEE "FROM" AVEC UNE LISTE DE TABLES
*
* @tables<Array> Liste de tables OU SQL PUR
*
* @return sql<Array> Renvoie un tableau formatté
*
*/
public static function FROM($tables){
return $tables;
}
/* CONSTRUIT LA REQUETE FORMATTEE "UPDATE" AVEC LA TABLE EN QUESTION
*
* @table<String> Table en question
*
* @return sql<Array> Renvoie un tableau formatté
*
*/
public static function UPDATE($table){
return $table;
}
/* CONSTRUIT LA REQUETE FORMATTEE "DELETE" AVEC LA TABLE EN QUESTION
*
* @table<String> Table en question
*
* @return sql<Array> Renvoie un tableau formatté
*
*/
public static function DELETE($table){
return $table;
}
/* CONSTRUIT LA REQUETE TEXTUELLE "IN" AVEC UNE LISTE DE TABLES
*
* @field<Array> Tableau contenant [table, field]
* @array<Array> Valeurs de la clause IN
* @offset<int> Permet de rendre la condition unique (nommage des variables)
* @bound<Arary> Tableau associatif contenant les variables "bindés" -> ajout des champs
*
* @return sql<String> Renvoie le textuel formatté
*
*/
public static function IN($field, $array, $offset=0, &$bound){
/* [0] Initialisation
=========================================================*/
$sql = '';
/* [1] On construit la requête
=========================================================*/
/* (1) Champ */
$sql .= $field[0].'.'.$field[1].' IN (';
/* (2) Valeurs */
$c = 0;
foreach($array as $i=>$value){
if( $c > 0 ) $sql .= ', ';
$sql .= ':'.$field[0].'_x_'.$field[1].'_'.$offset.'_'.$i;
$bound[':'.$field[0].'_x_'.$field[1].'_'.$offset.'_'.$i] = $value;
$c++;
}
return $sql.")";
} /* CONSTRUIT LA REQUETE TEXTUELLE "WHERE" AVEC UNE LISTE DE TABLES
*
* @field<Array> Tableau contenant [table, field]
* @valeur<Array> Valeurs de la clause WHERE [valeur, opérateur]
* @offset<int> Permet de rendre la condition unique (nommage des variables)
* @bound<Arary> Tableau associatif contenant les variables "bindés" -> ajout des champs
*
* @return sql<String> Renvoie le textuel formatté
*
*/
public static function WHERE($field, $value, $offset=0, &$bound){
/* [0] Initialisation
=========================================================*/
$sql = '';
/* [1] On construit la requête
=========================================================*/
/* (1) Chamo */
$sql .= $field[0].'.'.$field[1].' ';
/* (2) Opérateur */
$sql .= substr($value[1], 2, -2).' ';
/* (3) Variable */
// {1} Si NULL //
if( is_null($value[0]) ){
$sql .= 'NULL';
return $sql;
}
// {2} Si not NULL //
$sql .= ':'.$field[0].'_x_'.$field[1].'_'.$offset;
$bound[':'.$field[0].'_x_'.$field[1].'_'.$offset] = $value[0];
return $sql;
} /* CONSTRUIT LA REQUETE FORMATTEE "SET" AVEC UNE LISTE DE TABLES
*
* @values<Array> Tableau de la forme [ field=>value, field2=>value2 ]
* @bound<Arary> Tableau associatif contenant les variables "bindés" -> ajout des champs
*
* @return sql<Array> Renvoie un tableau formatté
*
*/
public static function SET($values, &$bound){
/* [0] Initialisation
=========================================================*/
$sql = [];
/* [1] On construit la requête
=========================================================*/
$c = 0;
foreach($values as $field=>$value){
/* (1) Champ */
$sql[$c] = $field.' = ';
/* (2) Variable */
// {1} Si NULL //
if( is_null($value) ){
$sql[$c] .= 'NULL';
$c++;
continue;
}
// {2} Si not NULL //
$sql[$c] .= ':update_'.$field;
$bound[':update_'.$field] = $value;
$c++;
}
return $sql;
} /* CONSTRUIT LA REQUETE FORMATTEE "LIMIT" AVEC UN NOMBRE D'ENTREES
*
* @count<int> Nombre limite
*
* @return sql<Array> Renvoie un sql formatté
*
*/
public static function LIMIT($count=null){
/* [0] Initialisation
=========================================================*/
$sql = '';
/* [1] On construit la requête
=========================================================*/
if( intval($count) == $count )
$sql = intval($count);
return $sql;
}
/* CONSTRUIT LA REQUETE A PARTIR D'UNE REQUETTE FORMATTEE
*
* @request<Arary> Requête formattée
*
* @return sql<String> Requête formattée en SQL
*
*/
public static function BUILD($request){
/* [0] On initialise le retour
=========================================================*/
$sql = '';
/* [1] Gestion dans l'ordre
=========================================================*/
foreach($request as $clause=>$statements){
switch($clause){
/* (1) Clause SELECT
---------------------------------------------------------*/
case 'SELECT':
$sql .= "SELECT ";
$c = 0;
foreach($statements as $table=>$fields){
foreach($fields as $field=>$select){
/* (1) On construit le nom du champ */
$fieldStr = "$table.$field";
/* (2) On ajout le DISTINCT s'il y a lieu */
if( isset($select[1]) && $select[1] )
$fieldStr = "DISTINCT $fieldStr";
/* (3) On ajoute la fonction d'aggrégation s'il y a lieu */
if( isset($select[0]) && !is_null($select[0]) )
$fieldStr = substr($select[0], 2, -2)."($fieldStr)";
/* (4) On ajoute l'alias */
// si défini
if( isset($select[2]) )
$fieldStr = "$fieldStr as ".$select[2];
// si func et non défini
elseif( isset($select[0]) && !is_null($select[0]) )
$fieldStr = "$fieldStr as agg_$field";
else
$fieldStr = "$fieldStr";
$sql .= ($c==0) ? "$fieldStr" : ", $fieldStr";
$c++;
}
}
$sql .= "\n";
break;
/* (2) Clause FROM
---------------------------------------------------------*/
case 'FROM':
$sql .= 'FROM ';
$c = 0;
foreach($statements as $field){
$sql .= ($c==0) ? "$field" : ", $field";
$c++;
}
$sql .= "\n";
break;
/* (3) Clause WHERE
---------------------------------------------------------*/
case 'WHERE':
$c = 0;
foreach($statements as $field){
$sql .= ($c==0) ? "WHERE $field\n" : "AND $field\n";
$c++;
}
$sql .= ($c==0) ? '' : "\n";
break;
/* (4) Clause LIMIT
---------------------------------------------------------*/
case 'LIMIT':
if( is_numeric($statements) )
$sql .= 'LIMIT '.intval($statements);
break;
/* (5) Clause DELETE
---------------------------------------------------------*/
case 'DELETE':
$sql .= "DELETE FROM $statements\n";
break;
/* (6) Clause UPDATE
---------------------------------------------------------*/
case 'UPDATE':
$sql .= "UPDATE $statements\n";
break;
/* (7) Clause SET
---------------------------------------------------------*/
case 'SET':
$c = 0;
foreach($statements as $field){
$sql .= ($c>0) ? "\n, $field" : "SET $field";
$c++;
}
$sql .= "\n";
break;
/* (8) Clause GROUP BY
---------------------------------------------------------*/
case 'GROUPBY':
$sql .= 'GROUP BY ';
$c = 0;
foreach($statements as $table=>$fields)
foreach($fields as $field){
$sql .= ($c==0) ? "$table.$field" : ", $table.$field";
$c++;
}
$sql .= "\n";
break;
/* (9) Clause ORDER BY
---------------------------------------------------------*/
case 'ORDERBY':
// si aucun ORDER BY, on quitte
if( count($statements) == 0 )
continue;
$sql .= 'ORDER BY ';
$c = 0;
foreach($statements as $table=>$fields)
foreach($fields as $field=>$order){
if( $c > 0 ) $sql .= ', ';
$sql .= "$table.$field ". substr($order, 2, -2);
$c++;
}
$sql .= "\n";
break;
}
}
/* [2] On retourne le résultat
=========================================================*/
return $sql;
}
}
?>

193
src/packages/orm/0.8.3/core/Table.php vendored Executable file
View File

@ -0,0 +1,193 @@
<?php
namespace orm\core;
use \database\core\DatabaseDriver;
use \error\core\Error;
use \orm\core\Rows;
// CLASSE MAITRE
class Table{
/* RENVOIE LES DONNEES D'UNE TABLE
*
* @table<String> Nom de la table à selectionner
* @driver<String> [optional] DatabaseDriver label
*
* @return this<ORM> Retourne une instance de l'ORM
*
*/
public static function get($table_name, $driver=null){
/* [0] Initialisation des attributs
=========================================================*/
$schema = [
'database' => DatabaseDriver::get($driver)->getConfig()['dbname'],
'table' => null,
'columns' => null
];
/* [1] On vérifie que la table existe
=========================================================*/
/* (1) Requête */
$checkTable = DatabaseDriver::getPDO($driver)->query("SHOW tables FROM ".$schema['database']);
$checkTableResult = DatabaseDriver::delNumeric( $checkTable->fetchAll() );
/* (2) On met en forme les données */
$tables = [];
foreach($checkTableResult as $table)
$tables[] = $table['Tables_in_'.$schema['database']];
/* (3) Si n'existe pas, on renvoie une erreur */
if( !in_array($table_name, $tables) )
return null;
/* (4) On enregistre les données */
$schema['table'] = $table_name;
/* [2] Si la table existe, on récupère les colonnes
=========================================================*/
/* (1) On récupère les colonnes */
$getColumns = DatabaseDriver::getPDO($driver)->query("SHOW columns FROM ".$schema['database'].'.'.$table_name);
$columnsResult = DatabaseDriver::delNumeric( $getColumns->fetchAll() );
/* (2) On met en forme les données */
$columns = [];
foreach($columnsResult as $col){
// On formatte le type //
$type = $col['Type'];
if( preg_match('/^(int|float|varchar|text)/i', $type, $m) )
$type = strtolower($m[1]);
// On ajoute la colonne //
$columns[$col['Field']] = [
'type' => $type,
'primary' => $col['Key'] == 'PRI'
];
}
/* (3) Si on trouve rien, on envoie une erreur */
if( !is_array($columns) || count($columns) == 0 )
return null;
/* (4) On enregistre les colonnes */
$schema['columns'] = $columns;
/* [3] On récupère les clés étrangères
=========================================================*/
/* (1) On récupère le texte du 'CREATE TABLE' */
$getCreateTable = DatabaseDriver::getPDO($driver)->query("show create table ".$table_name);
$create_table = $getCreateTable->fetch()['Create Table'];
/* (2) On découpte en lignes */
$create_table_lines = explode("\n", $create_table);
/* (3) Pour chaque ligne, si c'est une contrainte, on l'enregistre dans la colonne associée */
foreach($create_table_lines as $i=>$line)
if( preg_match('/CONSTRAINT `.+` FOREIGN KEY \(`(.+)`\) REFERENCES `(.+)` \(`(.+)`\)+/i', $line, $m) )
$schema['columns'][$m[1]]['references'] = [$m[2], $m[3]];
/* [3] On renvoie une instance de 'Rows'
=========================================================*/
return new Rows($schema, $driver);
}
};
/*** USE CASE :: ACCESS TABLE `user` ***/
// ORM::Table('user');
/**** USE CASE :: WHERE ****/
// WHERE `username` = 'someUsername'
// ORM::Table('user')->whereUsername('someUsername');
// EQUIVALENT TO
// ORM::Table('user')->whereUsername('someUsername', Rows::COND_EQUAL);
// WHERE `id_user` < 100
// ORM::Table('user')->whereIdUser(100, Rows::COND_INF);
// WHERE `id_user` <= 100
// ORM::Table('user')->whereIdUser(100, Rows::COND_INFEQ);
// WHERE `id_user` > 10
// ORM::Table('user')->whereIdUser(10, Rows::COND_SUP);
// WHERE `id_user` >= 10
// ORM::Table('user')->whereIdUser(10, Rows::COND_SUPEQ);
// WHERE `id_user` in (1, 2, 3, 8)
// ORM::Table('user')->whereIdUser([1, 2, 3, 8], Rows::COND_IN);
// WHERE `id_user` LIKE 'John %'
// ORM::Table('user')->whereIdUser('John %', Rows::COND_LIKE);
/*** USE CASE :: ORDER BY ****/
// ORDER BY `a` ASC, `b` DESC
// Table::get('someTable')
// ->orderby('a', Rows::ORDER_ASC)
// ->orderby('b', Rows::ORDER_DESC);
//
// Note: `Rows::ORDER_ASC` is set by default if the given FLAG is invalid
/**** USE CASE :: SELECT ****/
// SELECT id_user, username
// Table::get('user')
// ->select('id_user')
// ->select('username');
/**** USE CASE :: AGGREGATION FUNCTIONS ****/
// SELECT COUNT(`count`)
// Table::get('user')->select('count', Rows::SEL_COUNT)
// SELECT SUM(distinct `count`)
// Table::get('user')->select('count', Rows::SEL_SUM, Rows::SEL_DISTINCT);
// SELECT AVG(`count`)
// Table::get('user')->select('count', Rows::SEL_AVG);
// SELECT MAX(`id_user`)
// Table::get('user')->select('id_user', Rows::SEL_MAX);
// SELECT MIN(`id_user`)
// Table::get('user')->select('id_user', Rows::SEL_MIN);
// SELECT GROUP_CONCAT(`count`)
// Table::get('user')->select('count', Rows::SEL_CONCAT);
/**** USE CASE :: FETCH ****/
// SELECT ... FROM ... WHERE ... ORDERBY ... LIMIT ...
// Table::get('user')
// ->select('id_user')
// ->fetch();
// SELECT UNIQUE ... FROM ... WHERE ... ORDERBY ... LIMIT ...
// Table::get('user')
// ->select('id_user')
// ->unique->fetch();
/**** USE CASE :: TABLE JOIN ****/
// WHERE `user`.`id_user` = `user_merge`.`id_user`
// Table::get('user_merge')->join(
// Table::get('user')->whereIdUser(1, Rows::COND_SUP)
// );

View File

@ -0,0 +1,281 @@
<?php
namespace token\core;
class TreeToken{
private static $DEBUG = false;
private $secret = null;
private $step = 0;
private $max_step = 0;
private static $salt = '_9284 we;\'sa';
private static $pepper = 'dasklj3948\'3=2';
private $sync = null;
/* (1) Constructs a new TreeToken
*
* @max_step<int> Max. number of children tokens
*
---------------------------------------------------------*/
public function __construct($max_step=100){
/* (1) Check argument */
if( abs(intval($max_step)) !== $max_step || $max_step < 0 )
throw new \Exception('Invalid argument type.');
/* (2) Manage session */
if( session_status() != PHP_SESSION_ACTIVE )
\session_start();
/* (3) Set attributes */
$this->max_step = $max_step+1;
}
/* (2) Gets the existing parent
*
* @return status<bool> TRUE: right parent + token
* FALSE: Invalid token
* NULL: No parent found
*
---------------------------------------------------------*/
private function check_parent(){
/* (1) Check system state
---------------------------------------------------------*/
$has_token = isset($_COOKIE['_PUBLIC_']) && preg_match( '/^[a-z0-9]{128}$/i', $_COOKIE['_PUBLIC_'] );
$has_parent = isset($_SESSION['_PRIVATE_']) && preg_match( '/^([a-z0-9]{128})\.(\d+)$/i', $_SESSION['_PRIVATE_'], $p_match );
/* (1) If no parent -> NULL */
if( !$has_parent )
return null;
/* (2) But if no token -> FALSE */
if( !$has_token )
return false;
if( self::$DEBUG ){
echo "* PARENT RECEIVED *\n";
echo 'sess_id: '.session_id()."\n";
echo 'pub: '.$_COOKIE['_PUBLIC_']."\n";
echo 'priv: '.$_SESSION['_PRIVATE_']."\n";
}
/* (2) Check parent token
---------------------------------------------------------*/
/* (1) Check public token */
if( self::tgen($p_match[1], $this->max_step) !== $_COOKIE['_PUBLIC_'] ){
if( self::$DEBUG )
echo "<b>/!\ invalid parent pub (token)</b>\n";
return false;
}
/* (2) Inherit parent properties */
$this->secret = $p_match[1];
$this->step = $p_match[2];
/* (3) If valid token */
if( self::$DEBUG )
echo "[ <b>Valid parent pub (token)</b> ]\n";
return true;
}
/* (3) Create or regenerate a parent
*
* @inName<inType> inDesc
*
* @return outName<outType> outDesc
*
---------------------------------------------------------*/
public function init_parent(){
/* (1) Check parent
---------------------------------------------------------*/
/* (1) Process check */
$valid_parent = $this->check_parent();
/* (2) If invalid parent -> destroy session */
if( $valid_parent === false ){
if( self::$DEBUG )
echo "-> new session <-\n";
\session_regenerate_id(true); // true: delete old session
\session_unset();
\session_destroy();
\session_start();
}
/* (2) Init new parent
---------------------------------------------------------*/
/* (1) Choose new secret */
$this->secret = self::tgen(uniqid());
/* (2) Set step = max */
$this->step = $this->max_step;
/* (3) Generate PRIVATE */
$_SESSION['_PRIVATE_'] = $this->secret.'.'.$this->max_step;
/* (4) Generate PUBLIC */
$_COOKIE['_PUBLIC_'] = self::tgen($this->secret, $this->max_step);
setcookie('_PUBLIC_', $_COOKIE['_PUBLIC_'], time()+30*60, '/');
if( self::$DEBUG ){
echo "\n* PARENT UPDATED *\n";
echo 'sess_id: '.session_id()."\n";
echo 'pub: '.$_COOKIE['_PUBLIC_']."\n";
echo 'priv: '.$_SESSION['_PRIVATE_']."\n";
}
/* (5) Granted */
return $valid_parent !== false;
}
/* (4) Checks a child
*
* @return status<bool> TRUE: Valid child
* FALSE: Invalid token
*
---------------------------------------------------------*/
private function check_child(){
/* (1) Check the parent
---------------------------------------------------------*/
/* (1) Process parent check */
$valid_parent = $this->check_parent();
/* (2) Manage missing OR invalid parent */
if( $valid_parent !== true )
return false;
/* (2) Check system state
---------------------------------------------------------*/
$has_token = isset($_SERVER['PHP_AUTH_DIGEST']) && preg_match( '/^[a-z0-9]{128}$/i', $_SERVER['PHP_AUTH_DIGEST'] );
/* (1) If no token -> false */
if( !$has_token )
return false;
/* (3) Check child token
---------------------------------------------------------*/
/* (1) If no more steps -> false */
if( $this->step <= 1 ){
if( self::$DEBUG )
echo "<b>/!\ no more token available</b>\n";
return false;
}
if( self::$DEBUG ){
echo "* CHILD RECEIVED *\n";
echo 'sess_id: '.session_id()."\n";
echo 'token: '.$_SERVER['PHP_AUTH_DIGEST']."\n";
echo 'priv: '.$this->secret.'.'.$this->step."\n";
}
/* (2) Check child token */
if( self::tgen($this->secret, $this->step) !== $_SERVER['PHP_AUTH_DIGEST'] ){
if( self::$DEBUG )
echo "<b>/!\ invalid child token</b>\n";
return false;
}
/* (3) If valid token */
if( self::$DEBUG )
echo "[ <b>Valid child token</b> ]\n";
return true;
}
/* (5) Updates a child
*
* @inName<inType> inDesc
*
* @return outName<outType> outDesc
*
---------------------------------------------------------*/
public function init_child(){
/* (1) Check child
---------------------------------------------------------*/
/* (1) Process check */
$valid_child = $this->check_child();
/* (2) If invalid child -> destroy session */
if( $valid_child !== true )
return false;
/* (2) Update parent for other children
---------------------------------------------------------*/
/* (1) Decrement step */
$this->step--;
if( $this->step > 1 ){ // only if it is not the last step
/* (2) Update step in session */
$_SESSION['_PRIVATE_'] = $this->secret.'.'.$this->step;
/* (3) Generate child-specific PUBLIC */
header('Authorization: '.self::tgen($this->secret, $this->step));
if( self::$DEBUG ){
echo "\n* CHILD UPDATED *\n";
echo 'sess_id: '.session_id()."\n";
echo 'token: '.$_SERVER['PHP_AUTH_DIGEST']."\n";
echo 'priv: '.$_SESSION['_PRIVATE_']."\n";
}
}
/* (2) Granted */
return true;
}
/* (x) Generates a pseudo-rdm token
*
* @data<String> Seed to use
* @depth<int> Token depth
*
* @return token<String> @data hashed @depth times
*
---------------------------------------------------------*/
private static function tgen($data, $depth=1){
/* (0) If depth < 1 -> depth=1 */
$depth = ( $depth < 1 ) ? 1 : $depth;
/* (1) Apply salt */
$hash = self::$salt.$data;
/* (2) Hash @depth times */
for( $d = 0 ; $d < $depth ; $d++ )
$hash = ( $d == $depth-1 ) ? hash('sha512', $hash.self::$pepper) : hash('sha512', $hash);
/* (3) Return hash */
return $hash;
}
}