DaPortal

<?php //$Id$
//Copyright (c) 2012-2016 Pierre Pronchery <khorben@defora.org>
//This file is part of DeforaOS Web DaPortal
//
//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, version 3 of the License.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program. If not, see <http://www.gnu.org/licenses/>.
//UserModule
class UserModule extends Module
{
//public
//methods
//essential
//UserModule::UserModule
public function __construct($id, $name, $title = FALSE)
{
$title = ($title === FALSE) ? _('Users') : $title;
parent::__construct($id, $name, $title);
}
//accessors
//UserModule::getTitle
public function getTitle(Engine $engine = NULL)
{
$credentials = $engine->getCredentials();
return $credentials->getUserID()
? _('User') : parent::getTitle();
}
//useful
//UserModule::call
public function call(Engine $engine, Request $request, $internal = 0)
{
if(($action = $request->getAction()) === FALSE)
$action = 'default';
if($internal)
switch($action)
{
case 'actions':
return $this->$action($engine,
$request);
default:
return FALSE;
}
switch($action)
{
case 'admin':
case 'close':
case 'default':
case 'disable':
case 'display':
case 'enable':
case 'groups':
case 'list':
case 'lock':
case 'login':
case 'logout':
case 'profile':
case 'register':
case 'reset':
case 'submit':
case 'unlock':
case 'update':
case 'validate':
case 'widget':
$action = 'call'.$action;
return $this->$action($engine, $request);
default:
return new ErrorResponse(_('Invalid action'),
Response::$CODE_ENOENT);
}
}
//protected
//methods
//accessors
//UserModule::canClose
protected function canClose(Engine $engine, &$error = FALSE)
{
$cred = $engine->getCredentials();
if($cred->isAdmin())
{
$error = _('Administrators cannot close themselves');
return FALSE;
}
if($this->configGet('close') != 1)
{
$error = _('Closing accounts is not allowed');
return FALSE;
}
return TRUE;
}
//UserModule::canDelete
protected function canDelete(Engine $engine, User $user = NULL,
&$error = FALSE)
{
$cred = $engine->getCredentials();
if(!$cred->isAdmin())
{
$error = _('Deleting users is not allowed');
return FALSE;
}
return TRUE;
}
//UserModule::canDisable
protected function canDisable(Engine $engine, User $user = NULL,
&$error = FALSE)
{
$cred = $engine->getCredentials();
if(!$cred->isAdmin())
{
$error = _('Disabling users is not allowed');
return FALSE;
}
if($user !== FALSE && $user->getUserID() == $cred->getUserID())
{
$error = _('Disabling oneself is not allowed');
return FALSE;
}
return TRUE;
}
//UserModule::canEnable
protected function canEnable(Engine $engine, User $user = NULL,
&$error = FALSE)
{
$cred = $engine->getCredentials();
if(!$cred->isAdmin())
{
$error = _('Enabling users is not allowed');
return FALSE;
}
return TRUE;
}
//UserModule::canLock
protected function canLock(Engine $engine, User $user = NULL,
&$error = FALSE)
{
$cred = $engine->getCredentials();
if(!$cred->isAdmin())
{
$error = _('Locking users is not allowed');
return FALSE;
}
return TRUE;
}
//UserModule::canRegister
protected function canRegister(Request $request = NULL, &$error = FALSE)
{
if($this->configGet('register') != 1)
{
$error = _('Registering is not allowed');
return FALSE;
}
if($request !== NULL && $request->isIdempotent())
{
$error = _('The request expired or is invalid');
return FALSE;
}
return TRUE;
}
//UserModule::canReset
protected function canReset(Request $request = NULL, &$error = FALSE)
{
if($this->configGet('reset') != 1)
{
$error = _('Password resets are not allowed');
return FALSE;
}
if($request !== NULL && $request->isIdempotent())
{
$error = _('The request expired or is invalid');
return FALSE;
}
return TRUE;
}
//UserModule::canSubmit
protected function canSubmit(Engine $engine, &$error = FALSE)
{
$cred = $engine->getCredentials();
if(!$cred->isAdmin())
{
$error = _('Permission denied');
return FALSE;
}
return TRUE;
}
//UserModule::canUnlock
protected function canUnlock(Engine $engine, User $user = NULL,
&$error = FALSE)
{
$cred = $engine->getCredentials();
if(!$cred->isAdmin())
{
$error = _('Unlocking users is not allowed');
return FALSE;
}
return TRUE;
}
//forms
//UserModule::formClose
protected function formClose(Engine $engine)
{
$r = $this->getRequest('close');
$form = new PageElement('form', array('request' => $r));
$message = _('Do you really want to close your account?');
$dialog = $form->append('dialog', array('type' => 'warning',
'text' => $message));
$dialog->append('button', array('stock' => 'cancel',
'target' => '_cancel',
'text' => _('Cancel'),
'request' => $this->getRequest('profile')));
$dialog->append('button', array('stock' => 'close',
'type' => 'submit', 'value' => 'submit',
'text' => _('Close')));
return $form;
}
//UserModule::formLogin
protected function formLogin(Engine $engine, Request $request,
$cancel = TRUE)
{
$secure = ($this->configGet('secure') === '0') ? FALSE : TRUE;
$username = $request->get('username');
$args = $request->getParameters();
if(is_array($args))
{
if(isset($args['module']) && isset($args['action'])
&& $args['module'] == $this->getName()
&& $args['action'] == 'logout')
//do not offer to log out after logging in
$args = FALSE;
else
{
unset($args['username']);
unset($args['password']);
}
}
$r = $this->getRequest('login', $args);
$form = new PageElement('form', array('request' => $r,
'secure' => $secure));
$entry = $form->append('entry', array(
'name' => 'username',
'text' => _('Username: '),
'placeholder' => _('Username'),
'value' => $username));
$entry = $form->append('entry', array(
'hidden' => TRUE,
'name' => 'password',
'placeholder' => _('Password'),
'text' => _('Password: ')));
$r = $this->getRequest();
if($cancel)
$form->append('button', array('text' => _('Cancel'),
'stock' => 'cancel',
'target' => '_cancel',
'request' => $r));
$button = $form->append('button', array('type' => 'submit',
'stock' => 'login',
'text' => _('Login')));
return $form;
}
//UserModule::formRegister
protected function formRegister(Engine $engine, $username, $email)
{
$secure = ($this->configGet('secure') === '0') ? FALSE : TRUE;
$r = $this->getRequest('register');
$form = new PageElement('form', array('request' => $r,
'secure' => $secure));
$form->append('entry', array('text' => _('Username: '),
'name' => 'username', 'value' => $username));
$form->append('entry', array('text' => _('e-mail address: '),
'name' => 'email', 'value' => $email));
$form->append('button', array('stock' => 'cancel',
'text' => _('Cancel'),
'target' => '_cancel',
'request' => $this->getRequest()));
$form->append('button', array('stock' => 'register',
'type' => 'submit', 'text' => _('Register')));
return $form;
}
//UserModule::formReset
protected function formReset(Engine $engine, $username, $email)
{
$secure = ($this->configGet('secure') === '0') ? FALSE : TRUE;
$r = $this->getRequest('reset');
$form = new PageElement('form', array('request' => $r,
'secure' => $secure));
$form->append('entry', array('text' => _('Username: '),
'name' => 'username', 'value' => $username));
$form->append('entry', array('text' => _('e-mail address: '),
'name' => 'email', 'value' => $email));
$form->append('button', array('stock' => 'cancel',
'text' => _('Cancel'),
'target' => '_cancel',
'request' => $this->getRequest()));
$form->append('button', array('stock' => 'reset',
'type' => 'submit', 'text' => _('Reset')));
return $form;
}
//UserModule::formSubmit
protected function formSubmit(Engine $engine, Request $request)
{
$r = $this->getRequest('submit');
$form = new PageElement('form', array('request' => $r));
$vbox = $form->append('vbox');
$vbox->append('entry', array('name' => 'username',
'text' => _('Username: '),
'value' => $request->get('username')));
$vbox->append('entry', array('name' => 'fullname',
'text' => _('Full name: '),
'value' => $request->get('fullname')));
$vbox->append('entry', array('name' => 'password',
'hidden' => TRUE,
'text' => _('Password: '), 'value' => ''));
$vbox->append('entry', array('name' => 'email',
'text' => _('e-mail: '),
'value' => $request->get('email')));
//groups
if(($groups = Group::listAll($engine, TRUE)) !== FALSE)
{
//primary group
if(($group_id = $request->get('group_id')) === FALSE)
$group_id = 0;
$combobox = $vbox->append('combobox', array(
'text' => _('Primary group: '),
'name' => 'group_id',
'value' => $group_id));
foreach($groups as $group)
$combobox->append('label', array(
'text' => $group->getGroupname(),
'value' => $group->getGroupID()));
//secondary groups
$vbox->append('label', array(
'text' => _('Secondary groups:')));
$columns = array('group' => _('Group'),
'member' => _('Member'));
$view = $vbox->append('treeview', array(
'columns' => $columns,
'alternate' => TRUE));
foreach($groups as $group)
{
$r = new Request('group', 'list',
$group->getGroupID(),
$group->getGroupName());
$link = new PageElement('link', array(
'stock' => 'group',
'request' => $request,
'text' => $group->getGroupName()));
$checkbox = new PageElement('checkbox', array(
'name' => 'ids['.$group->getGroupID().']'));
$row = $view->append('row');
$row->set('group', $link);
$row->set('member', $checkbox);
}
}
//enabled
$vbox->append('checkbox', array('name' => 'enabled',
'value' => $request->get('enabled')
? TRUE : FALSE,
'text' => _('Enabled')));
//locked
$vbox->append('checkbox', array('name' => 'locked',
'value' => $request->get('locked')
? TRUE : FALSE,
'text' => _('Locked')));
//administrator
$vbox->append('checkbox', array('name' => 'admin',
'value' => $request->get('admin')
? TRUE : FALSE,
'text' => _('Administrator')));
//buttons
$r = $this->getRequest('admin');
$form->append('button', array('request' => $r,
'stock' => 'cancel',
'target' => '_cancel',
'text' => _('Cancel')));
$form->append('button', array('type' => 'submit',
'stock' => 'new', 'name' => 'action',
'value' => 'submit', 'text' => _('Create')));
return $form;
}
//UserModule::formUpdate
protected function formUpdate(Engine $engine, Request $request,
User $user, $id, $error)
{
$cred = $engine->getCredentials();
//output the page
$title = $id ? _('Profile update for ').$user->getUsername()
: _('Profile update');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => 'user',
'text' => $title));
if(is_string($error))
$page->append('dialog', array('type' => 'error',
'text' => $error));
$r = new Request($this->name, 'update', $request->getID(),
$request->getID() ? $request->getTitle() : FALSE);
$form = $page->append('form', array('request' => $r));
//fields
//username (cannot be changed)
$form->append('label', array('text' => _('Username: ')));
$form->append('label', array('text' => $user->getUsername()));
//full name
if(($fullname = $request->get('fullname')) === FALSE)
$fullname = $user->getFullname();
$form->append('entry', array('text' => _('Full name: '),
'name' => 'fullname', 'value' => $fullname));
//e-mail address
if(($email = $request->get('email')) === FALSE)
$email = $user->getEmail();
$form->append('entry', array('text' => _('e-mail: '),
'name' => 'email', 'value' => $email));
//groups
$vbox = $form->append('vbox');
if($id && ($groups = Group::listAll($engine, TRUE)) !== FALSE)
{
//primary group
if(($group_id = $request->get('group_id')) === FALSE)
$group_id = $user->getGroupID();
$combobox = $vbox->append('combobox', array(
'text' => _('Primary group: '),
'name' => 'group_id',
'value' => $group_id));
foreach($groups as $group)
$combobox->append('label', array(
'text' => $group->getGroupname(),
'value' => $group->getGroupID()));
//secondary groups
$vbox->append('label', array(
'text' => _('Secondary groups:')));
$columns = array('group' => _('Group'),
'member' => _('Member'));
$view = $vbox->append('treeview', array(
'columns' => $columns,
'alternate' => TRUE));
foreach($groups as $group)
{
$r = new Request('group', 'list',
$group->getGroupID(),
$group->getGroupName());
$link = new PageElement('link', array(
'stock' => 'group',
'request' => $request,
'text' => $group->getGroupName()));
$checkbox = new PageElement('checkbox', array(
'name' => 'ids['.$group->getGroupID().']'));
if($user->isMember($engine, $group->getGroupName()))
$checkbox->set('value', TRUE);
$row = $view->append('row');
$row->set('group', $link);
$row->set('member', $checkbox);
}
}
//password
$form->append('label', array('text' => _('Optionally: ')));
if($id === FALSE && !$cred->isAdmin())
$form->append('entry', array(
'text' => _('Current password: '),
'name' => 'password', 'hidden' => TRUE));
$form->append('entry', array('text' => _('New password: '),
'name' => 'password1', 'hidden' => TRUE));
$form->append('entry', array(
'text' => _('Repeat new password: '),
'name' => 'password2', 'hidden' => TRUE));
//buttons
if($cred->isAdmin() && $request->getID() !== FALSE)
$r = $this->getRequest('admin');
else
$r = ($request->getID() !== FALSE)
? $user->getRequest($this->name, 'profile')
: $this->getRequest('profile');
$form->append('button', array('stock' => 'cancel',
'request' => $r, 'target' => '_cancel',
'text' => _('Cancel')));
$form->append('button', array('stock' => 'update',
'type' => 'submit', 'text' => _('Update')));
return $page;
}
//useful
//UserModule::actions
protected function actions(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$list = $this->configGet('list');
if($request->get('user') !== FALSE
|| $request->get('group') !== FALSE)
return FALSE;
$ret = array();
if($request->get('admin'))
return $this->_actions_admin($engine, $cred, $ret);
if($list == 1)
{
$r = $this->getRequest('list');
$icon = new PageElement('image', array(
'stock' => 'user'));
$link = new PageElement('link', array('request' => $r,
'text' => _('User list')));
$ret[] = new PageElement('row', array('icon' => $icon,
'important' => TRUE, 'label' => $link));
}
if($cred->getUserID() == 0)
{
//not logged in yet
$r = $this->getRequest('login');
$icon = new PageElement('image', array(
'stock' => 'login'));
$link = new PageElement('link', array('request' => $r,
'text' => _('Login')));
$ret[] = new PageElement('row', array('icon' => $icon,
'important' => TRUE,
'label' => $link));
if($this->canReset())
{
$r = $this->getRequest('reset');
$icon = new PageElement('image', array(
'stock' => 'reset'));
$link = new PageElement('link', array(
'request' => $r,
'text' => _('Password reset')));
$ret[] = new PageElement('row', array(
'icon' => $icon,
'label' => $link));
}
if($this->canRegister())
{
$r = $this->getRequest('register');
$icon = new PageElement('image', array(
'stock' => 'register'));
$link = new PageElement('link', array(
'request' => $r,
'text' => _('Register')));
$ret[] = new PageElement('row', array(
'icon' => $icon,
'label' => $link));
}
}
else
{
//already logged in
if($request->get('admin') != 0)
$this->_actions_admin($engine, $cred, $ret);
//user's content
$r = $this->getRequest('display');
$icon = new PageElement('image', array(
'stock' => 'user'));
$link = new PageElement('link', array('request' => $r,
'text' => _('My content')));
$ret[] = new PageElement('row', array('icon' => $icon,
'label' => $link));
//user's groups
$r = $this->getRequest('groups');
$icon = new PageElement('image', array(
'stock' => 'user'));
$link = new PageElement('link', array('request' => $r,
'text' => _('My groups')));
$ret[] = new PageElement('row', array('icon' => $icon,
'label' => $link));
//user's profile
$r = $this->getRequest('profile');
$icon = new PageElement('image', array(
'stock' => 'user'));
$link = new PageElement('link', array('request' => $r,
'text' => _('My profile')));
$ret[] = new PageElement('row', array('icon' => $icon,
'label' => $link));
//logout
$r = $this->getRequest('logout');
$icon = new PageElement('image', array(
'stock' => 'logout'));
$link = new PageElement('link', array('request' => $r,
'text' => _('Logout')));
$ret[] = new PageElement('row', array('icon' => $icon,
'important' => TRUE,
'label' => $link));
}
return $ret;
}
private function _actions_admin(Engine $engine, AuthCredentials $cred,
&$ret)
{
if(!$cred->isAdmin())
return $ret;
//user creation
$r = $this->getRequest('submit');
$icon = new PageElement('image', array('stock' => 'new'));
$link = new PageElement('link', array('request' => $r,
'text' => _('New user')));
$ret[] = new PageElement('row', array('icon' => $icon,
'label' => $link));
//administration
$r = $this->getRequest('admin');
$icon = new PageElement('image', array('stock' => 'admin'));
$link = new PageElement('link', array('request' => $r,
'text' => _('Users administration')));
$ret[] = new PageElement('row', array('icon' => $icon,
'label' => $link));
$r = $this->getRequest('admin', array('type' => 'group'));
return $ret;
}
//calls
//UserModule::callAdmin
protected function callAdmin(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$db = $engine->getDatabase();
$actions = array('disable' => _('Disable'),
'enable' => _('Enable'), 'lock' => _('Lock'),
'unlock' => _('Unlock'), 'delete' => _('Delete'));
$dialog = FALSE;
if(!$cred->isAdmin())
return new ErrorResponse(_('Permission denied'),
Response::$CODE_EPERM);
//perform actions if necessary
foreach($actions as $a => $t)
if($request->get($a) !== FALSE)
{
$a = '_admin'.$a;
$dialog = $this->$a($engine, $request);
break;
}
//list users
$title = _('Users administration');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
if($dialog !== FALSE)
$page->append($dialog);
$query = static::$query_admin;
//FIXME implement sorting
$query .= ' ORDER BY username ASC';
if(($res = $db->query($engine, $query)) === FALSE)
return new ErrorResponse(_('Could not list users'));
$columns = array('username' => _('Username'),
'group' => _('Group'),
'enabled' => _('Enabled'),
'locked' => _('Locked'),
'admin' => _('Administrator'),
'email' => _('e-mail'));
$r = $this->getRequest('admin');
$view = $page->append('treeview', array('request' => $r,
'view' => 'details', 'columns' => $columns));
//toolbar
$toolbar = $view->append('toolbar');
$toolbar->append('button', array('stock' => 'new',
'text' => _('New user'),
'request' => $this->getRequest('submit')));
$toolbar->append('button', array('stock' => 'refresh',
'text' => _('Refresh'),
'request' => $r));
foreach($actions as $value => $text)
$toolbar->append('button', array('stock' => $value,
'text' => $text, 'type' => 'submit',
'name' => 'action', 'value' => $value));
$no = new PageElement('image', array('stock' => 'no',
'size' => 16, 'title' => _('Disabled')));
$yes = new PageElement('image', array('stock' => 'yes',
'size' => 16, 'title' => _('Enabled')));
$locked = new PageElement('image', array('stock' => 'no',
'size' => 16, 'title' => _('Locked')));
$unlocked = new PageElement('image', array('stock' => 'yes',
'size' => 16, 'title' => _('Unlocked')));
foreach($res as $r)
{
$row = $view->append('row');
$row->set('id', 'ids['.$r['id'].']');
$row->set('username', $r['username']);
$request = new Request($this->name, 'update', $r['id'],
$r['username']);
$link = new PageElement('link', array('stock' => 'user',
'request' => $request,
'text' => $r['username']));
if($r['id'] != 0 && $db->isTrue($r['enabled']))
$row->set('username', $link);
$row->set('group', $r['groupname']);
$row->set('enabled', $db->isTrue($r['enabled'])
? $yes : $no);
$row->set('locked', ($r['locked'] == '!')
? $locked : $unlocked);
$row->set('admin', $db->isTrue($r['admin'])
? $yes : $no);
$link = new PageElement('link', array(
'url' => 'mailto:'.$r['email'],
'text' => $r['email']));
$row->set('email', $link);
}
$vbox = $page->append('vbox');
$request = $this->getRequest();
$vbox->append('link', array('request' => $request,
'stock' => 'user',
'text' => _('Back to my account')));
$request = new Request('admin');
$vbox->append('link', array('request' => $request,
'stock' => 'admin',
'text' => _('Back to the administration')));
return new PageResponse($page);
}
protected function _adminDelete(Engine $engine, Request $request)
{
return $this->helperApplyUser($engine, $request, 'delete',
$this->getRequest('admin'));
}
protected function _adminDisable(Engine $engine, Request $request)
{
return $this->helperApplyUser($engine, $request, 'disable',
$this->getRequest('admin'));
}
protected function _adminEnable(Engine $engine, Request $request)
{
return $this->helperApplyUser($engine, $request, 'enable',
$this->getRequest('admin'));
}
protected function _adminLock(Engine $engine, Request $request)
{
return $this->helperApplyUser($engine, $request, 'lock',
$this->getRequest('admin'));
}
protected function _adminUnlock(Engine $engine, Request $request)
{
return $this->helperApplyUser($engine, $request, 'unlock',
$this->getRequest('admin'));
}
//UserModule::callClose
protected function callClose(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$error = TRUE;
if($cred->getUserID() == 0)
//must be logged in
return $this->callDefault($engine, new Request());
$error = _('Unknown error');
if(!$this->canClose($engine, $error))
return new ErrorResponse($error, Response::$CODE_EPERM);
//process the request
if(($error = $this->_closeProcess($engine, $request)) === FALSE)
//closing was successful
return $this->_closeSuccess($engine, $request);
return $this->_closeForm($engine, $request, $error);
}
private function _closeForm(Engine $engine, Request $request, $error)
{
$title = _('Close your account');
$page = new Page(array('title' => $title));
$code = Response::$CODE_SUCCESS;
$page->append('title', array('stock' => $this->name,
'text' => $title));
if(is_string($error))
{
$page->append('dialog', array('type' => 'error',
'text' => $error));
$code = Response::$CODE_EUNKNOWN;
}
$form = $this->formClose($engine);
$page->append($form);
return new PageResponse($page, $code);
}
private function _closeProcess(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$uid = $cred->getUserID();
$username = $cred->getUsername();
//verify the request
if($request->isIdempotent())
return TRUE;
//disable the user
if(($user = User::lookup($engine, $username, $uid)) === FALSE
|| $user->disable($engine) !== TRUE)
return _('The account could not be closed');
//log the user out
$this->helperLogout($engine, $username, TRUE);
//no error
return FALSE;
}
protected function _closeSuccess(Engine $engine, Request $request)
{
$title = _('Account closed');
$text = _('Your account was closed successfully.');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
$vbox = $page->append('vbox');
$vbox->append('label', array('text' => $text));
$vbox->append('link', array('stock' => 'home',
'text' => _('Back to the homepage'),
'request' => new Request()));
return new PageResponse($page);
}
//UserModule::callDefault
protected function callDefault(Engine $engine, Request $request)
{
$db = $engine->getDatabase();
$query = static::$query_content;
$cred = $engine->getCredentials();
if(($id = $request->getID()) !== FALSE)
return $this->callDisplay($engine, $request);
//FIXME add content?
$title = ($cred->getUserID() != 0) ? _('My account')
: _('Site menu');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
//obtain the list of modules
if(($res = $db->query($engine, $query)) === FALSE)
return new ErrorResponse(_('Could not list modules'));
$vbox = $page->append('vbox');
$vbox->append('title'); //XXX to reduce the next level of titles
$vbox = $vbox->append('vbox');
foreach($res as $r)
{
$request = new Request($r['name'], 'actions',
FALSE, FALSE, array('admin' => 0));
$rows = $engine->process($request, TRUE);
if(!is_array($rows) || count($rows) == 0)
continue;
$request = new Request($r['name']);
$text = ucfirst($r['name']);
$link = new PageElement('link', array(
'request' => $request,
'text' => $text));
$title = $vbox->append('title', array(
'stock' => $r['name']));
$title->append($link);
$view = $vbox->append('iconview');
foreach($rows as $row)
$view->append($row);
}
$request = new Request();
$page->append('link', array('stock' => 'home',
'request' => $request,
'text' => _('Back to the homepage')));
return new PageResponse($page);
}
//UserModule::callDisable
protected function callDisable(Engine $engine, Request $request)
{
$error = _('Unknown error');
if($request->isIdempotent())
return new ErrorResponse(_('Permission denied'),
Response::$CODE_EPERM);
if(!$this->canDisable($engine, FALSE, $error))
return new ErrorResponse($error, Response::$CODE_EPERM);
if(($user = User::lookup($engine, $request->getTitle(),
$request->getID())) === FALSE)
return new ErrorResponse(_('Could not load user'),
Response::$CODE_ENOENT);
if(!$this->canDisable($engine, $user, $error))
return new ErrorResponse($user->getUsername()
.': '.$error, Response::$CODE_EPERM);
if(!$user->disable($engine, $error))
return new ErrorResponse($error);
return new StringResponse(_('User disabled successfully'));
}
//UserModule::callDisplay
protected function callDisplay(Engine $engine, Request $request)
{
$database = $engine->getDatabase();
$query = static::$query_content;
$cred = $engine->getCredentials();
$link = FALSE;
$user = FALSE;
//obtain the list of modules
if(($res = $database->query($engine, $query)) === FALSE)
return new ErrorResponse(_('Could not list modules'));
if(($uid = $request->getID()) !== FALSE)
{
$user = User::lookup($engine, $request->getTitle(),
$uid);
$title = _('Content from ').$request->getTitle();
}
else if(($uid = $cred->getUserID()) != 0)
{
$user = User::lookup($engine, $cred->getUsername(),
$uid);
$title = _('My content');
$r = $this->getRequest();
$link = new PageElement('link', array('stock' => 'user',
'request' => $r,
'text' => _('Back to my account')));
}
if($user === FALSE || $user->getUserID() == 0)
return $this->callLogin($engine, new Request());
$page = new Page(array('title' => $title));
//title
$page->append('title', array('stock' => $this->name,
'text' => $title));
$vbox = $page->append('vbox');
$vbox->append('title'); //XXX to reduce the next level of titles
$vbox2 = $vbox->append('vbox');
foreach($res as $r)
{
$request = new Request($r['name'], 'actions', FALSE,
FALSE, array('user' => $user));
$rows = $engine->process($request, TRUE);
if(!is_array($rows) || count($rows) == 0)
continue;
$text = ucfirst($r['name']);
$vbox2->append('title', array(
'stock' => $r['name'],
'text' => $text));
$view = $vbox2->append('iconview');
foreach($rows as $row)
$view->append($row);
}
//buttons
if($link !== FALSE)
$vbox->append($link);
if($this->configGet('list'))
{
$request = $this->getRequest('list');
$vbox->append('link', array('request' => $request,
'stock' => 'back',
'text' => _('Back to the user list')));
}
return new PageResponse($page);
}
//UserModule::callEnable
protected function callEnable(Engine $engine, Request $request)
{
$error = _('Unknown error');
if($request->isIdempotent())
return new ErrorResponse(_('Permission denied'),
Response::$CODE_EPERM);
if(!$this->canEnable($engine, FALSE, $error))
return new ErrorResponse($error, Response::$CODE_EPERM);
if(($user = User::lookup($engine, $request->getTitle(),
$request->getID(), FALSE)) === FALSE)
return new ErrorResponse(_('Could not load user'),
Response::$CODE_ENOENT);
if(!$this->canEnable($engine, $user, $error))
return new ErrorResponse($user->getUsername()
.': '.$error, Response::$CODE_EPERM);
if(!$user->enable($engine, $error))
return new ErrorResponse($error);
return new StringResponse(_('User enabled successfully'));
}
//UserModule::callGroups
protected function callGroups(Engine $engine, Request $request)
{
$database = $engine->getDatabase();
$query = static::$query_groups_user;
$cred = $engine->getCredentials();
$id = $request->getID();
//determine whose groups to view
if($id === FALSE)
$user = User::lookup($engine, $cred->getUsername(),
$cred->getUserID());
else
$user = User::lookup($engine, $request->getTitle(),
$id);
if($user === FALSE || ($id = $user->getUserID()) == 0)
//the anonymous user has no memberships
return new ErrorResponse(
_('There are no groups for this user'),
Response::$CODE_ENOENT);
if($id === $cred->getUserID())
//viewing own profile
$id = FALSE;
//output the page
$title = $id ? _('Groups for ').$user->getUsername()
: _('My groups');
$page = new Page(array('title' => $title));
$vbox = $page->append('vbox');
$vbox->append('title', array('stock' => 'user',
'text' => $title));
$args = array('user_id' => $user->getUserID());
if(($res = $database->query($engine, $query, $args)) === FALSE)
{
$error = _('Could not list the groups');
$page->append('dialog', array('type' => 'error',
'text' => $error));
return new PageResponse($page,
Response::$CODE_EUNKNOWN);
}
$columns = array('title' => _('Group'),
'count' => _('Members'));
$view = $vbox->append('treeview', array('columns' => $columns));
foreach($res as $group)
{
$r = new Request('group', FALSE, $group['id'],
$group['groupname']);
$group['title'] = new PageElement('link', array(
'request' => $r, 'stock' => 'group',
'text' => $group['groupname']));
$r = new Request('group', 'list', $group['id'],
$group['groupname']);
$group['count'] = new PageElement('link', array(
'request' => $r, 'stock' => 'group',
'text' => $group['count']));
$view->append('row', $group);
}
if($id === FALSE)
{
$r = $this->getRequest();
$vbox->append('link', array('stock' => 'user',
'request' => $r,
'text' => _('Back to my account')));
}
return new PageResponse($page);
}
//UserModule::callList
protected function callList(Engine $engine, Request $request)
{
$list = $this->configGet('list');
$cred = $engine->getCredentials();
$title = _('User list');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => 'login',
'text' => $title));
$vbox = $page->append('vbox');
if($list != 1)
{
$error = _('Permission denied');
$vbox->append('dialog', array('type' => 'error',
'text' => $error));
return new PageResponse($page, Response::$CODE_EPERM);
}
if(($users = User::listAll($engine, TRUE)) === FALSE)
{
$error = _('Could not list the users');
$vbox->append('dialog', array('type' => 'error',
'text' => $error));
return new PageResponse($page,
Response::$CODE_EUNKNOWN);
}
$columns = array('title' => 'Username',
'fullname' => 'Full name');
$view = $vbox->append('treeview', array('columns' => $columns));
foreach($users as $user)
{
$r = $user->getRequest($this->name);
$link = new PageElement('link', array('request' => $r,
'stock' => 'user',
'text' => $user->getUsername()));
$r = array('title' => $link,
'fullname' => $user->getFullname());
$view->append('row', $r);
}
//buttons
$r = $this->getRequest();
$text = $cred->getUserID() ? _('Back to my account')
: _('Back to the site menu');
$vbox->append('link', array('request' => $r, 'stock' => 'user',
'text' => $text));
$r = new Request();
$vbox->append('link', array('request' => $r, 'stock' => 'home',
'text' => _('Back to the homepage')));
return new PageResponse($page);
}
//UserModule::callLock
protected function callLock(Engine $engine, Request $request)
{
$error = _('Unknown error');
if($request->isIdempotent())
return new ErrorResponse(_('Permission denied'),
Response::$CODE_EPERM);
if(($user = User::lookup($engine, $request->getTitle(),
$request->getID())) === FALSE)
return new ErrorResponse(_('Could not load user'),
Response::$CODE_ENOENT);
if(!$this->canLock($engine, $user, $error))
return new ErrorResponse($user->getUsername()
.': '.$error, Response::$CODE_EPERM);
if(!$user->lock($engine, $error))
return new ErrorResponse($error);
return new StringResponse(_('User locked successfully'));
}
//UserModule::callLogin
protected function callLogin(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$title = _('User login');
$already = _('You are already logged in');
$forgot = _('I forgot my password...');
$register = _('Register an account...');
$code = Response::$CODE_SUCCESS;
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => 'login',
'text' => $title));
//process login
$error = $this->_loginProcess($engine, $request);
//login successful
if($error === FALSE)
return $this->_loginSuccess($engine, $request, $page);
else if(is_string($error))
{
$page->append('dialog', array('type' => 'error',
'text' => $error));
$code = Response::$CODE_EPERM;
}
else if($cred->getUserID() != 0)
$page->append('dialog', array('type' => 'info',
'text' => $already));
$form = $this->formLogin($engine, $request);
$page->append($form);
if($this->canReset())
{
$r = $this->getRequest('reset');
$page->append('link', array('request' => $r,
'stock' => 'reset',
'text' => $forgot));
}
if($this->canRegister())
{
$r = $this->getRequest('register');
$page->append('link', array('request' => $r,
'stock' => 'register',
'text' => $register));
}
return new PageResponse($page, $code);
}
protected function _loginProcess(Engine $engine, Request $request)
{
$db = $engine->getDatabase();
if($request->isIdempotent())
//no real login attempt
return TRUE;
if(($username = $request->get('username')) === FALSE
|| strlen($username) == 0
|| ($password = $request->get('password'))
=== FALSE)
return _('The username and password must be set');
if($this->helperLogin($engine, $username, $password) === FALSE)
return _('Invalid username or password');
return FALSE;
}
protected function _loginSuccess(Engine $engine, Request $request,
PageElement $page)
{
$parameters = $request->getParameters();
$p = array();
if(is_array($parameters))
//sanitize the parameters
foreach($parameters as $n => $v)
switch($n)
{
case 'module':
case 'action':
case 'id':
case 'title':
case 'username':
case 'password':
break;
default:
if(substr($n, 0, 1) == '_')
break;
$p[$n] = $v;
break;
}
$r = new Request($request->get('module'),
$request->get('action'), $request->get('id'),
$request->get('title'), $p);
$page->set('location', $engine->getURL($r));
$page->set('refresh', 30);
$box = $page->append('vbox');
$text = _('Authentication in progress, please wait...');
$box->append('label', array('text' => $text));
$box = $box->append('hbox');
$text = _('If you are not redirected within 30 seconds, please ');
$box->append('label', array('text' => $text));
$box->append('link', array('text' => _('click here'),
'request' => $r));
$box->append('label', array('text' => '.'));
return new PageResponse($page);
}
//UserModule::callLogout
protected function callLogout(Engine $engine, Request $request)
{
$title = _('User logout');
$cred = $engine->getCredentials();
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => 'logout',
'text' => $title));
if($cred->getUserID() == 0)
{
$text = _('You were logged out successfully');
$page->append('dialog', array('type' => 'info',
'text' => $text));
$r = new Request();
$page->append('link', array('stock' => 'home',
'request' => $r,
'text' => _('Back to the homepage')));
return new PageResponse($page);
}
$r = $this->getRequest('logout');
if($request->isIdempotent())
{
$form = $page->append('form', array(
'request' => $r));
$text = _('Do you really want to logout?');
$dialog = $form->append('dialog', array(
'type' => 'question', 'text' => $text));
$r = $this->getRequest();
$dialog->append('button', array('text' => _('Cancel'),
'stock' => 'cancel',
'target' => '_cancel',
'request' => $r));
$dialog->append('button', array('text' => _('Logout'),
'stock' => 'logout',
'type' => 'submit'));
return new PageResponse($page);
}
//process logout
$page->set('location', $engine->getURL($r));
$page->set('refresh', 30);
$box = $page->append('vbox');
$text = _('Logging out, please wait...');
$box->append('label', array('text' => $text));
$box = $box->append('hbox');
$text = _('If you are not redirected within 30 seconds, please ');
$box->append('label', array('text' => $text));
$box->append('link', array('text' => _('click here'),
'request' => $r));
$box->append('label', array('text' => '.'));
$this->helperLogout($engine, $cred->getUsername());
return new PageResponse($page);
}
//UserModule::callProfile
protected function callProfile(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$id = $request->getID();
$title = $request->getTitle();
//determine whose profile to view
if($id === FALSE)
$user = User::lookup($engine, $cred->getUsername(),
$cred->getUserID());
else
$user = User::lookup($engine, $title, $id);
if($user === FALSE || ($id = $user->getUserID()) == 0)
//the anonymous user has no profile
return new ErrorResponse(
_('There is no profile for this user'),
Response::$CODE_ENOENT);
if($id === $cred->getUserID())
//viewing own profile
$id = FALSE;
//output the page
$title = $id ? _('Profile for ').$user->getUsername()
: _('My profile');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => 'user',
'text' => $title));
$vbox = $page->append('vbox');
$hbox = $vbox->append('hbox');
$col1 = $hbox->append('vbox');
$col2 = $hbox->append('vbox');
$col1->append('label', array('class' => 'bold',
'text' => _('Fullname: ')));
$col2->append('label', array('text' => $user->getFullname()));
$col1->append('label', array('class' => 'bold',
'text' => _('e-mail: ')));
$col2->append('label', array('text' => $user->getEmail()));
//link to profile update
$r = $user->getRequest($this->name, 'update');
$button = FALSE;
if($request->getID() !== FALSE && $cred->isAdmin())
$button = new PageElement('button', array(
'stock' => 'admin', 'request' => $r,
'text' => _('Update')));
else if($id === FALSE)
$button = new PageElement('button', array(
'stock' => 'user', 'request' => $r,
'text' => _('Update')));
if($button !== FALSE)
$vbox->append($button);
if($id === FALSE)
{
$r = $this->getRequest();
$vbox->append('link', array('stock' => 'user',
'request' => $r,
'text' => _('Back to my account')));
if($this->canClose($engine))
{
$r = $this->getRequest('close');
$vbox->append('link', array('stock' => 'close',
'request' => $r,
'text' => _('Close my account')));
}
}
return new PageResponse($page);
}
//UserModule::callRegister
protected function callRegister(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$error = TRUE;
if($cred->getUserID() != 0)
//already registered and logged in
return $this->callDisplay($engine, new Request());
//process registration
if(!$request->isIdempotent()
&& $this->canRegister($request, $error)
&& $this->_registerProcess($engine, $request,
$error))
$error = FALSE;
if($error === FALSE)
//registration was successful
return $this->_registerSuccess($engine, $request);
return $this->_registerForm($engine, $request, $error);
}
private function _registerForm(Engine $engine, Request $request, $error)
{
$title = _('User registration');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
if(is_string($error))
$page->append('dialog', array('type' => 'error',
'text' => $error));
$username = $request->get('username');
$email = $request->get('email');
$form = $this->formRegister($engine, $username, $email);
$page->append($form);
return new PageResponse($page);
}
private function _registerProcess(Engine $engine, Request $request,
&$error)
{
$error = '';
if(($username = $request->get('username')) === FALSE)
$error .= _("A username is required\n");
if(($email = $request->get('email')) === FALSE)
$error .= _("An e-mail address is required\n");
if(strlen($error) > 0)
return FALSE;
//register the user
if(($user = User::register($engine, $this->name, $username,
FALSE, $email, FALSE, $error)) === FALSE)
return FALSE;
return TRUE;
}
private function _registerSuccess(Engine $engine, Request $request)
{
$title = _('User registration');
$text = _("You should receive an e-mail shortly with your password, along with a confirmation key.\n
Thank you for registering!");
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
$page->append('dialog', array('type' => 'info',
'text' => $text));
$page->append('link', array('stock' => 'home',
'text' => _('Back to the homepage'),
'request' => new Request()));
return new PageResponse($page);
}
//UserModule::callReset
protected function callReset(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$error = TRUE;
if($cred->getUserID() != 0)
//already registered and logged in
return $this->callDisplay($engine, new Request());
if(($uid = $request->getID()) !== FALSE
&& ($token = $request->get('token')) !== FALSE)
return $this->_resetToken($engine, $request, $uid,
$token);
//process reset
if(!$request->isIdempotent()
&& $this->canReset($request, $error)
&& $this->_resetProcess($engine, $request,
$error))
$error = FALSE;
if($error === FALSE)
//reset was successful
return $this->_resetSuccess($engine, $request);
return $this->_resetForm($engine, $request, $error);
}
private function _resetForm(Engine $engine, Request $request, $error)
{
$title = _('Password reset');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
if(is_string($error))
$page->append('dialog', array('type' => 'error',
'text' => $error));
$username = $request->get('username');
$email = $request->get('email');
$form = $this->formReset($engine, $username, $email);
$page->append($form);
return new PageResponse($page);
}
private function _resetProcess(Engine $engine, Request $request,
&$error)
{
$error = '';
if(($username = $request->get('username')) === FALSE)
$error .= _("Your username is required\n");
if(($email = $request->get('email')) === FALSE)
$error .= _("Your e-mail address is required\n");
if(strlen($error) > 0)
return FALSE;
//send a reset token to the user
if(($user = User::reset($engine, $this->name, $username, $email,
$error)) === FALSE)
return FALSE;
return TRUE;
}
private function _resetSuccess(Engine $engine, Request $request)
{
$title = _('Password reset');
$text = _("You should receive an e-mail shortly, with a link allowing you to reset your password.");
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
$page->append('dialog', array('type' => 'info',
'text' => $text));
$page->append('link', array('stock' => 'home',
'text' => _('Back to the homepage'),
'request' => new Request()));
return new PageResponse($page);
}
private function _resetToken(Engine $engine, Request $request, $uid,
$token)
{
$error = TRUE;
//process reset
if(!$this->canReset())
$error = _('Password resets are not allowed');
else if(!$request->isIdempotent())
$error = $this->_resetTokenProcess($engine, $request,
$uid, $token);
if($error === FALSE)
//reset was successful
return $this->_resetTokenSuccess($engine, $request);
return $this->_resetTokenForm($engine, $request, $uid, $token,
$error);
}
private function _resetTokenForm(Engine $engine, Request $request, $uid,
$token, $error)
{
$title = _('Password reset');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
if(is_string($error))
$page->append('dialog', array('type' => 'error',
'text' => $error));
$r = new Request($this->name, 'reset', $uid, FALSE,
array('token' => $token));
$form = $page->append('form', array('request' => $r));
$form->append('entry', array('text' => _('Password: '),
'name' => 'password', 'hidden' => TRUE));
$form->append('entry', array('text' => _('Repeat password: '),
'name' => 'password2', 'hidden' => TRUE));
$form->append('button', array('stock' => 'cancel',
'text' => _('Cancel'),
'request' => $this->getRequest()));
$form->append('button', array('stock' => 'reset',
'type' => 'submit', 'text' => _('Reset')));
return new PageResponse($page);
}
private function _resetTokenProcess(Engine $engine, Request $request,
$uid, $token)
{
$ret = '';
if(($password = $request->get('password')) === FALSE)
$ret .= _('A new password is required');
else if(($password2 = $request->get('password2')) === FALSE
|| $password !== $password2)
$ret .= _('The passwords did not match');
if(strlen($ret) > 0)
return $ret;
//reset the password
$error = '';
if(User::resetPassword($engine, $uid, $password, $token, $error)
=== FALSE)
$ret .= $error;
return strlen($ret) ? $ret : FALSE;
}
private function _resetTokenSuccess(Engine $engine, Request $request)
{
$title = _('Password reset');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
$page->append('dialog', array('type' => 'info',
'text' => _("Your password was reset successfully.\n")));
$page->append('link', array('stock' => 'home',
'text' => _('Back to the homepage'),
'request' => new Request()));
$page->append('link', array('stock' => 'login',
'text' => _('Proceed to login page'),
'request' => $this->getRequest('login')));
return new PageResponse($page);
}
//UserModule::callSubmit
protected function callSubmit(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$title = _('New user');
//check permissions
$error = _('Permission denied');
if($this->canSubmit($engine, $error) === FALSE)
return new PageResponse($error, Response::$CODE_EPERM);
//create the page
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
//process the request
$user = FALSE;
if(($error = $this->_submitProcess($engine, $request, $user))
=== FALSE)
return $this->_submitSuccess($engine, $request, $page,
$user);
else if(is_string($error))
$page->append('dialog', array('type' => 'error',
'text' => $error));
//form
$form = $this->formSubmit($engine, $request);
$page->append($form);
return new PageResponse($page);
}
protected function _submitProcess(Engine $engine, Request $request,
&$user)
{
//verify the request
if($request->get('submit') === FALSE)
return TRUE;
if($request->isIdempotent() !== FALSE)
return _('The request expired or is invalid');
if(($username = $request->get('username')) === FALSE)
return _('Invalid arguments');
$enabled = $request->get('enabled') ? TRUE : FALSE;
$locked = $request->get('locked') ? TRUE : FALSE;
$admin = $request->get('admin') ? TRUE : FALSE;
//create the user
$error = FALSE;
$user = User::insert($engine, $username,
$request->get('group_id'),
$request->get('fullname'),
$request->get('password'),
$request->get('email'),
$enabled, $locked, $admin, $error);
if($user === FALSE)
return $error;
//set the group memberships
if(($ids = $request->get('ids')) !== FALSE && is_array($ids))
foreach($ids as $id)
$user->addGroup($engine, $id);
//no error
return FALSE;
}
protected function _submitSuccess(Engine $engine, Request $request,
$page, User $user)
{
$r = $user->isEnabled()
? $user->getRequest($this->name)
: $this->getRequest('admin');
return $this->helperRedirect($engine, $r, $page);
}
//UserModule::callUnlock
protected function callUnlock(Engine $engine, Request $request)
{
$error = _('Unknown error');
if($request->isIdempotent())
return new ErrorResponse(_('Permission denied'),
Response::$CODE_EPERM);
if(($user = User::lookup($engine, $request->getTitle(),
$request->getID())) === FALSE)
return new ErrorResponse(_('Could not load user'),
Response::$CODE_ENOENT);
if(!$this->canUnlock($engine, $user, $error))
return new ErrorResponse($user->getUsername()
.': '.$error, Response::$CODE_EPERM);
if(!$user->unlock($engine, $error))
return new ErrorResponse($error);
return new StringResponse(_('User unlocked successfully'));
}
//UserModule::callUpdate
protected function callUpdate(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$id = $request->getID();
$title = $request->getTitle();
$error = TRUE;
//determine whose profile to update
if($id === FALSE)
$user = User::lookup($engine, $cred->getUsername(),
$cred->getUserID());
else
$user = User::lookup($engine, $title, $id);
if($user === FALSE || ($id = $user->getUserID()) == 0)
{
//the anonymous user has no profile
$error = _('There is no profile for this user');
return new ErrorResponse($error,
Response::$CODE_ENOENT);
}
if($id === $cred->getUserID())
//viewing own profile
$id = FALSE;
if($id !== FALSE && !$cred->isAdmin())
return new ErrorResponse(_('Permission denied'),
Response::$CODE_EPERM);
//process update
if(!$request->isIdempotent())
$error = $this->_updateProcess($engine, $request,
$user);
if($error === FALSE)
//update was successful
return $this->_updateSuccess($engine, $request);
$page = $this->formUpdate($engine, $request, $user, $id,
$error);
return new PageResponse($page);
}
private function _updateProcess(Engine $engine, Request $request,
User $user)
{
$ret = '';
$db = $engine->getDatabase();
$cred = $engine->getCredentials();
if(($fullname = $request->get('fullname')) === FALSE)
$ret .= _("The full name is required\n");
if(($email = $request->get('email')) === FALSE)
$ret .= _("The e-mail address is required\n");
if(strlen($ret) > 0)
return $ret;
//update the profile
$error = '';
$args = array('user_id' => $user->getUserID(),
'fullname' => $fullname, 'email' => $email);
if($db->query($engine, static::$query_update, $args) === FALSE)
return _('Could not update the profile');
//update the group if authorized, set and changed
if($cred->isAdmin()
&& ($group_id = $request->get('group_id'))
!== FALSE
&& $group_id != $user->getGroupID())
$user->setGroup($engine, $group_id);
//update the group memberships
$db->withTransaction($engine, function()
use ($engine, $request, $user)
{
$user->removeGroups($engine);
if(($ids = $request->get('ids')) !== FALSE
&& is_array($ids))
foreach($ids as $id)
$user->addGroup($engine, $id);
});
//update the password if requested
if(($password1 = $request->get('password1')) === FALSE
|| strlen($password1) == 0
|| ($password2 = $request->get('password2'))
=== FALSE
|| strlen($password2) == 0)
return FALSE;
//check the current password (if not an admin)
if(!$cred->isAdmin())
{
$error = _('The current password must be specified');
if(($password = $request->get('password')) === FALSE
|| strlen($password) == 0)
return $error;
if($user->authenticate($engine, $password) === FALSE)
return $error;
}
//verify that the new password matches
if($password1 != $password2)
return _('The new password does not match');
if(!$user->setPassword($engine, $password1))
return _('Could not set the new password');
return FALSE;
}
private function _updateSuccess(Engine $engine, Request $request)
{
$id = $request->getID();
$title = _('Profile update');
$page = new Page(array('title' => $title));
$page->append('title', array('stock' => $this->name,
'text' => $title));
$info = $id ? _('The profile was updated successfully')
: _('Your profile was updated successfully');
$dialog = $page->append('dialog', array('type' => 'info',
'text' => $info));
if($id)
{
$r = $this->getRequest('admin');
$dialog->append('button', array('stock' => 'admin',
'request' => $r,
'text' => _('User administration')));
$text = _('User profile');
}
else
$text = _('My profile');
$r = new Request($this->name, 'profile', $id,
$request->getTitle());
$dialog->append('button', array('stock' => 'user',
'request' => $r, 'text' => $text));
return new PageResponse($page);
}
//UserModule::callValidate
protected function callValidate(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
$error = TRUE;
$uid = $request->getID();
$token = $request->get('token');
if($cred->getUserID() != 0)
//already registered and logged in
return $this->callDisplay($engine, new Request());
$page = new Page(array('title' => _('Account confirmation')));
$page->append('title', array('stock' => $this->name,
'text' => _('Account confirmation')));
if(!$this->canRegister())
{
$page->append('dialog', array('type' => 'error',
'text' => _('Registering is not allowed')));
return new PageResponse($page, Response::$CODE_EPERM);
}
$box = $page->append('vbox');
if(($user = User::validate($engine, $uid, $token, $error))
=== FALSE)
$box->append('dialog', array('type' => 'error',
'text' => $error));
else
{
$box->append('dialog', array('type' => 'info',
'title' => _('Congratulations!'),
'text' => _('Your account is now enabled.')));
$r = $this->getRequest();
$box->append('link', array('stock' => 'login',
'request' => $r,
'text' => _('Login')));
}
$r = new Request();
$box->append('link', array('stock' => 'home', 'request' => $r,
'text' => _('Back to the homepage')));
return new PageResponse($page);
}
//UserModule::callWidget
protected function callWidget(Engine $engine, Request $request)
{
$cred = $engine->getCredentials();
if($cred->getUserID() == 0)
return $this->_widgetLogin($engine, $request);
$box = new PageElement('vbox');
$r = $this->getRequest();
$box->append('button', array('stock' => 'home',
'request' => $r, 'text' => _('My account')));
$r = $this->getRequest('display');
$box->append('button', array('stock' => 'user',
'request' => $r, 'text' => _('My content')));
$r = $this->getRequest('update');
$box->append('button', array('stock' => 'user',
'request' => $r, 'text' => _('My profile')));
$r = $this->getRequest('logout');
$box->append('button', array('stock' => 'logout',
'request' => $r, 'text' => _('Logout')));
return new PageResponse($box);
}
protected function _widgetLogin(Engine $engine, Request $request)
{
$parameters = $request->getParameters();
$request = $engine->getRequest();
$parameters['module'] = $request->getModule();
$parameters['action'] = $request->getAction();
$parameters['id'] = $request->getID();
$parameters['title'] = $request->getTitle();
$parameters = array_merge($parameters,
$request->getParameters());
$request = $this->getRequest('login', $parameters);
$widget = $this->formLogin($engine, $request, FALSE);
return new PageResponse($widget);
}
//helpers
//UserModule::helperApplyUser
protected function helperApplyUser(Engine $engine, Request $request,
$action, $fallback, $key = 'user_id')
{
$cred = $engine->getCredentials();
//FIXME use $this->can$action() instead
if(!$cred->isAdmin())
//must be admin
return new PageElement('dialog', array(
'type' => 'error',
'text' => _('Permission denied')));
if($request->isIdempotent())
//must be safe
return FALSE;
$invalid = 0;
$errors = 0;
$success = 0;
$message = '';
$sep = '';
if(($ids = $request->get('ids')) === FALSE || !is_array($ids))
$ids = array();
foreach($ids as $id)
{
$user = new User($engine, $id);
if($user->getUserID() === FALSE) //XXX
$invalid++;
else if($user->$action($engine) === FALSE)
$errors++;
else
$success++;
}
$type = $errors ? 'error' : ($invalid ? 'warning' : 'info');
if($errors)
{
$message .= "Could not $action $errors user(s)";
$sep = "\n";
}
if($invalid)
{
$message .= $sep.$invalid.' '._('invalid user(s)');
$sep = "\n";
}
if($success)
$message .= $sep."Could $action $success user(s)";
if($message == '')
return FALSE;
return new PageElement('dialog', array('type' => $type,
'text' => $message));
}
//UserModule::helperLogin
protected function helperLogin(Engine $engine, $username, $password)
{
$log = $this->configGet('log');
if(($user = User::lookup($engine, $username)) === FALSE
|| ($credentials = $user->authenticate($engine,
$password)) === FALSE)
return $engine->log(LOG_NOTICE, $username
.': Invalid login attempt');
if($engine->setCredentials($credentials) !== TRUE)
return $engine->log(LOG_NOTICE, $username
.': Unable to log user in');
if($log)
$engine->log(LOG_NOTICE,
$username.': User logged in');
return TRUE;
}
//UserModule::helperLogout
protected function helperLogout(Engine $engine, $username,
$closed = FALSE)
{
$log = $this->configGet('log');
if($engine->setCredentials() === FALSE)
return $engine->log(LOG_ERR, $username
.': Unable to log user out');
if($log)
$engine->log(LOG_NOTICE, $username
.': User logged out');
if($log && $closed)
$engine->log(LOG_NOTICE,
$username.': User account closed');
return TRUE;
}
//UserModule::helperRedirect
protected function helperRedirect(Engine $engine, Request $request,
PageElement $page, $text = FALSE)
{
if($text === FALSE)
$text = _('Redirection in progress, please wait...');
$page->set('location', $engine->getURL($request));
$page->set('refresh', 30);
$box = $page->append('vbox');
$box->append('label', array('text' => $text));
$box = $box->append('hbox');
$text = _('If you are not redirected within 30 seconds, please ');
$box->append('label', array('text' => $text));
$box->append('link', array('text' => _('click here'),
'request' => $request));
$box->append('label', array('text' => '.'));
return new PageResponse($page);
}
//private
//properties
//queries
static private $query_admin = 'SELECT user_id AS id, username, admin,
daportal_user.enabled AS enabled, email,
daportal_group.group_id AS group_id, groupname,
substr(password, 1, 1) AS locked
FROM daportal_user
LEFT JOIN daportal_group
ON daportal_user.group_id=daportal_group.group_id';
static private $query_content = "SELECT name FROM daportal_module
WHERE enabled='1' ORDER BY name ASC";
//IN: user_id
static private $query_groups_user = 'SELECT dug.group_id AS id,
groupname, COUNT(member.user_id) AS count
FROM daportal_user_group dug, daportal_group,
daportal_user_group member
WHERE dug.group_id=daportal_group.group_id
AND dug.user_id=:user_id
AND daportal_group.group_id=member.group_id
GROUP BY dug.group_id, groupname
ORDER BY groupname ASC';
//IN: user_id
// fullname
// email
static private $query_update = 'UPDATE daportal_user
SET fullname=:fullname, email=:email
WHERE user_id=:user_id';
}
?>