mirror of https://github.com/MISP/MISP
chg: [security] admins can delete user TOTP
parent
28cec403b9
commit
856a9e4b4c
|
@ -747,6 +747,7 @@ class ACLComponent extends Component
|
|||
'email_otp' => array('*'),
|
||||
'totp' => array('*'),
|
||||
'totp_new' => array('*'),
|
||||
'totp_delete' => array('perm_admin'),
|
||||
'searchGpgKey' => array('*'),
|
||||
'fetchGpgKey' => array('*'),
|
||||
'histogram' => array('*'),
|
||||
|
|
|
@ -67,6 +67,7 @@ class UsersController extends AppController
|
|||
$user['User']['pgp_status'] = isset($pgpDetails[2]) ? $pgpDetails[2] : 'OK';
|
||||
$user['User']['fingerprint'] = !empty($pgpDetails[4]) ? $pgpDetails[4] : 'N/A';
|
||||
}
|
||||
// FIXME chri - show warning for TOTP if LinOTP is enabled
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($this->__massageUserObject($user), $this->response->type());
|
||||
} else {
|
||||
|
@ -88,6 +89,7 @@ class UsersController extends AppController
|
|||
unset($user['User']['authkey']);
|
||||
}
|
||||
$user['User']['password'] = '*****';
|
||||
$user['User']['totp'] = '*****';
|
||||
$temp = [];
|
||||
$objectsToInclude = array('User', 'Role', 'UserSetting', 'Organisation');
|
||||
foreach ($objectsToInclude as $objectToInclude) {
|
||||
|
@ -588,17 +590,7 @@ class UsersController extends AppController
|
|||
unset($user['User']['authkey']);
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
$user['User']['password'] = '*****';
|
||||
$temp = array();
|
||||
foreach ($user['UserSetting'] as $v) {
|
||||
$temp[$v['setting']] = $v['value'];
|
||||
}
|
||||
$user['UserSetting'] = $temp;
|
||||
return $this->RestResponse->viewData(array(
|
||||
'User' => $user['User'],
|
||||
'Role' => $user['Role'],
|
||||
'UserSetting' => $user['UserSetting']
|
||||
), $this->response->type());
|
||||
return $this->RestResponse->viewData($this->__massageUserObject($user), $this->response->type());
|
||||
}
|
||||
$this->set('user', $user);
|
||||
|
||||
|
@ -1788,12 +1780,22 @@ class UsersController extends AppController
|
|||
}
|
||||
}
|
||||
|
||||
public function totp_new($id = null)
|
||||
public function totp_new()
|
||||
{
|
||||
// FIXME chri - reuse $id to load user if (org)site admin
|
||||
$user = $this->Auth->user();
|
||||
// only allow the users themselves to generate a TOTP secret.
|
||||
// If TOTP is enforced they will be invited to generate it at first login
|
||||
$user = $this->User->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('User.id' => $this->Auth->user('id')),
|
||||
'fields' => array(
|
||||
'totp', 'email', 'id'
|
||||
)
|
||||
));
|
||||
if (empty($user)) {
|
||||
throw new NotFoundException(__('Invalid user'));
|
||||
}
|
||||
// do not allow this page to be accessed if the current already has a TOTP. Just redirect to the users details page with a Flash->error()
|
||||
if ($user['totp']) {
|
||||
if ($user['User']['totp']) {
|
||||
$this->Flash->error(__("Your account already has an TOTP. Please contact your organisational administrator to change or delete it."));
|
||||
$this->redirect($this->referer());
|
||||
}
|
||||
|
@ -1810,7 +1812,7 @@ class UsersController extends AppController
|
|||
$otp_now = $otp->now();
|
||||
if (trim($this->request->data['User']['otp']) == $otp_now) {
|
||||
// we know the user can generate TOTP tokens, save the new TOTP to the database
|
||||
$this->User->id = $user['id'];
|
||||
$this->User->id = $user['User']['id'];
|
||||
$this->User->saveField('totp', $secret);
|
||||
$this->Flash->info(__('The OTP is correct and now active for your account.'));
|
||||
$this->redirect(array('controller' => 'events', 'action'=> 'index'));
|
||||
|
@ -1826,13 +1828,46 @@ class UsersController extends AppController
|
|||
new \BaconQrCode\Renderer\Image\SvgImageBackEnd()
|
||||
);
|
||||
$writer = new \BaconQrCode\Writer($renderer);
|
||||
$qrcode = $writer->writeString('otpauth://totp/' . Configure::read('MISP.org') . ' MISP (' . $user['email'] . ')?secret=' . $secret);
|
||||
$qrcode = $writer->writeString('otpauth://totp/' . Configure::read('MISP.org') . ' MISP (' . $user['User']['email'] . ')?secret=' . $secret);
|
||||
$writer = preg_replace('/^.+\n/', '', $qrcode); // ignore first <?xml version line
|
||||
|
||||
$this->set('qrcode', $qrcode);
|
||||
$this->set('secret', $secret);
|
||||
}
|
||||
|
||||
public function totp_delete($id) {
|
||||
if ($this->request->is('post') || $this->request->is('delete')) {
|
||||
$user = $this->User->find('first', array(
|
||||
'conditions' => $this->__adminFetchConditions($id),
|
||||
'recursive' => -1
|
||||
));
|
||||
if (empty($user)) {
|
||||
throw new NotFoundException(__('Invalid user'));
|
||||
}
|
||||
$this->User->id = $id;
|
||||
if ($this->User->saveField('totp', null)) {
|
||||
$fieldsDescrStr = 'User (' . $id . '): ' . $user['User']['email'] . 'TOTP deleted';
|
||||
$this->User->extralog($this->Auth->user(), "update", $fieldsDescrStr, '');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('User', 'admin_totp_delete', $id, $this->response->type(), 'User TOTP deleted.');
|
||||
} else {
|
||||
$this->Flash->success(__('User TOTP deleted'));
|
||||
$this->redirect('/admin/users/index');
|
||||
}
|
||||
}
|
||||
$this->Flash->error(__('User TOTP was not deleted'));
|
||||
$this->redirect('/admin/users/index');
|
||||
} else {
|
||||
$this->set(
|
||||
'question',
|
||||
__('Are you sure you want to delete the TOTP of the user?.')
|
||||
);
|
||||
$this->set('title', __('Delete user TOTP'));
|
||||
$this->set('actionName', 'Delete');
|
||||
$this->render('/genericTemplates/confirm');
|
||||
}
|
||||
}
|
||||
|
||||
public function email_otp()
|
||||
{
|
||||
$user = $this->Session->read('email_otp_user');
|
||||
|
|
|
@ -138,6 +138,16 @@
|
|||
'privacy' => 1,
|
||||
'requirement' => empty(Configure::read('Security.advanced_authkeys'))
|
||||
),
|
||||
array(
|
||||
'name' => '',
|
||||
'header_title' => __('TOTP'),
|
||||
'icon' => 'mobile',
|
||||
'element' => 'boolean',
|
||||
'sort' => 'User.totp',
|
||||
'class' => 'short',
|
||||
'data_path' => 'User.totp',
|
||||
'colors' => true,
|
||||
),
|
||||
array(
|
||||
'name' => '',
|
||||
'header_title' => __('Contact alert'),
|
||||
|
|
|
@ -25,7 +25,8 @@ $boolean = sprintf(
|
|||
$isTotp ? __('Yes') : __('No'));
|
||||
$totpHtml = $boolean;
|
||||
$totpHtml .= ($isTotp ? '' : $this->Html->link(__('Generate'), array('action' => 'totp_new', $user['User']['id'])));
|
||||
$totpHtml .= ($admin_view && $isTotp ? ' ' . __('Delete') : ''); // FIXME chri - only allow delete for (org)admin
|
||||
|
||||
$totpHtml .= ($admin_view && $isTotp ? ' ' . $this->Form->postLink(__('Delete'), array('action' => 'totp_delete', $user['User']['id'])) : ''); // FIXME chri - only allow delete for (org)admin
|
||||
|
||||
|
||||
$table_data = [
|
||||
|
|
Loading…
Reference in New Issue