Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
anis
anis-server
Commits
63f88730
Commit
63f88730
authored
Apr 19, 2019
by
François Agneray
Browse files
Add encryption key (metamodel database password)
parent
de086636
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/Action/Meta/DatabaseAction.php
View file @
63f88730
...
...
@@ -24,11 +24,13 @@ final class DatabaseAction
private
$logger
;
private
$em
;
private
$encryptionKey
;
public
function
__construct
(
LoggerInterface
$logger
,
EntityManagerInterface
$em
)
public
function
__construct
(
LoggerInterface
$logger
,
EntityManagerInterface
$em
,
string
$encryptionKey
)
{
$this
->
logger
=
$logger
;
$this
->
em
=
$em
;
$this
->
encryptionKey
=
$encryptionKey
;
}
public
function
__invoke
(
Request
$request
,
Response
$response
,
array
$args
):
Response
...
...
@@ -89,7 +91,7 @@ final class DatabaseAction
$database
->
setHost
(
$parsedBody
[
'dbhost'
]);
$database
->
setPort
(
$parsedBody
[
'dbport'
]);
$database
->
setLogin
(
$parsedBody
[
'dblogin'
]);
$database
->
setPassword
(
$parsedBody
[
'dbpassword'
]);
$database
->
setPassword
(
$
this
->
encryptData
(
$
parsedBody
[
'dbpassword'
])
)
;
$this
->
em
->
flush
();
}
}
src/Action/Meta/DatabaseListAction.php
View file @
63f88730
...
...
@@ -24,11 +24,13 @@ final class DatabaseListAction
private
$logger
;
private
$em
;
private
$encryptionKey
;
public
function
__construct
(
LoggerInterface
$logger
,
EntityManagerInterface
$em
)
public
function
__construct
(
LoggerInterface
$logger
,
EntityManagerInterface
$em
,
string
$encryptionKey
)
{
$this
->
logger
=
$logger
;
$this
->
em
=
$em
;
$this
->
encryptionKey
=
$encryptionKey
;
}
public
function
__invoke
(
Request
$request
,
Response
$response
,
array
$args
):
Response
...
...
@@ -74,7 +76,7 @@ final class DatabaseListAction
$database
->
setHost
(
$parsedBody
[
'dbhost'
]);
$database
->
setPort
(
$parsedBody
[
'dbport'
]);
$database
->
setLogin
(
$parsedBody
[
'dblogin'
]);
$database
->
setPassword
(
$parsedBody
[
'dbpassword'
]);
$database
->
setPassword
(
$
this
->
encryptData
(
$
parsedBody
[
'dbpassword'
])
)
;
$this
->
em
->
persist
(
$database
);
$this
->
em
->
flush
();
...
...
src/Action/Search/SearchDataAction.php
View file @
63f88730
...
...
@@ -56,6 +56,14 @@ final class SearchDataAction
* @var AnisQueryBuilderFactory
*/
private
$aqbf
;
/**
* The encryption key used by anis to encrypt and decrypt sensitive data like passwords
* This key is provided by configuration (see the config file)
*
* @var string
*/
private
$encryptionKey
;
/**
* This class is creates before call __invoke to execute the action
...
...
@@ -69,12 +77,14 @@ final class SearchDataAction
LoggerInterface
$logger
,
EntityManagerInterface
$em
,
DBALConnectionFactory
$dcf
,
AnisQueryBuilderFactory
$aqbf
AnisQueryBuilderFactory
$aqbf
,
string
$encryptionKey
)
{
$this
->
logger
=
$logger
;
$this
->
em
=
$em
;
$this
->
dcf
=
$dcf
;
$this
->
aqbf
=
$aqbf
;
$this
->
encryptionKey
=
$encryptionKey
;
}
/**
...
...
@@ -123,7 +133,8 @@ final class SearchDataAction
}
$database
=
$dataset
->
getProject
()
->
getDatabase
();
$connection
=
$this
->
dcf
->
create
(
$database
);
$decryptedPassword
=
$this
->
decryptData
(
$database
->
getPassword
());
$connection
=
$this
->
dcf
->
create
(
$database
,
$decryptedPassword
);
$queryBuilder
=
$connection
->
createQueryBuilder
();
$anisQueryBuilder
=
$this
->
aqbf
->
create
(
$queryBuilder
,
$dataset
);
...
...
src/Action/Search/SearchMetaAction.php
View file @
63f88730
...
...
@@ -56,6 +56,14 @@ final class SearchMetaAction
* @var AnisQueryBuilderFactory
*/
private
$aqbf
;
/**
* The encryption key used by anis to encrypt and decrypt sensitive data like passwords
* This key is provided by configuration (see the config file)
*
* @var string
*/
private
$encryptionKey
;
/**
* This class is creates before call __invoke to execute the action
...
...
@@ -69,12 +77,14 @@ final class SearchMetaAction
LoggerInterface
$logger
,
EntityManagerInterface
$em
,
DBALConnectionFactory
$dcf
,
AnisQueryBuilderFactory
$aqbf
AnisQueryBuilderFactory
$aqbf
,
string
$encryptionKey
)
{
$this
->
logger
=
$logger
;
$this
->
em
=
$em
;
$this
->
dcf
=
$dcf
;
$this
->
aqbf
=
$aqbf
;
$this
->
encryptionKey
=
$encryptionKey
;
}
/**
...
...
@@ -113,7 +123,8 @@ final class SearchMetaAction
}
$database
=
$dataset
->
getProject
()
->
getDatabase
();
$connection
=
$this
->
dcf
->
create
(
$database
);
$decryptedPassword
=
$this
->
decryptData
(
$database
->
getPassword
());
$connection
=
$this
->
dcf
->
create
(
$database
,
$decryptedPassword
);
$queryBuilder
=
$connection
->
createQueryBuilder
();
$anisQueryBuilder
=
$this
->
aqbf
->
create
(
$queryBuilder
,
$dataset
);
...
...
src/Utils/ActionTrait.php
View file @
63f88730
...
...
@@ -32,4 +32,21 @@ trait ActionTrait
'error_description'
=>
$error_description
)));
}
protected
function
encryptData
(
string
$data
):
string
{
// Generate an initialization vector
$iv
=
openssl_random_pseudo_bytes
(
openssl_cipher_iv_length
(
'aes-256-cbc'
));
// Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector.
$encrypted
=
openssl_encrypt
(
$data
,
'aes-256-cbc'
,
$this
->
encryptionKey
,
0
,
$iv
);
// The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)
return
base64_encode
(
$encrypted
.
'::'
.
$iv
);
}
protected
function
decryptData
(
string
$data
):
string
{
// To decrypt, split the encrypted data from our IV - our unique separator used was "::"
list
(
$encryptedData
,
$iv
)
=
explode
(
'::'
,
base64_decode
(
$data
),
2
);
return
openssl_decrypt
(
$encryptedData
,
'aes-256-cbc'
,
$this
->
encryptionKey
,
0
,
$iv
);
}
}
src/Utils/DBALConnectionFactory.php
View file @
63f88730
...
...
@@ -31,16 +31,17 @@ class DBALConnectionFactory
* the metamodel
*
* @param Database $database This object contains the database connection parameters
* @param string $decryptedPassword This string contains the decrypted password for the database connection
*
* @return Connection
*/
public
static
function
create
(
Database
$database
):
Connection
public
static
function
create
(
Database
$database
,
string
$decryptedPassword
):
Connection
{
$config
=
new
\
Doctrine\DBAL\Configuration
();
$connectionParams
=
array
(
'dbname'
=>
$database
->
getDbName
(),
'user'
=>
$database
->
getLogin
(),
'password'
=>
$d
atabase
->
get
Password
()
,
'password'
=>
$d
ecrypted
Password
,
'host'
=>
$database
->
getHost
(),
'port'
=>
$database
->
getPort
(),
'driver'
=>
$database
->
getType
(),
...
...
src/dependencies.php
View file @
63f88730
...
...
@@ -22,7 +22,7 @@ $container['em'] = function ($c) {
$settings
=
$c
->
get
(
'settings'
);
$metadata
=
$settings
[
'metadata'
];
$c
=
\
Doctrine\ORM\Tools\Setup
::
createAnnotationMetadataConfiguration
(
$metadata
[
'entity_path'
]
,
array
(
'src/Entity'
)
,
$metadata
[
'dev_mode'
]
);
$c
->
setProxyDir
(
$metadata
[
'path_proxy'
]);
...
...
@@ -130,11 +130,13 @@ $container['App\Action\Settings\OptionAction'] = function ($c) {
// Metamodel actions
$container
[
'App\Action\Meta\DatabaseListAction'
]
=
function
(
$c
)
{
return
new
App\Action\Meta\DatabaseListAction
(
$c
->
get
(
'logger'
),
$c
->
get
(
'em'
));
$settings
=
$c
->
get
(
'settings'
);
return
new
App\Action\Meta\DatabaseListAction
(
$c
->
get
(
'logger'
),
$c
->
get
(
'em'
),
$settings
[
'encryption_key'
]);
};
$container
[
'App\Action\Meta\DatabaseAction'
]
=
function
(
$c
)
{
return
new
App\Action\Meta\DatabaseAction
(
$c
->
get
(
'logger'
),
$c
->
get
(
'em'
));
$settings
=
$c
->
get
(
'settings'
);
return
new
App\Action\Meta\DatabaseAction
(
$c
->
get
(
'logger'
),
$c
->
get
(
'em'
),
$settings
[
'encryption_key'
]);
};
$container
[
'App\Action\Meta\TableListAction'
]
=
function
(
$c
)
{
...
...
@@ -223,9 +225,11 @@ $container['App\Action\Meta\UserAction'] = function ($c) {
// Search actions
$container
[
'App\Action\Search\SearchMetaAction'
]
=
function
(
$c
)
{
return
new
App\Action\Search\SearchMetaAction
(
$c
->
get
(
'logger'
),
$c
->
get
(
'em'
),
$c
->
get
(
'dcf'
),
$c
->
get
(
'aqbf'
));
$settings
=
$c
->
get
(
'settings'
);
return
new
App\Action\Search\SearchMetaAction
(
$c
->
get
(
'logger'
),
$c
->
get
(
'em'
),
$c
->
get
(
'dcf'
),
$c
->
get
(
'aqbf'
),
$settings
[
'encryption_key'
]);
};
$container
[
'App\Action\Search\SearchDataAction'
]
=
function
(
$c
)
{
return
new
App\Action\Search\SearchDataAction
(
$c
->
get
(
'logger'
),
$c
->
get
(
'em'
),
$c
->
get
(
'dcf'
),
$c
->
get
(
'aqbf'
));
$settings
=
$c
->
get
(
'settings'
);
return
new
App\Action\Search\SearchDataAction
(
$c
->
get
(
'logger'
),
$c
->
get
(
'em'
),
$c
->
get
(
'dcf'
),
$c
->
get
(
'aqbf'
),
$settings
[
'encryption_key'
]);
};
src/settings.php
View file @
63f88730
...
...
@@ -11,13 +11,14 @@
return
[
'settings'
=>
[
// app config
'encryption_key'
=>
'r3Q8C7LgIrRcTtI8I6EPzFwrDXJ4adgnGQ9V/pWVI8M='
,
// slim framework settings
'displayErrorDetails'
=>
(
bool
)
getenv
(
'SLIM_DISPLAY_ERROR_DETAILS'
),
'determineRouteBeforeAppMiddleware'
=>
false
,
'addContentLengthHeader'
=>
false
,
// Allow the web server to send the content-length header
// metadata settings (doctrine 2)
'metadata'
=>
[
'entity_path'
=>
[
'src/Entity'
],
'path_proxy'
=>
getenv
(
'METADATA_DOCTRINE_PATH_PROXY'
),
'dev_mode'
=>
getenv
(
'METADATA_DOCTRINE_DEV_MODE'
),
'connection_options'
=>
[
...
...
@@ -32,7 +33,7 @@ return [
],
// monolog settings
'logger'
=>
[
'name'
=>
getenv
(
'LOGGER_NAME'
),
'name'
=>
getenv
(
'LOGGER_NAME'
),
'path'
=>
getenv
(
'LOGGER_PATH'
),
'level'
=>
getenv
(
'LOGGER_LEVEL'
)
],
...
...
@@ -40,14 +41,6 @@ return [
'mailer'
=>
[
'host'
=>
getenv
(
'MAILER_HOST'
),
'port'
=>
getenv
(
'MAILER_PORT'
)
],
'anis'
=>
[
'search_modules'
=>
[
'criteria'
,
'from'
,
'order'
,
'select'
]
]
]
];
tests/Action/Meta/DatabaseActionTest.php
View file @
63f88730
...
...
@@ -10,7 +10,8 @@ final class DatabaseActionTest extends AbstractActionTestCase
parent
::
setUp
();
$this
->
action
=
new
\
App\Action\Meta\DatabaseAction
(
new
\
Psr\Log\NullLogger
(),
$this
->
entityManager
$this
->
entityManager
,
base64_decode
(
'r3Q8C7LgIrRcTtI8I6EPzFwrDXJ4adgnGQ9V/pWVI8M='
)
);
}
...
...
@@ -102,7 +103,9 @@ final class DatabaseActionTest extends AbstractActionTestCase
$request
=
$this
->
getRequestForPut
(
$editedDatabase
);
$response
=
(
$this
->
action
)(
$request
,
new
\
Slim\Http\Response
(),
array
(
'id'
=>
1
));
$this
->
assertEquals
(
200
,
(
int
)
$response
->
getStatusCode
());
$this
->
assertSame
((
string
)
$response
->
getBody
(),
json_encode
(
$editedDatabase
));
$arrayResponse
=
json_decode
((
string
)
$response
->
getBody
(),
true
);
$arrayResponse
[
'dbpassword'
]
=
'password'
;
$this
->
assertSame
(
$arrayResponse
,
$editedDatabase
);
$this
->
assertSame
(
2
,
$this
->
getDatabaseTester
()
->
getConnection
()
->
getRowCount
(
'database'
));
}
...
...
tests/Action/Meta/DatabaseListActionTest.php
View file @
63f88730
...
...
@@ -10,7 +10,8 @@ final class DatabaseListActionTest extends AbstractActionTestCase
parent
::
setUp
();
$this
->
action
=
new
\
App\Action\Meta\DatabaseListAction
(
new
\
Psr\Log\NullLogger
(),
$this
->
entityManager
$this
->
entityManager
,
base64_decode
(
'r3Q8C7LgIrRcTtI8I6EPzFwrDXJ4adgnGQ9V/pWVI8M='
)
);
}
...
...
@@ -77,7 +78,9 @@ final class DatabaseListActionTest extends AbstractActionTestCase
$request
=
$this
->
getRequestForPost
(
$newDatabase
);
$response
=
(
$this
->
action
)(
$request
,
new
\
Slim\Http\Response
(),
array
());
$this
->
assertEquals
(
201
,
(
int
)
$response
->
getStatusCode
());
$this
->
assertSame
((
string
)
$response
->
getBody
(),
json_encode
(
array_merge
(
array
(
'id'
=>
3
),
$newDatabase
)));
$arrayResponse
=
json_decode
((
string
)
$response
->
getBody
(),
true
);
$arrayResponse
[
'dbpassword'
]
=
'password'
;
$this
->
assertSame
(
$arrayResponse
,
array_merge
(
array
(
'id'
=>
3
),
$newDatabase
));
$this
->
assertSame
(
3
,
$this
->
getDatabaseTester
()
->
getConnection
()
->
getRowCount
(
'database'
));
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment