From b55888bd34b1033b74ac831c1533fc7e2e856dfa Mon Sep 17 00:00:00 2001
From: Damien <damien.burel@maarch.org>
Date: Mon, 19 Nov 2018 17:59:51 +0100
Subject: [PATCH] FEAT #8836 Update user + password

---
 rest/index.php                              |  5 +++
 src/app/user/controllers/UserController.php | 50 +++++++++++++++++++++
 src/app/user/models/UserModel.php           | 39 ++++++++++++++++
 src/core/controllers/PasswordController.php |  7 +++
 src/core/models/PasswordModel.php           | 14 ++++++
 5 files changed, 115 insertions(+)

diff --git a/rest/index.php b/rest/index.php
index 9cd8b1ddef..55bbd56d28 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -61,8 +61,13 @@ $app->get('/documents/{id}/status', \Document\controllers\DocumentController::cl
 $app->get('/documents/{id}/handwrittenDocument', \Document\controllers\DocumentController::class . ':getHandwrittenDocumentById');
 $app->put('/documents/{id}/action', \Document\controllers\DocumentController::class . ':makeAction');
 
+//Password Rules
+$app->get('/passwordRules', \SrcCore\controllers\PasswordController::class . ':get');
+
 //Users
 $app->get('/users', \User\controllers\UserController::class . ':get');
+$app->put('/users/{id}', \User\controllers\UserController::class . ':update');
+$app->put('/users/{id}/password', \User\controllers\UserController::class . ':updatePassword');
 $app->get('/users/{id}/signatures', \User\controllers\UserController::class . ':getSignatures');
 $app->post('/users/{id}/signatures', \User\controllers\UserController::class . ':createSignature');
 $app->delete('/users/{id}/signatures/{signatureId}', \User\controllers\UserController::class . ':deleteSignature');
diff --git a/src/app/user/controllers/UserController.php b/src/app/user/controllers/UserController.php
index b9f9a1d0ed..27081e29fd 100755
--- a/src/app/user/controllers/UserController.php
+++ b/src/app/user/controllers/UserController.php
@@ -19,6 +19,8 @@ use Docserver\models\DocserverModel;
 use Respect\Validation\Validator;
 use Slim\Http\Request;
 use Slim\Http\Response;
+use SrcCore\controllers\PasswordController;
+use SrcCore\models\AuthenticationModel;
 use User\models\UserModel;
 
 class UserController
@@ -34,6 +36,54 @@ class UserController
         return $response->withJson(['users' => $users]);
     }
 
+    public function update(Request $request, Response $response, array $args)
+    {
+        $user = UserModel::getByEmail(['email' => $GLOBALS['email'], 'select' => ['id']]);
+        if ($user['id'] != $args['id']) {
+            return $response->withStatus(403)->withJson(['errors' => 'User out of perimeter']);
+        }
+
+        $data = $request->getParams();
+        $check = Validator::stringType()->notEmpty()->validate($data['firstname']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['lastname']);
+        if (!$check) {
+            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
+        }
+
+        $data['id'] = $args['id'];
+        UserModel::update($data);
+
+        return $response->withJson(['success' => 'success']);
+    }
+
+    public function updatePassword(Request $request, Response $response, array $args)
+    {
+        $user = UserModel::getByEmail(['email' => $GLOBALS['email'], 'select' => ['id']]);
+        if ($user['id'] != $args['id']) {
+            return $response->withStatus(403)->withJson(['errors' => 'User out of perimeter']);
+        }
+
+        $data = $request->getParams();
+        $check = Validator::stringType()->notEmpty()->validate($data['currentPassword']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['newPassword']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['passwordConfirmation']);
+        if (!$check) {
+            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
+        }
+
+        if ($data['newPassword'] != $data['passwordConfirmation']) {
+            return $response->withStatus(400)->withJson(['errors' => 'New password does not match password confirmation']);
+        } elseif (!AuthenticationModel::authentication(['email' => $GLOBALS['email'], 'password' => $data['currentPassword']])) {
+            return $response->withStatus(401)->withJson(['errors' => 'Wrong Password']);
+        } elseif (!PasswordController::isPasswordValid(['password' => $data['newPassword']])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Password does not match security criteria']);
+        }
+
+        UserModel::updatePassword(['id' => $args['id'], 'password' => $data['newPassword']]);
+
+        return $response->withJson(['success' => 'success']);
+    }
+
     public function getSignatures(Request $request, Response $response, array $args)
     {
         $user = UserModel::getByEmail(['email' => $GLOBALS['email'], 'select' => ['id']]);
diff --git a/src/app/user/models/UserModel.php b/src/app/user/models/UserModel.php
index 8ddd16f412..fd2a14a923 100755
--- a/src/app/user/models/UserModel.php
+++ b/src/app/user/models/UserModel.php
@@ -14,6 +14,7 @@
 
 namespace User\models;
 
+use SrcCore\models\AuthenticationModel;
 use SrcCore\models\DatabaseModel;
 use SrcCore\models\ValidatorModel;
 
@@ -74,6 +75,44 @@ class UserModel
         return $aUser[0];
     }
 
+    public static function update(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['id', 'firstname', 'lastname']);
+        ValidatorModel::intVal($aArgs, ['id']);
+        ValidatorModel::stringType($aArgs, ['firstname', 'lastname']);
+
+        DatabaseModel::update([
+            'table'     => 'users',
+            'set'       => [
+                'firstname' => $aArgs['firstname'],
+                'lastname'  => $aArgs['lastname'],
+            ],
+            'where'     => ['id = ?'],
+            'data'      => [$aArgs['id']]
+        ]);
+
+        return true;
+    }
+
+    public static function updatePassword(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['id', 'password']);
+        ValidatorModel::intVal($aArgs, ['id']);
+        ValidatorModel::stringType($aArgs, ['password']);
+
+        DatabaseModel::update([
+            'table'     => 'users',
+            'set'       => [
+                'password'                      => AuthenticationModel::getPasswordHash($aArgs['password']),
+                'password_modification_date'    => 'CURRENT_TIMESTAMP'
+            ],
+            'where'     => ['id = ?'],
+            'data'      => [$aArgs['id']]
+        ]);
+
+        return true;
+    }
+
     public static function getLabelledUserById(array $aArgs)
     {
         ValidatorModel::intVal($aArgs, ['id']);
diff --git a/src/core/controllers/PasswordController.php b/src/core/controllers/PasswordController.php
index de986a2605..5d2cd3f05c 100755
--- a/src/core/controllers/PasswordController.php
+++ b/src/core/controllers/PasswordController.php
@@ -14,11 +14,18 @@
 
 namespace SrcCore\controllers;
 
+use Slim\Http\Request;
+use Slim\Http\Response;
 use SrcCore\models\PasswordModel;
 use SrcCore\models\ValidatorModel;
 
 class PasswordController
 {
+    public function get(Request $request, Response $response)
+    {
+        return $response->withJson(['rules' => PasswordModel::getRules()]);
+    }
+
     public static function isPasswordValid(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['password']);
diff --git a/src/core/models/PasswordModel.php b/src/core/models/PasswordModel.php
index 021d5d43bc..870d7aea5f 100755
--- a/src/core/models/PasswordModel.php
+++ b/src/core/models/PasswordModel.php
@@ -16,6 +16,20 @@ namespace SrcCore\models;
 
 class PasswordModel
 {
+    public static function getRules(array $aArgs = [])
+    {
+        ValidatorModel::arrayType($aArgs, ['select', 'where', 'data']);
+
+        $aRules = DatabaseModel::select([
+            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'     => ['password_rules'],
+            'where'     => $aArgs['where'],
+            'data'      => $aArgs['data'],
+        ]);
+
+        return $aRules;
+    }
+
     public static function getEnabledRules()
     {
         $aRules = DatabaseModel::select([
-- 
GitLab