aboutsummaryrefslogtreecommitdiffhomepage
path: root/application/front/controller/admin
diff options
context:
space:
mode:
Diffstat (limited to 'application/front/controller/admin')
-rw-r--r--application/front/controller/admin/PasswordController.php100
-rw-r--r--application/front/controller/admin/ShaarliAdminController.php59
2 files changed, 159 insertions, 0 deletions
diff --git a/application/front/controller/admin/PasswordController.php b/application/front/controller/admin/PasswordController.php
new file mode 100644
index 00000000..6e8f0bcb
--- /dev/null
+++ b/application/front/controller/admin/PasswordController.php
@@ -0,0 +1,100 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Shaarli\Front\Controller\Admin;
6
7use Shaarli\Container\ShaarliContainer;
8use Shaarli\Front\Exception\OpenShaarliPasswordException;
9use Shaarli\Front\Exception\ShaarliFrontException;
10use Slim\Http\Request;
11use Slim\Http\Response;
12use Throwable;
13
14/**
15 * Class PasswordController
16 *
17 * Slim controller used to handle passwords update.
18 */
19class PasswordController extends ShaarliAdminController
20{
21 public function __construct(ShaarliContainer $container)
22 {
23 parent::__construct($container);
24
25 $this->assignView(
26 'pagetitle',
27 t('Change password') .' - '. $this->container->conf->get('general.title', 'Shaarli')
28 );
29 }
30
31 /**
32 * GET /password - Displays the change password template
33 */
34 public function index(Request $request, Response $response): Response
35 {
36 return $response->write($this->render('changepassword'));
37 }
38
39 /**
40 * POST /password - Change admin password - existing and new passwords need to be provided.
41 */
42 public function change(Request $request, Response $response): Response
43 {
44 $this->checkToken($request);
45
46 if ($this->container->conf->get('security.open_shaarli', false)) {
47 throw new OpenShaarliPasswordException();
48 }
49
50 $oldPassword = $request->getParam('oldpassword');
51 $newPassword = $request->getParam('setpassword');
52
53 if (empty($newPassword) || empty($oldPassword)) {
54 $this->saveErrorMessage(t('You must provide the current and new password to change it.'));
55
56 return $response
57 ->withStatus(400)
58 ->write($this->render('changepassword'))
59 ;
60 }
61
62 // Make sure old password is correct.
63 $oldHash = sha1(
64 $oldPassword .
65 $this->container->conf->get('credentials.login') .
66 $this->container->conf->get('credentials.salt')
67 );
68
69 if ($oldHash !== $this->container->conf->get('credentials.hash')) {
70 $this->saveErrorMessage(t('The old password is not correct.'));
71
72 return $response
73 ->withStatus(400)
74 ->write($this->render('changepassword'))
75 ;
76 }
77
78 // Save new password
79 // Salt renders rainbow-tables attacks useless.
80 $this->container->conf->set('credentials.salt', sha1(uniqid('', true) .'_'. mt_rand()));
81 $this->container->conf->set(
82 'credentials.hash',
83 sha1(
84 $newPassword
85 . $this->container->conf->get('credentials.login')
86 . $this->container->conf->get('credentials.salt')
87 )
88 );
89
90 try {
91 $this->container->conf->write($this->container->loginManager->isLoggedIn());
92 } catch (Throwable $e) {
93 throw new ShaarliFrontException($e->getMessage(), 500, $e);
94 }
95
96 $this->saveSuccessMessage(t('Your password has been changed'));
97
98 return $response->write($this->render('changepassword'));
99 }
100}
diff --git a/application/front/controller/admin/ShaarliAdminController.php b/application/front/controller/admin/ShaarliAdminController.php
index ea703f62..3385006c 100644
--- a/application/front/controller/admin/ShaarliAdminController.php
+++ b/application/front/controller/admin/ShaarliAdminController.php
@@ -7,7 +7,19 @@ namespace Shaarli\Front\Controller\Admin;
7use Shaarli\Container\ShaarliContainer; 7use Shaarli\Container\ShaarliContainer;
8use Shaarli\Front\Controller\Visitor\ShaarliVisitorController; 8use Shaarli\Front\Controller\Visitor\ShaarliVisitorController;
9use Shaarli\Front\Exception\UnauthorizedException; 9use Shaarli\Front\Exception\UnauthorizedException;
10use Shaarli\Front\Exception\WrongTokenException;
11use Shaarli\Security\SessionManager;
12use Slim\Http\Request;
10 13
14/**
15 * Class ShaarliAdminController
16 *
17 * All admin controllers (for logged in users) MUST extend this abstract class.
18 * It makes sure that the user is properly logged in, and otherwise throw an exception
19 * which will redirect to the login page.
20 *
21 * @package Shaarli\Front\Controller\Admin
22 */
11abstract class ShaarliAdminController extends ShaarliVisitorController 23abstract class ShaarliAdminController extends ShaarliVisitorController
12{ 24{
13 public function __construct(ShaarliContainer $container) 25 public function __construct(ShaarliContainer $container)
@@ -18,4 +30,51 @@ abstract class ShaarliAdminController extends ShaarliVisitorController
18 throw new UnauthorizedException(); 30 throw new UnauthorizedException();
19 } 31 }
20 } 32 }
33
34 /**
35 * Any persistent action to the config or data store must check the XSRF token validity.
36 */
37 protected function checkToken(Request $request): void
38 {
39 if (!$this->container->sessionManager->checkToken($request->getParam('token'))) {
40 throw new WrongTokenException();
41 }
42 }
43
44 /**
45 * Save a SUCCESS message in user session, which will be displayed on any template page.
46 */
47 protected function saveSuccessMessage(string $message): void
48 {
49 $this->saveMessage(SessionManager::KEY_SUCCESS_MESSAGES, $message);
50 }
51
52 /**
53 * Save a WARNING message in user session, which will be displayed on any template page.
54 */
55 protected function saveWarningMessage(string $message): void
56 {
57 $this->saveMessage(SessionManager::KEY_WARNING_MESSAGES, $message);
58 }
59
60 /**
61 * Save an ERROR message in user session, which will be displayed on any template page.
62 */
63 protected function saveErrorMessage(string $message): void
64 {
65 $this->saveMessage(SessionManager::KEY_ERROR_MESSAGES, $message);
66 }
67
68 /**
69 * Use the sessionManager to save the provided message using the proper type.
70 *
71 * @param string $type successed/warnings/errors
72 */
73 protected function saveMessage(string $type, string $message): void
74 {
75 $messages = $this->container->sessionManager->getSessionParameter($type) ?? [];
76 $messages[] = $message;
77
78 $this->container->sessionManager->setSessionParameter($type, $messages);
79 }
21} 80}