Browse Source

Merge pull request #3023 from nextcloud/issue-2915-filter-out-sensitive-appconfigs

Filter out sensitive appconfig values
tags/v12.0.0beta1
Christoph Wurst 7 years ago
parent
commit
012708e1ba

+ 17
- 2
core/Command/Config/ListConfigs.php View File

'apps' => [], 'apps' => [],
]; ];
foreach ($apps as $appName) { foreach ($apps as $appName) {
$configs['apps'][$appName] = $this->appConfig->getValues($appName, false);
$configs['apps'][$appName] = $this->getAppConfigs($appName, $noSensitiveValues);
} }
break; break;


default: default:
$configs = [ $configs = [
'apps' => [ 'apps' => [
$app => $this->appConfig->getValues($app, false),
$app => $this->getAppConfigs($app, $noSensitiveValues),
], ],
]; ];
} }
return $configs; return $configs;
} }


/**
* Get the app configs
*
* @param string $app
* @param bool $noSensitiveValues
* @return array
*/
protected function getAppConfigs($app, $noSensitiveValues) {
if ($noSensitiveValues) {
return $this->appConfig->getFilteredValues($app, false);
} else {
return $this->appConfig->getValues($app, false);
}
}

/** /**
* @param string $argumentName * @param string $argumentName
* @param CompletionContext $context * @param CompletionContext $context

+ 1
- 1
lib/private/AllConfig.php View File

/** /**
* @param SystemConfig $systemConfig * @param SystemConfig $systemConfig
*/ */
function __construct(SystemConfig $systemConfig) {
public function __construct(SystemConfig $systemConfig) {
$this->userCache = new CappedMemoryCache(); $this->userCache = new CappedMemoryCache();
$this->systemConfig = $systemConfig; $this->systemConfig = $systemConfig;
} }

+ 47
- 8
lib/private/AppConfig.php View File



namespace OC; namespace OC;


use OC\DB\OracleConnection;
use OCP\IAppConfig; use OCP\IAppConfig;
use OCP\IConfig;
use OCP\IDBConnection; use OCP\IDBConnection;


/** /**
* database. * database.
*/ */
class AppConfig implements IAppConfig { class AppConfig implements IAppConfig {
/**
* @var \OCP\IDBConnection $conn
*/

/** @var array[] */
protected $sensitiveValues = [
'user_ldap' => [
'ldap_agent_password',
],
];

/** @var \OCP\IDBConnection */
protected $conn; protected $conn;


private $cache = array();
/** @var array[] */
private $cache = [];

/** @var bool */
private $configLoaded = false;


/** /**
* @param IDBConnection $conn * @param IDBConnection $conn
* *
* @param string $app the app we are looking for * @param string $app the app we are looking for
* @return array an array of key names * @return array an array of key names
* @deprecated 8.0.0 use method getAppKeys of \OCP\IConfig
* *
* This function gets all keys of an app. Please note that the values are * This function gets all keys of an app. Please note that the values are
* not returned. * not returned.
* @param string $key key * @param string $key key
* @param string $default = null, default value if the key does not exist * @param string $default = null, default value if the key does not exist
* @return string the value or $default * @return string the value or $default
* @deprecated 8.0.0 use method getAppValue of \OCP\IConfig
* *
* This function gets a value from the appconfig table. If the key does * This function gets a value from the appconfig table. If the key does
* not exist the default value will be returned * not exist the default value will be returned
* @param string $key key * @param string $key key
* @param string|float|int $value value * @param string|float|int $value value
* @return bool True if the value was inserted or updated, false if the value was the same * @return bool True if the value was inserted or updated, false if the value was the same
* @deprecated 8.0.0 use method setAppValue of \OCP\IConfig
*/ */
public function setValue($app, $key, $value) { public function setValue($app, $key, $value) {
if (!$this->hasKey($app, $key)) { if (!$this->hasKey($app, $key)) {
* http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions002.htm#i1033286 * http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions002.htm#i1033286
* > Large objects (LOBs) are not supported in comparison conditions. * > Large objects (LOBs) are not supported in comparison conditions.
*/ */
if (!($this->conn instanceof \OC\DB\OracleConnection)) {
if (!($this->conn instanceof OracleConnection)) {
// Only update the value when it is not the same // Only update the value when it is not the same
$sql->andWhere($sql->expr()->neq('configvalue', $sql->createParameter('configvalue'))) $sql->andWhere($sql->expr()->neq('configvalue', $sql->createParameter('configvalue')))
->setParameter('configvalue', $value); ->setParameter('configvalue', $value);
* *
* @param string $app app * @param string $app app
* @param string $key key * @param string $key key
* @return boolean|null
* @return boolean
* @deprecated 8.0.0 use method deleteAppValue of \OCP\IConfig
*/ */
public function deleteKey($app, $key) { public function deleteKey($app, $key) {
$this->loadConfigValues(); $this->loadConfigValues();
$sql->execute(); $sql->execute();


unset($this->cache[$app][$key]); unset($this->cache[$app][$key]);
return false;
} }


/** /**
* Remove app from appconfig * Remove app from appconfig
* *
* @param string $app app * @param string $app app
* @return boolean|null
* @return boolean
* @deprecated 8.0.0 use method deleteAppValue of \OCP\IConfig
* *
* Removes all keys in appconfig belonging to the app. * Removes all keys in appconfig belonging to the app.
*/ */
$sql->execute(); $sql->execute();


unset($this->cache[$app]); unset($this->cache[$app]);
return false;
} }


/** /**
} }
} }


/**
* get all values of the app or and filters out sensitive data
*
* @param string $app
* @return array
*/
public function getFilteredValues($app) {
$values = $this->getValues($app, false);

foreach ($this->sensitiveValues[$app] as $sensitiveKey) {
if (isset($values[$sensitiveKey])) {
$values[$sensitiveKey] = IConfig::SENSITIVE_VALUE;
}
}

return $values;
}

/** /**
* Load all the app config values * Load all the app config values
*/ */
protected function loadConfigValues() { protected function loadConfigValues() {
if ($this->configLoaded) return;
if ($this->configLoaded) {
return;
}


$this->cache = []; $this->cache = [];



+ 0
- 1
lib/private/SystemConfig.php View File

'passwordsalt' => true, 'passwordsalt' => true,
'secret' => true, 'secret' => true,
'updater.secret' => true, 'updater.secret' => true,
'ldap_agent_password' => true,
'proxyuserpwd' => true, 'proxyuserpwd' => true,
'log.condition' => [ 'log.condition' => [
'shared_secret' => true, 'shared_secret' => true,

+ 9
- 0
lib/public/IAppConfig.php View File

*/ */
public function getValues($app, $key); public function getValues($app, $key);


/**
* get all values of the app or and filters out sensitive data
*
* @param string $app
* @return array
* @since 12.0.0
*/
public function getFilteredValues($app);

/** /**
* sets a value in the appconfig * sets a value in the appconfig
* @param string $app app * @param string $app app

+ 6
- 0
tests/Core/Command/Config/ListConfigsTest.php View File

$this->systemConfig->expects($this->any()) $this->systemConfig->expects($this->any())
->method('getValue') ->method('getValue')
->willReturnMap($systemConfigMap); ->willReturnMap($systemConfigMap);
$this->appConfig->expects($this->any())
->method('getValues')
->willReturnMap($appConfig);
} else { } else {
$this->systemConfig->expects($this->any()) $this->systemConfig->expects($this->any())
->method('getFilteredValue') ->method('getFilteredValue')
->willReturnMap($systemConfigMap); ->willReturnMap($systemConfigMap);
$this->appConfig->expects($this->any())
->method('getFilteredValues')
->willReturnMap($appConfig);
} }


$this->appConfig->expects($this->any()) $this->appConfig->expects($this->any())

+ 23
- 0
tests/lib/AppConfigTest.php View File

*/ */


namespace Test; namespace Test;
use OCP\IConfig;


/** /**
* Class AppConfigTest * Class AppConfigTest
$this->assertEquals($expected, $values); $this->assertEquals($expected, $values);
} }


public function testGetFilteredValues() {
/** @var \OC\AppConfig|\PHPUnit_Framework_MockObject_MockObject $config */
$config = $this->getMockBuilder(\OC\AppConfig::class)
->setConstructorArgs([\OC::$server->getDatabaseConnection()])
->setMethods(['getValues'])
->getMock();

$config->expects($this->once())
->method('getValues')
->with('user_ldap', false)
->willReturn([
'ldap_agent_password' => 'secret',
'ldap_dn' => 'dn',
]);

$values = $config->getFilteredValues('user_ldap');
$this->assertEquals([
'ldap_agent_password' => IConfig::SENSITIVE_VALUE,
'ldap_dn' => 'dn',
], $values);
}

public function testSettingConfigParallel() { public function testSettingConfigParallel() {
$appConfig1 = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); $appConfig1 = new \OC\AppConfig(\OC::$server->getDatabaseConnection());
$appConfig2 = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); $appConfig2 = new \OC\AppConfig(\OC::$server->getDatabaseConnection());

Loading…
Cancel
Save