Skip to content

Commit 78e1314

Browse files
committed
Add type sanitation
1 parent 3605953 commit 78e1314

File tree

8 files changed

+698
-156
lines changed

8 files changed

+698
-156
lines changed

README.md

Lines changed: 54 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -652,10 +652,13 @@ You can tune the middleware behavior using middleware specific configuration par
652652
- "authorization.columnHandler": Handler to implement column authorization rules ("")
653653
- "authorization.recordHandler": Handler to implement record authorization filter rules ("")
654654
- "validation.handler": Handler to implement validation rules for input values ("")
655-
- "validation.types": List of types for which the default validation must take place ("all")
655+
- "validation.types": Types to enable type validation for, empty means 'none' ("all")
656+
- "validation.tables": Tables to enable type validation for, empty means 'none' ("all")
656657
- "ipAddress.tables": Tables to search for columns to override with IP address ("")
657658
- "ipAddress.columns": Columns to protect and override with the IP address on create ("")
658659
- "sanitation.handler": Handler to implement sanitation rules for input values ("")
660+
- "sanitation.types": Types to enable type sanitation for, empty means 'none' ("all")
661+
- "sanitation.tables": Tables to enable type sanitation for, empty means 'none' ("all")
659662
- "multiTenancy.handler": Handler to implement simple multi-tenancy rules ("")
660663
- "pageLimits.pages": The maximum page number that a list operation allows ("100")
661664
- "pageLimits.records": The maximum number of records returned by a list operation ("1000")
@@ -887,14 +890,28 @@ the 'sanitation' middleware and define a 'sanitation.handler' function that retu
887890

888891
The above example will strip all HTML tags from strings in the input.
889892

890-
### Validating input
893+
### Type sanitation
894+
895+
If you enable the 'sanitation' middleware, then you (automtically) also enable type sanitation. When this is enabled you may:
896+
897+
- send leading and trailing whitespace (it will be ignored).
898+
- send a float to an integer field (it will be rounded).
899+
- send a base64url encoded (it will be converted to regular base64 encoding).
900+
- send a time/date/timestamp in any strtotime accepted format (it will be converted).
891901

892-
By default all input is accepted unless the validation middleware is specified. The default types validations are then applied.
902+
You may use the config settings "`sanitation.types`" and "`sanitation.tables`"' to define for which types and
903+
in which tables you want to apply type sanitation (defaults to 'all'). Example:
893904

894-
#### Validation handler
905+
'sanitation.types' => 'date,timestamp',
906+
'sanitation.tables' => 'posts,comments',
895907

896-
If you want to validate the input in a custom way, you may add the 'validation' middleware and define a 'validation.handler'
897-
function that returns a boolean indicating whether or not the value is valid.
908+
Here we enable the type sanitation for date and timestamp fields in the posts and comments tables.
909+
910+
### Validating input
911+
912+
By default all input is accepted and sent to the database. If you want to validate the input in a custom way,
913+
you may add the 'validation' middleware and define a 'validation.handler' function that returns a boolean
914+
indicating whether or not the value is valid.
898915

899916
'validation.handler' => function ($operation, $tableName, $column, $value, $context) {
900917
return ($column['name'] == 'post_id' && !is_numeric($value)) ? 'must be numeric' : true;
@@ -920,9 +937,10 @@ Then the server will return a '422' HTTP status code and nice error message:
920937

921938
You can parse this output to make form fields show up with a red border and their appropriate error message.
922939

923-
#### Validation types
940+
### Type validations
924941

925-
The default types validations return the following error messages:
942+
If you enable the 'validation' middleware, then you (automtically) also enable type validation.
943+
This includes the following error messages:
926944

927945
| error message | reason | applies to types |
928946
| ------------------- | --------------------------- | ------------------------------------------- |
@@ -940,18 +958,13 @@ The default types validations return the following error messages:
940958
| invalid timestamp | use yyyy-mm-dd hh:mm:ss | timestamp |
941959
| invalid base64 | illegal characters | varbinary, blob |
942960

943-
If you want the types validation to apply to all the types, you must activate the "`validation`" middleware.
944-
By default, all types are enabled. Which is equivalent to the two configuration possibilities:
945-
946-
'validation.types' => 'all',
947-
948-
or
949-
950-
'validation.types'=> 'integer,bigint,varchar,decimal,float,double,boolean,date,time,timestamp,clob,blob,varbinary,geometry',
961+
You may use the config settings "`validation.types`" and "`validation.tables`"' to define for which types and
962+
in which tables you want to apply type validation (defaults to 'all'). Example:
951963

952-
In case you want to use a validation handler but don't want any types validation, use:
964+
'validation.types' => 'date,timestamp',
965+
'validation.tables' => 'posts,comments',
953966

954-
'validation.types' => '',
967+
Here we enable the type validation for date and timestamp fields in the posts and comments tables.
955968

956969
NB: Types that are enabled will be checked for null values when the column is non-nullable.
957970

@@ -1058,41 +1071,30 @@ in case that you use a non-default "cacheType" the hostname (optionally with por
10581071

10591072
## Types
10601073

1061-
These are the supported types with their default length/precision/scale:
1062-
1063-
character types
1064-
- varchar(255)
1065-
- clob
1066-
1067-
boolean types:
1068-
- boolean
1069-
1070-
integer types:
1071-
- integer
1072-
- bigint
1073-
1074-
floating point types:
1075-
- float
1076-
- double
1077-
1078-
decimal types:
1079-
- decimal(19,4)
1080-
1081-
date/time types:
1082-
- date
1083-
- time
1084-
- timestamp
1085-
1086-
binary types:
1087-
- varbinary(255)
1088-
- blob
1089-
1090-
other types:
1091-
- geometry /* non-jdbc type, extension with limited support */
1074+
These are the supported types with their length, category, JSON type and format:
1075+
1076+
| type | length | category | JSON type | format |
1077+
| ---------- | ------ | --------- | --------- | ------------------- |
1078+
| varchar | 255 | character | string | |
1079+
| clob | | character | string | |
1080+
| boolean | | boolean | boolean | |
1081+
| integer | | integer | number | |
1082+
| bigint | | integer | number | |
1083+
| float | | float | number | |
1084+
| double | | float | number | |
1085+
| decimal | 19,4 | decimal | string | |
1086+
| date | | date/time | string | yyyy-mm-dd |
1087+
| time | | date/time | srting | hh:mm:ss |
1088+
| timestamp | | date/time | string | yyyy-mm-dd hh:mm:ss |
1089+
| varbinary | 255 | binary | string | base64 encoded |
1090+
| blob | | binary | string | base64 encoded |
1091+
| geometry | | other | string | well-known text |
1092+
1093+
Note that geometry is a non-jdbc type and thus has limited support.
10921094

10931095
## Data types in JavaScript
10941096

1095-
Javascript and Javascript object notation are not very well suited for reading database records. Decimal, date/time, binary and geometry types are represented as strings in JSON (binary is base64 encoded, geometries are in WKT format). Below are two more serious issues described.
1097+
Javascript and Javascript object notation (JSON) are not very well suited for reading database records. Decimal, date/time, binary and geometry types must be represented as strings in JSON (binary is base64 encoded, geometries are in WKT format). Below are two more serious issues described.
10961098

10971099
### 64 bit integers
10981100

@@ -1147,7 +1149,7 @@ I am testing mainly on Ubuntu and I have the following test setups:
11471149
- (Docker) Debian 9 with PHP 7.0, MariaDB 10.1, PostgreSQL 9.6 (PostGIS 2.3) and SQLite 3.16
11481150
- (Docker) Ubuntu 18.04 with PHP 7.2, MySQL 5.7, PostgreSQL 10.4 (PostGIS 2.4) and SQLite 3.22
11491151
- (Docker) Debian 10 with PHP 7.3, MariaDB 10.3, PostgreSQL 11.4 (PostGIS 2.5) and SQLite 3.27
1150-
- (Docker) Ubuntu 20.04 with PHP 7.3, MySQL 8.0, PostgreSQL 12.2 (PostGIS 3.0) and SQLite 3.31
1152+
- (Docker) Ubuntu 20.04 with PHP 7.4, MySQL 8.0, PostgreSQL 12.2 (PostGIS 3.0) and SQLite 3.31
11511153
- (Docker) CentOS 8 with PHP 7.4, MariaDB 10.4, PostgreSQL 12.2 (PostGIS 3.0) and SQLite 3.26
11521154

11531155
This covers not all environments (yet), so please notify me of failing tests and report your environment.
@@ -1262,7 +1264,7 @@ To run the docker tests run "build_all.sh" and "run_all.sh" from the docker dire
12621264
sqlsrv: skipped, driver not loaded
12631265
sqlite: 105 tests ran in 1063 ms, 12 skipped, 0 failed
12641266
================================================
1265-
Ubuntu 20.04 (PHP 7.3)
1267+
Ubuntu 20.04 (PHP 7.4)
12661268
================================================
12671269
[1/4] Starting MySQL 8.0 ........ done
12681270
[2/4] Starting PostgreSQL 12.2 .. done

0 commit comments

Comments
 (0)