roundcubemail-plugins-kolab/plugins/kolab_2fa/lib/Kolab2FA/Storage/RcubeUser.php

184 lines
4.7 KiB
PHP
Raw Normal View History

<?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;
}
}