183 lines
4.7 KiB
PHP
183 lines
4.7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Storage backend to use the Roundcube user prefs to store 2-Factor-Authentication settings
|
|
*
|
|
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
|
*
|
|
* Copyright (C) 2015, Kolab Systems AG <contact@kolabsys.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* 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 Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
namespace Kolab2FA\Storage;
|
|
|
|
use \rcmail;
|
|
use \rcube_user;
|
|
|
|
class RcubeUser extends Base
|
|
{
|
|
// sefault config
|
|
protected $config = array(
|
|
'keymap' => array(),
|
|
);
|
|
|
|
private $cache = array();
|
|
private $user;
|
|
|
|
public function init(array $config)
|
|
{
|
|
parent::init($config);
|
|
|
|
$rcmail = rcmail::get_instance();
|
|
$this->config['hostname'] = $rcmail->user->ID ? $rcmail->user->data['mail_host'] : $_SESSION['hostname'];
|
|
}
|
|
|
|
/**
|
|
* List/set methods activated for this user
|
|
*/
|
|
public function enumerate()
|
|
{
|
|
if ($factors = $this->get_factors()) {
|
|
return array_keys(array_filter($factors, function($prop) {
|
|
return !empty($prop['active']);
|
|
}));
|
|
}
|
|
|
|
return array();
|
|
}
|
|
|
|
/**
|
|
* Read data for the given key
|
|
*/
|
|
public function read($key)
|
|
{
|
|
if (!isset($this->cache[$key])) {
|
|
$factors = $this->get_factors();
|
|
console('READ', $key, $factors);
|
|
$this->cache[$key] = $factors[$key];
|
|
}
|
|
|
|
return $this->cache[$key];
|
|
}
|
|
|
|
/**
|
|
* Save data for the given key
|
|
*/
|
|
public function write($key, $value)
|
|
{
|
|
if ($user = $this->get_user($this->username)) {
|
|
$this->cache[$key] = $value;
|
|
|
|
$factors = $this->get_factors();
|
|
$factors[$key] = $value;
|
|
|
|
$pkey = $this->key2property('blob');
|
|
$save_data = array($pkey => $factors);
|
|
$update_index = false;
|
|
|
|
// remove entry
|
|
if ($value === null) {
|
|
unset($factors[$key]);
|
|
$update_index = true;
|
|
}
|
|
// remove non-active entries
|
|
else if (!empty($value['active'])) {
|
|
$factors = array_filter($factors, function($prop) {
|
|
return !empty($prop['active']);
|
|
});
|
|
$update_index = true;
|
|
}
|
|
|
|
// update the index of active factors
|
|
if ($update_index) {
|
|
$save_data[$this->key2property('factors')] = array_keys(
|
|
array_filter($factors, function($prop) {
|
|
return !empty($prop['active']);
|
|
})
|
|
);
|
|
}
|
|
|
|
return $user->save_prefs($save_data, true);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Remove the data stoed for the given key
|
|
*/
|
|
public function remove($key)
|
|
{
|
|
return $this->write($key, null);
|
|
}
|
|
|
|
/**
|
|
* Set username to store data for
|
|
*/
|
|
public function set_username($username)
|
|
{
|
|
parent::set_username($username);
|
|
|
|
// reset cached values
|
|
$this->cache = array();
|
|
$this->user = null;
|
|
}
|
|
|
|
/**
|
|
* Helper method to get a rcube_user instance for storing prefs
|
|
*/
|
|
private function get_user($username)
|
|
{
|
|
// use global instance if we have a valid Roundcube session
|
|
$rcmail = rcmail::get_instance();
|
|
if ($rcmail->user->ID && $rcmail->user->get_username() == $username) {
|
|
return $rcmail->user;
|
|
}
|
|
|
|
if (!$this->user) {
|
|
$this->user = rcube_user::query($username, $this->config['hostname']);
|
|
}
|
|
|
|
return $this->user;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
private function get_factors()
|
|
{
|
|
if ($user = $this->get_user($this->username)) {
|
|
$prefs = $user->get_prefs();
|
|
return (array)$prefs[$this->key2property('blob')];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
private function key2property($key)
|
|
{
|
|
// map key to configured property name
|
|
if (is_array($this->config['keymap']) && isset($this->config['keymap'][$key])) {
|
|
return $this->config['keymap'][$key];
|
|
}
|
|
|
|
// default
|
|
return 'kolab_2fa_' . $key;
|
|
}
|
|
|
|
}
|