summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/css/app.css9
-rw-r--r--controllers/user.php78
-rw-r--r--core/helper.php7
-rw-r--r--locales/fr_FR/translations.php3
-rw-r--r--locales/pl_PL/translations.php3
-rw-r--r--models/user.php158
-rw-r--r--templates/project_new.php2
-rw-r--r--templates/task_new.php2
-rw-r--r--templates/user_edit.php3
-rw-r--r--templates/user_new.php2
10 files changed, 231 insertions, 36 deletions
diff --git a/assets/css/app.css b/assets/css/app.css
index a2a73be2..4935c296 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -156,9 +156,6 @@ textarea {
font-size: 99%;
}
-select {
-}
-
::-webkit-input-placeholder {
color: #bbb;
padding-top: 2px;
@@ -183,6 +180,12 @@ textarea.form-error {
border: 2px solid #b94a48;
}
+.form-required {
+ color: red;
+ padding-left: 5px;
+ font-weight: bold;
+}
+
.form-errors {
color: #b94a48;
list-style-type: none;
diff --git a/controllers/user.php b/controllers/user.php
index e5b2030b..bc5c48fe 100644
--- a/controllers/user.php
+++ b/controllers/user.php
@@ -4,9 +4,19 @@ namespace Controller;
require_once __DIR__.'/base.php';
+/**
+ * User controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
class User extends Base
{
- // Display access forbidden page
+ /**
+ * Display access forbidden page
+ *
+ * @access public
+ */
public function forbidden()
{
$this->response->html($this->template->layout('user_forbidden', array(
@@ -15,14 +25,22 @@ class User extends Base
)));
}
- // Logout and destroy session
+ /**
+ * Logout and destroy session
+ *
+ * @access public
+ */
public function logout()
{
$this->session->close();
$this->response->redirect('?controller=user&action=login');
}
- // Display the form login
+ /**
+ * Display the form login
+ *
+ * @access public
+ */
public function login()
{
if (isset($_SESSION['user'])) $this->response->redirect('?controller=app');
@@ -35,7 +53,11 @@ class User extends Base
)));
}
- // Check credentials
+ /**
+ * Check credentials
+ *
+ * @access public
+ */
public function check()
{
$values = $this->request->getValues();
@@ -51,7 +73,11 @@ class User extends Base
)));
}
- // List all users
+ /**
+ * List all users
+ *
+ * @access public
+ */
public function index()
{
$users = $this->user->getAll();
@@ -67,7 +93,11 @@ class User extends Base
)));
}
- // Display a form to create a new user
+ /**
+ * Display a form to create a new user
+ *
+ * @access public
+ */
public function create()
{
$this->response->html($this->template->layout('user_new', array(
@@ -79,7 +109,11 @@ class User extends Base
)));
}
- // Validate and save a new user
+ /**
+ * Validate and save a new user
+ *
+ * @access public
+ */
public function save()
{
$values = $this->request->getValues();
@@ -105,14 +139,18 @@ class User extends Base
)));
}
- // Display a form to edit a user
+ /**
+ * Display a form to edit a user
+ *
+ * @access public
+ */
public function edit()
{
$user = $this->user->getById($this->request->getIntegerParam('user_id'));
if (! $user) $this->notfound();
- if (! $_SESSION['user']['is_admin'] && $_SESSION['user']['id'] != $user['id']) {
+ if ($this->acl->isRegularUser() && $this->acl->getUserId() != $user['id']) {
$this->forbidden();
}
@@ -127,17 +165,21 @@ class User extends Base
)));
}
- // Validate and update a user
+ /**
+ * Validate and update a user
+ *
+ * @access public
+ */
public function update()
{
$values = $this->request->getValues();
- if ($_SESSION['user']['is_admin'] == 1) {
+ if ($this->acl->isAdminUser()) {
$values += array('is_admin' => 0);
}
else {
- if ($_SESSION['user']['id'] != $values['id']) {
+ if ($this->acl->getUserId() != $values['id']) {
$this->forbidden();
}
@@ -168,7 +210,11 @@ class User extends Base
)));
}
- // Confirmation dialog before to remove a user
+ /**
+ * Confirmation dialog before to remove a user
+ *
+ * @access public
+ */
public function confirm()
{
$user = $this->user->getById($this->request->getIntegerParam('user_id'));
@@ -182,7 +228,11 @@ class User extends Base
)));
}
- // Remove a user
+ /**
+ * Remove a user
+ *
+ * @access public
+ */
public function remove()
{
$user_id = $this->request->getIntegerParam('user_id');
diff --git a/core/helper.php b/core/helper.php
index 0eeec4cd..da90bad6 100644
--- a/core/helper.php
+++ b/core/helper.php
@@ -18,6 +18,11 @@ function is_admin()
return $_SESSION['user']['is_admin'] == 1;
}
+function get_username()
+{
+ return $_SESSION['user']['username'];
+}
+
function markdown($text)
{
require_once __DIR__.'/../vendor/Michelf/MarkdownExtra.inc.php';
@@ -206,6 +211,7 @@ function form_textarea($name, $values = array(), array $errors = array(), array
$html .= implode(' ', $attributes).'>';
$html .= isset($values->$name) ? escape($values->$name) : isset($values[$name]) ? $values[$name] : '';
$html .= '</textarea>';
+ if (in_array('required', $attributes)) $html .= '<span class="form-required">*</span>';
$html .= error_list($errors, $name);
return $html;
@@ -217,6 +223,7 @@ function form_input($type, $name, $values = array(), array $errors = array(), ar
$html = '<input type="'.$type.'" name="'.$name.'" id="form-'.$name.'" '.form_value($values, $name).' class="'.$class.'" ';
$html .= implode(' ', $attributes).'/>';
+ if (in_array('required', $attributes)) $html .= '<span class="form-required">*</span>';
$html .= error_list($errors, $name);
return $html;
diff --git a/locales/fr_FR/translations.php b/locales/fr_FR/translations.php
index 9a73228b..362d29c2 100644
--- a/locales/fr_FR/translations.php
+++ b/locales/fr_FR/translations.php
@@ -264,4 +264,7 @@ return array(
'Do you really want to remove this comment?' => 'Voulez-vous vraiment supprimer ce commentaire ?',
'Only administrators or the creator of the comment can access to this page.' => 'Uniquement les administrateurs ou le créateur du commentaire peuvent accéder à cette page.',
'Details' => 'Détails',
+ 'Current password for the user "%s"' => 'Mot de passe actuel pour l\'utilisateur « %s »',
+ 'The current password is required' => 'Le mot de passe actuel est obligatoire',
+ 'Wrong password' => 'Mauvais mot de passe',
);
diff --git a/locales/pl_PL/translations.php b/locales/pl_PL/translations.php
index 27ffdef7..25c3e637 100644
--- a/locales/pl_PL/translations.php
+++ b/locales/pl_PL/translations.php
@@ -267,4 +267,7 @@ return array(
// 'Do you really want to remove this comment?' => '',
// 'Only administrators or the creator of the comment can access to this page.' => '',
// 'Details' => '',
+ // 'Current password for the user "%s"' => '',
+ // 'The current password is required' => '',
+ // 'Wrong password' => '',
);
diff --git a/models/user.php b/models/user.php
index 21c65b59..496ae0da 100644
--- a/models/user.php
+++ b/models/user.php
@@ -7,20 +7,51 @@ require_once __DIR__.'/base.php';
use \SimpleValidator\Validator;
use \SimpleValidator\Validators;
+/**
+ * User model
+ *
+ * @package model
+ * @author Frederic Guillot
+ */
class User extends Base
{
+ /**
+ * SQL table name
+ *
+ * @var string
+ */
const TABLE = 'users';
+ /**
+ * Get a specific user by id
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @return array
+ */
public function getById($user_id)
{
return $this->db->table(self::TABLE)->eq('id', $user_id)->findOne();
}
+ /**
+ * Get a specific user by the username
+ *
+ * @access public
+ * @param string $username Username
+ * @return array
+ */
public function getByUsername($username)
{
return $this->db->table(self::TABLE)->eq('username', $username)->findOne();
}
+ /**
+ * Get all users
+ *
+ * @access public
+ * @return array
+ */
public function getAll()
{
return $this->db
@@ -30,11 +61,24 @@ class User extends Base
->findAll();
}
+ /**
+ * List all users (key-value pairs with id/username)
+ *
+ * @access public
+ * @return array
+ */
public function getList()
{
return $this->db->table(self::TABLE)->asc('username')->listing('id', 'username');
}
+ /**
+ * Add a new user in the database
+ *
+ * @access public
+ * @param array $values Form values
+ * @return boolean
+ */
public function create(array $values)
{
if (isset($values['confirmation'])) unset($values['confirmation']);
@@ -43,6 +87,13 @@ class User extends Base
return $this->db->table(self::TABLE)->save($values);
}
+ /**
+ * Modify a new user
+ *
+ * @access public
+ * @param array $values Form values
+ * @return array
+ */
public function update(array $values)
{
if (! empty($values['password'])) {
@@ -52,17 +103,25 @@ class User extends Base
unset($values['password']);
}
- unset($values['confirmation']);
+ if (isset($values['confirmation'])) unset($values['confirmation']);
+ if (isset($values['current_password'])) unset($values['current_password']);
- $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values);
+ $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values);
if ($_SESSION['user']['id'] == $values['id']) {
$this->updateSession();
}
- return true;
+ return $result;
}
+ /**
+ * Remove a specific user
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @return boolean
+ */
public function remove($user_id)
{
$this->db->startTransaction();
@@ -76,17 +135,32 @@ class User extends Base
return true;
}
+ /**
+ * Update user session information
+ *
+ * @access public
+ * @param array $user User data
+ */
public function updateSession(array $user = array())
{
if (empty($user)) {
$user = $this->getById($_SESSION['user']['id']);
}
- if (isset($user['password'])) unset($user['password']);
+ if (isset($user['password'])) {
+ unset($user['password']);
+ }
$_SESSION['user'] = $user;
}
+ /**
+ * Validate user creation
+ *
+ * @access public
+ * @param array $values Form values
+ * @return array $valid, $errors [0] = Success or not, [1] = List of errors
+ */
public function validateCreation(array $values)
{
$v = new Validator($values, array(
@@ -108,23 +182,28 @@ class User extends Base
);
}
+ /**
+ * Validate user modification
+ *
+ * @access public
+ * @param array $values Form values
+ * @return array $valid, $errors [0] = Success or not, [1] = List of errors
+ */
public function validateModification(array $values)
{
if (! empty($values['password'])) {
- return $this->validateCreation($values);
+ return $this->validatePasswordModification($values);
}
- else {
- $v = new Validator($values, array(
- new Validators\Required('id', t('The user id is required')),
- new Validators\Required('username', t('The username is required')),
- new Validators\MaxLength('username', t('The maximum length is %d characters', 50), 50),
- new Validators\AlphaNumeric('username', t('The username must be alphanumeric')),
- new Validators\Unique('username', t('The username must be unique'), $this->db->getConnection(), self::TABLE, 'id'),
- new Validators\Integer('default_project_id', t('This value must be an integer')),
- new Validators\Integer('is_admin', t('This value must be an integer')),
- ));
- }
+ $v = new Validator($values, array(
+ new Validators\Required('id', t('The user id is required')),
+ new Validators\Required('username', t('The username is required')),
+ new Validators\MaxLength('username', t('The maximum length is %d characters', 50), 50),
+ new Validators\AlphaNumeric('username', t('The username must be alphanumeric')),
+ new Validators\Unique('username', t('The username must be unique'), $this->db->getConnection(), self::TABLE, 'id'),
+ new Validators\Integer('default_project_id', t('This value must be an integer')),
+ new Validators\Integer('is_admin', t('This value must be an integer')),
+ ));
return array(
$v->execute(),
@@ -132,6 +211,53 @@ class User extends Base
);
}
+ /**
+ * Validate password modification
+ *
+ * @access public
+ * @param array $values Form values
+ * @return array $valid, $errors [0] = Success or not, [1] = List of errors
+ */
+ public function validatePasswordModification(array $values)
+ {
+ $v = new Validator($values, array(
+ new Validators\Required('id', t('The user id is required')),
+ new Validators\Required('username', t('The username is required')),
+ new Validators\MaxLength('username', t('The maximum length is %d characters', 50), 50),
+ new Validators\AlphaNumeric('username', t('The username must be alphanumeric')),
+ new Validators\Unique('username', t('The username must be unique'), $this->db->getConnection(), self::TABLE, 'id'),
+ new Validators\Required('current_password', t('The current password is required')),
+ new Validators\Required('password', t('The password is required')),
+ new Validators\MinLength('password', t('The minimum length is %d characters', 6), 6),
+ new Validators\Required('confirmation', t('The confirmation is required')),
+ new Validators\Equals('password', 'confirmation', t('Passwords doesn\'t matches')),
+ new Validators\Integer('default_project_id', t('This value must be an integer')),
+ new Validators\Integer('is_admin', t('This value must be an integer')),
+ ));
+
+ if ($v->execute()) {
+
+ // Check password
+ $user = $this->getById($_SESSION['user']['id']);
+
+ if ($user !== false && \password_verify($values['current_password'], $user['password'])) {
+ return array(true, array());
+ }
+ else {
+ return array(false, array('current_password' => array(t('Wrong password'))));
+ }
+ }
+
+ return array(false, $v->getErrors());
+ }
+
+ /**
+ * Validate user login
+ *
+ * @access public
+ * @param array $values Form values
+ * @return array $valid, $errors [0] = Success or not, [1] = List of errors
+ */
public function validateLogin(array $values)
{
$v = new Validator($values, array(
diff --git a/templates/project_new.php b/templates/project_new.php
index 5ce6f97d..2026d461 100644
--- a/templates/project_new.php
+++ b/templates/project_new.php
@@ -9,7 +9,7 @@
<form method="post" action="?controller=project&amp;action=save" autocomplete="off">
<?= Helper\form_label(t('Name'), 'name') ?>
- <?= Helper\form_text('name', $values, $errors, array('autofocus required')) ?>
+ <?= Helper\form_text('name', $values, $errors, array('autofocus', 'required')) ?>
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
diff --git a/templates/task_new.php b/templates/task_new.php
index 4280bf80..efb9cb62 100644
--- a/templates/task_new.php
+++ b/templates/task_new.php
@@ -6,7 +6,7 @@
<form method="post" action="?controller=task&amp;action=save" autocomplete="off">
<?= Helper\form_label(t('Title'), 'title') ?>
- <?= Helper\form_text('title', $values, $errors, array('autofocus required')) ?><br/>
+ <?= Helper\form_text('title', $values, $errors, array('autofocus', 'required')) ?><br/>
<?= Helper\form_hidden('project_id', $values) ?>
diff --git a/templates/user_edit.php b/templates/user_edit.php
index c65f3381..0c82793d 100644
--- a/templates/user_edit.php
+++ b/templates/user_edit.php
@@ -13,6 +13,9 @@
<?= Helper\form_label(t('Username'), 'username') ?>
<?= Helper\form_text('username', $values, $errors, array('required')) ?><br/>
+ <?= Helper\form_label(t('Current password for the user "%s"', Helper\get_username()), 'current_password') ?>
+ <?= Helper\form_password('current_password', $values, $errors) ?><br/>
+
<?= Helper\form_label(t('Password'), 'password') ?>
<?= Helper\form_password('password', $values, $errors) ?><br/>
diff --git a/templates/user_new.php b/templates/user_new.php
index 0c753c2a..8b15525b 100644
--- a/templates/user_new.php
+++ b/templates/user_new.php
@@ -9,7 +9,7 @@
<form method="post" action="?controller=user&amp;action=save" autocomplete="off">
<?= Helper\form_label(t('Username'), 'username') ?>
- <?= Helper\form_text('username', $values, $errors, array('autofocus required')) ?><br/>
+ <?= Helper\form_text('username', $values, $errors, array('autofocus', 'required')) ?><br/>
<?= Helper\form_label(t('Password'), 'password') ?>
<?= Helper\form_password('password', $values, $errors, array('required')) ?><br/>