diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 45e5fd67fe1055a03f7f5daeca663cdbf47ddf96..80e43de02e6b333441c54db6298fa4dd3888e8ed 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,8 +21,8 @@ before_script: - sed 's!<server>.*</server>!<server>postgres</server>!;s!<password>.*</password>!<password>maarch</password>!;s!<name>.*</name>!<name>MaarchParapheur</name>!;s!<user>.*</user>!<user>maarch</user>!;s!<enable>.*</enable>!<enable>true</enable>!' config/config.xml.default > config/config.xml - sed -i 's/rights="none" pattern="PDF"/rights="read | write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml -job_php-7.4: - image: php:7.4-apache +job_php-8.1: + image: php:8.1-apache stage: test services: - name: postgres:10.1 @@ -30,18 +30,22 @@ job_php-7.4: script: - curl --location -s --output /usr/local/bin/phpunit https://phar.phpunit.de/phpunit-9.phar - chmod +x /usr/local/bin/phpunit - - phpunit --coverage-text --colors=never -c phpunit.xml - only: - - develop - except: - - schedules + - phpunit --coverage-text --colors=never + # only: + # - develop + # except: + # - schedules + rules: + - if: '$CI_COMMIT_BRANCH =~ /(feat|fix)\/[0-9]{4,5}\/develop/' + artifacts: paths: - test/unitTests/build/ expire_in: 2h + # coverage: '^\s*Lines:\s*\d+.\d+\%' -job_php-7.3: - image: php:7.3-apache +job_php-8.0: + image: php:8.0-apache stage: test services: - name: postgres:10.1 @@ -50,90 +54,118 @@ job_php-7.3: - curl --location -s --output /usr/local/bin/phpunit https://phar.phpunit.de/phpunit-9.phar - chmod +x /usr/local/bin/phpunit - phpunit --coverage-text --colors=never + # only: + # - develop + # except: + # - schedules + rules: + - if: '$CI_COMMIT_BRANCH =~ /(feat|fix)\/[0-9]{4,5}\/develop/' + artifacts: + paths: + - test/unitTests/build/ + expire_in: 2h + # coverage: '^\s*Lines:\s*\d+.\d+\%' + +job_php-7.4: + image: php:7.4-apache + stage: test + services: + - name: postgres:10.1 + command: [ "-c", "datestyle=iso,dmy" ] + script: + - curl --location -s --output /usr/local/bin/phpunit https://phar.phpunit.de/phpunit-9.phar + - chmod +x /usr/local/bin/phpunit + - phpunit --coverage-text --colors=never -c phpunit.xml + # only: + # - develop + # except: + # - schedules + rules: + - if: '$CI_COMMIT_BRANCH =~ /(feat|fix)\/[0-9]{4,5}\/develop/' + artifacts: + paths: + - test/unitTests/build/ + expire_in: 2h + # coverage: '^\s*Lines:\s*\d+.\d+\%' + +commits: + image: debian:10-slim + stage: synchronization only: - develop + - "21.03" except: + - tags - schedules - - -commits: - image: debian:10-slim - stage: synchronization - only: - - develop - - "21.03" - except: - - tags - - schedules - before_script: - # Skip the synchronisation if it is not enabled - - if [ $SYNC_ENABLED = "true" ]; then echo "Sync enabled"; else echo "Sync disabled, stopping the job" && exit 0; fi - # Configure ssh, with the private key to push to the private repository - - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' - - eval $(ssh-agent -s) - - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - - - mkdir -p ~/.ssh - - chmod 700 ~/.ssh - - ssh-keyscan "$GITLAB_URL" >> ~/.ssh/known_hosts - - chmod 644 ~/.ssh/known_hosts - - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config' - # Install git command - - apt install -y git - script: - - chmod +x ./ci/commit_synchronization.sh - - ./ci/commit_synchronization.sh + before_script: + # Skip the synchronisation if it is not enabled + - if [ $SYNC_ENABLED = "true" ]; then echo "Sync enabled"; else echo "Sync disabled, stopping the job" && exit 0; fi + # Configure ssh, with the private key to push to the private repository + - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + - eval $(ssh-agent -s) + - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - + - mkdir -p ~/.ssh + - chmod 700 ~/.ssh + - ssh-keyscan "$GITLAB_URL" >> ~/.ssh/known_hosts + - chmod 644 ~/.ssh/known_hosts + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config' + # Install git command + - apt install -y git + script: + - chmod +x ./ci/commit_synchronization.sh + - ./ci/commit_synchronization.sh tags: - image: debian:10-slim - stage: synchronization - only: - - tags - except: - - schedules - before_script: - # Skip the synchronisation if it is not enabled - - if [ $SYNC_ENABLED = "true" ]; then echo "Sync enabled"; else echo "Sync disabled, stopping the job" && exit 0; fi - # Configure ssh, with the private key to push to the private repository - - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' - - eval $(ssh-agent -s) - - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - - - mkdir -p ~/.ssh - - chmod 700 ~/.ssh - - ssh-keyscan "$GITLAB_URL" >> ~/.ssh/known_hosts - - chmod 644 ~/.ssh/known_hosts - - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config' - # Install git and curl command - - apt install -y git - - apt install -y curl - # Install npm - - curl -sL https://deb.nodesource.com/setup_14.x | bash - - - apt install -y nodejs - script: - - git config --global user.email "$CI_EMAIL" && git config --global user.name "$CI_USER" - # We will work in another directory, to avoid git conflicts - - mkdir tmp - - cd tmp - # Find the branch name from tag name - - VERSION1=$(echo $CI_COMMIT_TAG| cut -d'.' -f 1) - - VERSION2=$(echo $CI_COMMIT_TAG| cut -d'.' -f 2) - - VERSION="${VERSION1}.${VERSION2}" - # Pull the private repository - - git init && git remote add origin $PRIVATE_REPOSITORY_URL_SSH - - git pull origin $VERSION - # Update and push build prod - - npm install - - npm run build-prod - - git status - - git add -f dist/ - - git status - - git commit -m "Build prod for tag ${CI_COMMIT_TAG}" - - git show-ref - - git push origin HEAD:$VERSION - - git status - # Do the tag on the private repo - - git tag $CI_COMMIT_TAG - - git status - - git push origin --tags + image: debian:10-slim + stage: synchronization + only: + - tags + except: + - schedules + before_script: + # Skip the synchronisation if it is not enabled + - if [ $SYNC_ENABLED = "true" ]; then echo "Sync enabled"; else echo "Sync disabled, stopping the job" && exit 0; fi + # Configure ssh, with the private key to push to the private repository + - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + - eval $(ssh-agent -s) + - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - + - mkdir -p ~/.ssh + - chmod 700 ~/.ssh + - ssh-keyscan "$GITLAB_URL" >> ~/.ssh/known_hosts + - chmod 644 ~/.ssh/known_hosts + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config' + # Install git and curl command + - apt install -y git + - apt install -y curl + # Install npm + - curl -sL https://deb.nodesource.com/setup_14.x | bash - + - apt install -y nodejs + script: + - git config --global user.email "$CI_EMAIL" && git config --global user.name "$CI_USER" + # We will work in another directory, to avoid git conflicts + - mkdir tmp + - cd tmp + # Find the branch name from tag name + - VERSION1=$(echo $CI_COMMIT_TAG| cut -d'.' -f 1) + - VERSION2=$(echo $CI_COMMIT_TAG| cut -d'.' -f 2) + - VERSION="${VERSION1}.${VERSION2}" + # Pull the private repository + - git init && git remote add origin $PRIVATE_REPOSITORY_URL_SSH + - git pull origin $VERSION + # Update and push build prod + - npm install + - npm run build-prod + - git status + - git add -f dist/ + - git status + - git commit -m "Build prod for tag ${CI_COMMIT_TAG}" + - git show-ref + - git push origin HEAD:$VERSION + - git status + # Do the tag on the private repo + - git tag $CI_COMMIT_TAG + - git status + - git push origin --tags logs: @@ -177,39 +209,39 @@ logs: - curl -v -H 'Content-Type:application/json' -H "X-Redmine-API-Key:$REDMINE_API_KEY" -d "$BODY" -X PUT https://forge.maarch.org/issues/$ISSUE_ID.json new_branch: - image: debian:10-slim - stage: new_branch - only: - - branches - before_script: - # Install git and curl command - - apt-get update -yqq > /dev/null - - apt install -y curl - - apt install -y jq - script: - - chmod +x ./ci/create_mr.sh - - ./ci/create_mr.sh + image: debian:10-slim + stage: new_branch + only: + - branches + before_script: + # Install git and curl command + - apt-get update -yqq > /dev/null + - apt install -y curl + - apt install -y jq + script: + - chmod +x ./ci/create_mr.sh + - ./ci/create_mr.sh new_tag: - image: debian:10-slim - stage: new_tag - only: - - tags - before_script: - # Install git and curl command - - apt-get update -yqq > /dev/null - - 'which ssh-agent || ( apt-get install openssh-client -y )' - - eval $(ssh-agent -s) - - echo "$SSH_PRIVATE_KEY_2" | tr -d '\r' | ssh-add - - - mkdir -p ~/.ssh - - chmod 700 ~/.ssh - - ssh-keyscan "$GITLAB_URL" >> ~/.ssh/known_hosts - - chmod 644 ~/.ssh/known_hosts - - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config' - - apt install -y git - - apt install -y curl - - apt install -y jq - script: - - chmod +x ./ci/new_tag.sh - - ./ci/new_tag.sh + image: debian:10-slim + stage: new_tag + only: + - tags + before_script: + # Install git and curl command + - apt-get update -yqq > /dev/null + - 'which ssh-agent || ( apt-get install openssh-client -y )' + - eval $(ssh-agent -s) + - echo "$SSH_PRIVATE_KEY_2" | tr -d '\r' | ssh-add - + - mkdir -p ~/.ssh + - chmod 700 ~/.ssh + - ssh-keyscan "$GITLAB_URL" >> ~/.ssh/known_hosts + - chmod 644 ~/.ssh/known_hosts + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config' + - apt install -y git + - apt install -y curl + - apt install -y jq + script: + - chmod +x ./ci/new_tag.sh + - ./ci/new_tag.sh diff --git a/phpunit.xml b/phpunit.xml index f062ec810c67a21709f308afaeb05b6273df07de..8648b358c763e5e56ae2432487ee1c87ec7cd8c4 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,5 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" bootstrap="test/unitTests/define.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> + <php> + <server name='HTTP_HOST' value='http://localhost/MaarchParapheur' /> + <server name='SERVER_PORT' value='80' /> + </php> <coverage> <include> <directory suffix="Test.php">test</directory> diff --git a/src/app/email/controllers/EmailController.php b/src/app/email/controllers/EmailController.php index 8601bbad15c93bf1ec57b8472437354d4dcca8dc..b4cc19f7e9b6cac8f25bc82c286efd26fa290a7d 100644 --- a/src/app/email/controllers/EmailController.php +++ b/src/app/email/controllers/EmailController.php @@ -132,10 +132,10 @@ class EmailController $email['cci'] = json_decode($email['cci']); $configuration = ConfigurationModel::getByIdentifier(['identifier' => 'emailServer', 'select' => ['value']]); - $configuration = json_decode($configuration[0]['value'], true); if (empty($configuration)) { return ['errors' => 'Configuration is missing']; } + $configuration = json_decode($configuration[0]['value'], true); $phpmailer = new PHPMailer(); $phpmailer->setFrom($configuration['from']); diff --git a/src/app/user/controllers/UserController.php b/src/app/user/controllers/UserController.php index 3cae1c2259c90d7f90d9a0711ab19bd98b226956..ed9398ada46fd0c28a6943bd3b2d84a1aa0aa170 100755 --- a/src/app/user/controllers/UserController.php +++ b/src/app/user/controllers/UserController.php @@ -179,7 +179,11 @@ class UserController return $response->withStatus(400)->withJson(['errors' => 'Login already exists', 'lang' => 'userLoginAlreadyExists']); } - $body['x509_fingerprint'] = $body['x509Fingerprint']; + $body['x509_fingerprint'] = !empty($body['x509Fingerprint']) ? $body['x509Fingerprint'] : null; + + if (empty($body['phone'])) { + $body['phone'] = null; + } if (!empty($body['isRest'])) { $body['"isRest"'] = true; @@ -254,7 +258,6 @@ class UserController 'firstname' => $body['firstname'], 'lastname' => $body['lastname'], 'email' => $body['email'], - 'phone' => $body['phone'], 'signature_modes' => [] ]; diff --git a/src/app/user/models/UserModel.php b/src/app/user/models/UserModel.php index cf400b123e8cc27ea472e0b568ce2f1d7b817481..8cef89e10253b8a781bf7a5f12f832544eb70b92 100755 --- a/src/app/user/models/UserModel.php +++ b/src/app/user/models/UserModel.php @@ -103,7 +103,7 @@ class UserModel 'picture' => $args['picture'], 'password_modification_date' => 'CURRENT_TIMESTAMP', 'signature_modes' => $args['signatureModes'], - 'x509_fingerprint' => $args['x509_fingerprint'], + 'x509_fingerprint' => $args['x509_fingerprint'] ] ]); diff --git a/src/core/controllers/AuthenticationController.php b/src/core/controllers/AuthenticationController.php index 32dde88a04da6ff6514252c465a40d18c0c5adbe..fed906f671102396ab98c4c002c01778e69e7980 100755 --- a/src/core/controllers/AuthenticationController.php +++ b/src/core/controllers/AuthenticationController.php @@ -105,7 +105,7 @@ class AuthenticationController $connection = ConfigurationModel::getConnection(); if (in_array($connection, ['default', 'ldap'])) { - if (!Validator::stringType()->notEmpty()->validate($body['login']) || !Validator::stringType()->notEmpty()->validate($body['password'])) { + if (!array_key_exists('login', $body) || !array_key_exists('password', $body) || !Validator::stringType()->notEmpty()->validate($body['login']) || !Validator::stringType()->notEmpty()->validate($body['password'])) { return $response->withStatus(400)->withJson(['errors' => 'Bad Request']); } } diff --git a/src/core/models/DatabasePDO.php b/src/core/models/DatabasePDO.php index ba426ebf7c06933a36d764b6ca5872e84a616bd4..e47f6c31a80b3ac35ea81f79bf5eeff31f055ebe 100755 --- a/src/core/models/DatabasePDO.php +++ b/src/core/models/DatabasePDO.php @@ -69,7 +69,7 @@ class DatabasePDO \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::ATTR_CASE => \PDO::CASE_LOWER ]; - + try { self::$pdo = new \PDO($dsn, $user, $password, $options); break; @@ -79,7 +79,7 @@ class DatabasePDO self::$pdo = new \PDO($dsn, $user, $password, $options); break; } catch (\PDOException $PDOException) { - if (!empty($loadedXml->database[$key + 1])) { + if (!empty($loadedXml->{$key.'1'})) { continue; } else { throw new \Exception($PDOException->getMessage()); diff --git a/src/core/models/PasswordModel.php b/src/core/models/PasswordModel.php index 2ddb2fae0a3e11f0a603c5555daccf3515514158..c2e2ee351e48d5d24c250afba3b5f97385256557 100755 --- a/src/core/models/PasswordModel.php +++ b/src/core/models/PasswordModel.php @@ -23,8 +23,8 @@ class PasswordModel $aRules = DatabaseModel::select([ 'select' => empty($aArgs['select']) ? ['*'] : $aArgs['select'], 'table' => ['password_rules'], - 'where' => $aArgs['where'], - 'data' => $aArgs['data'], + 'where' => $aArgs['where'] ?? [], + 'data' => $aArgs['data'] ?? [], ]); return $aRules; diff --git a/test/unitTests/app/user/UserControllerTest.php b/test/unitTests/app/user/UserControllerTest.php index 1d573d5b63e680f81feace4edfd08aab1600e66d..6bd12b4a1bc05f96d3f7cab7e3df7a7f7ed8dde3 100755 --- a/test/unitTests/app/user/UserControllerTest.php +++ b/test/unitTests/app/user/UserControllerTest.php @@ -13,6 +13,7 @@ class UserControllerTest extends TestCase { private static $signatureId = null; private static $userId = null; + private static $userIdToDelete = null; public function testCreateUser() { @@ -22,10 +23,11 @@ class UserControllerTest extends TestCase $request = \Slim\Http\Request::createFromEnvironment($environment); $aArgs = [ - 'login' => 'emailLogin', - 'firstname' => 'Prénom', - 'lastname' => 'Nom', - 'email' => 'email@test.fr' + 'login' => 'emailLoginFingerprint', + 'firstname' => 'Prénom', + 'lastname' => 'Nom', + 'email' => 'email@test.fr', + 'phone' => '0701020304' ]; $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); @@ -35,6 +37,23 @@ class UserControllerTest extends TestCase $this->assertIsInt($responseBody->id); self::$userId = $responseBody->id; + //with x509Fingerprint + $aArgs = [ + 'login' => 'emailLogin', + 'firstname' => 'Prénom', + 'lastname' => 'Nom', + 'email' => 'email@test.fr', + 'x509Fingerprint' => 'fingerprint', + 'isRest' => true + ]; + + $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); + $response = $userController->create($fullRequest, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + $this->assertIsInt($responseBody->id); + self::$userIdToDelete = $responseBody->id; + //Mail missing $aArgs = [ 'login' => 'failLogin', @@ -162,11 +181,27 @@ class UserControllerTest extends TestCase $this->assertSame('email@test.fr', $responseBody->user->email); $this->assertSame('Prénom', $responseBody->user->firstname); $this->assertSame('Nom', $responseBody->user->lastname); + $this->assertSame('0701020304', $responseBody->user->phone); $response = $userController->getById($request, new \Slim\Http\Response(), ['id' => -1]); + $this->assertSame(400, $response->getStatusCode()); $responseBody = json_decode((string)$response->getBody()); + $this->assertSame('User does not exist', $responseBody->errors); + } - $this->assertEmpty($responseBody->users); + public function testGetFingerprintById() + { + $previousUserId = $GLOBALS['id']; + $GLOBALS['id'] = self::$userIdToDelete; + $userController = new \User\controllers\UserController(); + + //find "userIdToDelete" fingerprint before user gets deleted + $response = $userController->getUserInformationsById(['id' => self::$userIdToDelete]); + + $this->assertNotEmpty($response); + $this->assertNotEmpty($response['x509Fingerprint']); + $this->assertSame('fingerprint', $response['x509Fingerprint']); + $GLOBALS['id'] = $previousUserId; } public function testUpdate() @@ -181,13 +216,14 @@ class UserControllerTest extends TestCase $request = \Slim\Http\Request::createFromEnvironment($environment); $aArgs = [ - 'writingMode' => 'stylus', - 'writingSize' => 2, - 'writingColor' => '#F1F1F1', - 'lang' => 'fr', - 'notifications' => [ - 'instant' => true, - 'summaries' => [], + 'writingMode' => 'stylus', + 'writingSize' => 2, + 'writingColor' => '#F1F1F1', + 'lang' => 'fr', + 'signatureScaling' => false, + 'notifications' => [ + 'instant' => true, + 'summaries' => [], ], ]; @@ -203,7 +239,8 @@ class UserControllerTest extends TestCase $aArgs = [ 'firstname' => 'Jolly', 'lastname' => 'Jumper', - 'email' => 'email@test.fr' + 'email' => 'email@test.fr', + 'phone' => '0701020304' ]; $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); @@ -241,7 +278,7 @@ class UserControllerTest extends TestCase $aArgs = [ 'encodedSignature' => base64_encode(file_get_contents('test/unitTests/samples/signature.jpg')), 'format' => 'jpg' - ]; + ]; $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); $response = $signatureController->create($fullRequest, new \Slim\Http\Response(), ['id' => self::$userId]); @@ -290,4 +327,30 @@ class UserControllerTest extends TestCase ]); $GLOBALS['id'] = $previousUserId; } + + public function testDelete() + { + $userController = new \User\controllers\UserController(); + + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'DELETE']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $response = $userController->delete($request, new \Slim\Http\Response(), ['id' => self::$userIdToDelete]); + $this->assertSame(204, $response->getStatusCode()); + + $response = $userController->delete($request, new \Slim\Http\Response(), ['id' => self::$userIdToDelete]); + $responseBody = json_decode((string)$response->getBody()); + $this->assertSame(400, $response->getStatusCode()); + $this->assertSame('User does not exist', $responseBody->errors); + + $response = $userController->delete($request, new \Slim\Http\Response(), ['id' => '1']); + $responseBody = json_decode((string)$response->getBody()); + $this->assertSame(403, $response->getStatusCode()); + $this->assertSame('Privilege forbidden', $responseBody->errors); + + $response = $userController->delete($request, new \Slim\Http\Response(), ['id' => 1.1]); + $responseBody = json_decode((string)$response->getBody()); + $this->assertSame(400, $response->getStatusCode()); + $this->assertSame('Route id is not an integer', $responseBody->errors); + } }