aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/AppFramework/DependencyInjection/DIContainer.php4
-rw-r--r--lib/private/Authentication/Token/DefaultToken.php18
-rw-r--r--lib/private/Authentication/Token/DefaultTokenMapper.php4
-rw-r--r--lib/private/Authentication/Token/DefaultTokenProvider.php6
-rw-r--r--lib/private/Authentication/Token/IProvider.php3
-rw-r--r--lib/private/Authentication/Token/IToken.php7
-rw-r--r--lib/private/Files/Mount/ObjectHomeMountProvider.php65
-rw-r--r--lib/private/Files/ObjectStore/Mapper.php52
-rw-r--r--lib/private/Server.php2
-rw-r--r--lib/private/Setup.php3
-rw-r--r--lib/private/User/Session.php93
11 files changed, 231 insertions, 26 deletions
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php
index e120479ac59..92c3f618bdc 100644
--- a/lib/private/AppFramework/DependencyInjection/DIContainer.php
+++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php
@@ -157,6 +157,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer()->getGroupManager();
});
+ $this->registerService('OCP\\Http\\Client\\IClientService', function() {
+ return $this->getServer()->getHTTPClientService();
+ });
+
$this->registerService('OCP\\IL10N', function($c) {
return $this->getServer()->getL10N($c->query('AppName'));
});
diff --git a/lib/private/Authentication/Token/DefaultToken.php b/lib/private/Authentication/Token/DefaultToken.php
index 4a64eacb247..8cb36711b69 100644
--- a/lib/private/Authentication/Token/DefaultToken.php
+++ b/lib/private/Authentication/Token/DefaultToken.php
@@ -27,6 +27,8 @@ use OCP\AppFramework\Db\Entity;
/**
* @method void setId(int $id)
* @method void setUid(string $uid);
+ * @method void setLoginName(string $loginName)
+ * @method string getLoginName()
* @method void setPassword(string $password)
* @method void setName(string $name)
* @method string getName()
@@ -45,6 +47,11 @@ class DefaultToken extends Entity implements IToken {
protected $uid;
/**
+ * @var string login name used for generating the token
+ */
+ protected $loginName;
+
+ /**
* @var string encrypted user password
*/
protected $password;
@@ -76,7 +83,16 @@ class DefaultToken extends Entity implements IToken {
public function getUID() {
return $this->uid;
}
-
+
+ /**
+ * Get the login name used when generating the token
+ *
+ * @return string
+ */
+ public function getLoginName() {
+ return parent::getLoginName();
+ }
+
/**
* Get the (encrypted) login password
*
diff --git a/lib/private/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php
index 970c2242dbe..f24fab00a1a 100644
--- a/lib/private/Authentication/Token/DefaultTokenMapper.php
+++ b/lib/private/Authentication/Token/DefaultTokenMapper.php
@@ -71,7 +71,7 @@ class DefaultTokenMapper extends Mapper {
public function getToken($token) {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
- $result = $qb->select('id', 'uid', 'password', 'name', 'type', 'token', 'last_activity')
+ $result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'token', 'last_activity')
->from('authtoken')
->where($qb->expr()->eq('token', $qb->createParameter('token')))
->setParameter('token', $token)
@@ -96,7 +96,7 @@ class DefaultTokenMapper extends Mapper {
public function getTokenByUser(IUser $user) {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
- $qb->select('id', 'uid', 'password', 'name', 'type', 'token', 'last_activity')
+ $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'token', 'last_activity')
->from('authtoken')
->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
->setMaxResults(1000);
diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php
index 0f7c54dab57..a3ba7b69445 100644
--- a/lib/private/Authentication/Token/DefaultTokenProvider.php
+++ b/lib/private/Authentication/Token/DefaultTokenProvider.php
@@ -68,14 +68,16 @@ class DefaultTokenProvider implements IProvider {
*
* @param string $token
* @param string $uid
+ * @param string $loginName
* @param string $password
* @param string $name
* @param int $type token type
- * @return DefaultToken
+ * @return IToken
*/
- public function generateToken($token, $uid, $password, $name, $type = IToken::TEMPORARY_TOKEN) {
+ public function generateToken($token, $uid, $loginName, $password, $name, $type = IToken::TEMPORARY_TOKEN) {
$dbToken = new DefaultToken();
$dbToken->setUid($uid);
+ $dbToken->setLoginName($loginName);
$dbToken->setPassword($this->encryptPassword($password, $token));
$dbToken->setName($name);
$dbToken->setToken($this->hashToken($token));
diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php
index e4e4581e738..6a158b43357 100644
--- a/lib/private/Authentication/Token/IProvider.php
+++ b/lib/private/Authentication/Token/IProvider.php
@@ -32,12 +32,13 @@ interface IProvider {
*
* @param string $token
* @param string $uid
+ * @param string $loginName
* @param string $password
* @param string $name
* @param int $type token type
* @return IToken
*/
- public function generateToken($token, $uid, $password, $name, $type = IToken::TEMPORARY_TOKEN);
+ public function generateToken($token, $uid, $loginName, $password, $name, $type = IToken::TEMPORARY_TOKEN);
/**
* Get a token by token id
diff --git a/lib/private/Authentication/Token/IToken.php b/lib/private/Authentication/Token/IToken.php
index b741cd4ac22..dc2c3a0ae34 100644
--- a/lib/private/Authentication/Token/IToken.php
+++ b/lib/private/Authentication/Token/IToken.php
@@ -44,6 +44,13 @@ interface IToken extends JsonSerializable {
public function getUID();
/**
+ * Get the login name used when generating the token
+ *
+ * @return string
+ */
+ public function getLoginName();
+
+ /**
* Get the (encrypted) login password
*
* @return string
diff --git a/lib/private/Files/Mount/ObjectHomeMountProvider.php b/lib/private/Files/Mount/ObjectHomeMountProvider.php
index c910cf6bd45..f82313879dc 100644
--- a/lib/private/Files/Mount/ObjectHomeMountProvider.php
+++ b/lib/private/Files/Mount/ObjectHomeMountProvider.php
@@ -52,9 +52,27 @@ class ObjectHomeMountProvider implements IHomeMountProvider {
* @return \OCP\Files\Mount\IMountPoint[]
*/
public function getHomeMountForUser(IUser $user, IStorageFactory $loader) {
+
+ $config = $this->getMultiBucketObjectStoreConfig($user);
+ if ($config === null) {
+ $config = $this->getSingleBucketObjectStoreConfig($user);
+ }
+
+ if ($config === null) {
+ return null;
+ }
+
+ return new MountPoint('\OC\Files\ObjectStore\HomeObjectStoreStorage', '/' . $user->getUID(), $config['arguments'], $loader);
+ }
+
+ /**
+ * @param IUser $user
+ * @return array|null
+ */
+ private function getSingleBucketObjectStoreConfig(IUser $user) {
$config = $this->config->getSystemValue('objectstore');
if (!is_array($config)) {
- return null; //fall back to local home provider
+ return null;
}
// sanity checks
@@ -68,6 +86,49 @@ class ObjectHomeMountProvider implements IHomeMountProvider {
// instantiate object store implementation
$config['arguments']['objectstore'] = new $config['class']($config['arguments']);
- return new MountPoint('\OC\Files\ObjectStore\HomeObjectStoreStorage', '/' . $user->getUID(), $config['arguments'], $loader);
+ return $config;
+ }
+
+ /**
+ * @param IUser $user
+ * @return array|null
+ */
+ private function getMultiBucketObjectStoreConfig(IUser $user) {
+ $config = $this->config->getSystemValue('objectstore_multibucket');
+ if (!is_array($config)) {
+ return null;
+ }
+
+ // sanity checks
+ if (empty($config['class'])) {
+ \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
+ }
+ if (!isset($config['arguments'])) {
+ $config['arguments'] = [];
+ }
+ $config['arguments']['user'] = $user;
+
+ $bucket = $this->config->getUserValue($user->getUID(), 'homeobjectstore', 'bucket', null);
+
+ if ($bucket === null) {
+ /*
+ * Use any provided bucket argument as prefix
+ * and add the mapping from username => bucket
+ */
+ if (!isset($config['arguments']['bucket'])) {
+ $config['arguments']['bucket'] = '';
+ }
+ $mapper = new \OC\Files\ObjectStore\Mapper($user);
+ $config['arguments']['bucket'] .= $mapper->getBucket();
+
+ $this->config->setUserValue($user->getUID(), 'homeobjectstore', 'bucket', $config['arguments']['bucket']);
+ } else {
+ $config['arguments']['bucket'] = $bucket;
+ }
+
+ // instantiate object store implementation
+ $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
+
+ return $config;
}
}
diff --git a/lib/private/Files/ObjectStore/Mapper.php b/lib/private/Files/ObjectStore/Mapper.php
new file mode 100644
index 00000000000..f0004f1f966
--- /dev/null
+++ b/lib/private/Files/ObjectStore/Mapper.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+namespace OC\Files\ObjectStore;
+
+use OCP\IUser;
+
+/**
+ * Class Mapper
+ *
+ * @package OC\Files\ObjectStore
+ *
+ * Map a user to a bucket.
+ */
+class Mapper {
+ /** @var IUser */
+ private $user;
+
+ /**
+ * Mapper constructor.
+ *
+ * @param IUser $user
+ */
+ public function __construct(IUser $user) {
+ $this->user = $user;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBucket() {
+ $hash = md5($this->user->getUID());
+ return substr($hash, 0, 3);
+ }
+} \ No newline at end of file
diff --git a/lib/private/Server.php b/lib/private/Server.php
index c7b3799448e..0b425013267 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -236,7 +236,7 @@ class Server extends ServerContainer implements IServerContainer {
$defaultTokenProvider = null;
}
- $userSession = new \OC\User\Session($manager, $session, $timeFactory, $defaultTokenProvider);
+ $userSession = new \OC\User\Session($manager, $session, $timeFactory, $defaultTokenProvider, $c->getConfig());
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
\OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
});
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index d60c4663fb0..55a5e2bec11 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -371,7 +371,8 @@ class Setup {
$userSession = \OC::$server->getUserSession();
$defaultTokenProvider = \OC::$server->query('OC\Authentication\Token\DefaultTokenProvider');
$userSession->setTokenProvider($defaultTokenProvider);
- $userSession->createSessionToken($request, $username, $password);
+ $userSession->login($username, $password);
+ $userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
//guess what this does
Installer::installShippedApps();
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index ddd86a56abb..c77cfedba4c 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -42,6 +42,7 @@ use OC_User;
use OC_Util;
use OCA\DAV\Connector\Sabre\Auth;
use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\IConfig;
use OCP\IRequest;
use OCP\ISession;
use OCP\IUser;
@@ -68,8 +69,8 @@ use OCP\Session\Exceptions\SessionNotAvailableException;
* @package OC\User
*/
class Session implements IUserSession, Emitter {
-
- /** @var Manager $manager */
+
+ /** @var IUserManager $manager */
private $manager;
/** @var ISession $session */
@@ -81,6 +82,9 @@ class Session implements IUserSession, Emitter {
/** @var IProvider */
private $tokenProvider;
+ /** @var IConfig */
+ private $config;
+
/** @var User $activeUser */
protected $activeUser;
@@ -89,12 +93,14 @@ class Session implements IUserSession, Emitter {
* @param ISession $session
* @param ITimeFactory $timeFacory
* @param IProvider $tokenProvider
+ * @param IConfig $config
*/
- public function __construct(IUserManager $manager, ISession $session, ITimeFactory $timeFacory, $tokenProvider) {
+ public function __construct(IUserManager $manager, ISession $session, ITimeFactory $timeFacory, $tokenProvider, IConfig $config) {
$this->manager = $manager;
$this->session = $session;
$this->timeFacory = $timeFacory;
$this->tokenProvider = $tokenProvider;
+ $this->config = $config;
}
/**
@@ -219,7 +225,7 @@ class Session implements IUserSession, Emitter {
return;
}
- if ($this->manager->checkPassword($user->getUID(), $pwd) === false
+ if ($this->manager->checkPassword($token->getLoginName(), $pwd) === false
|| !$user->isEnabled()) {
// Password has changed or user was disabled -> log user out
$this->logout();
@@ -279,7 +285,7 @@ class Session implements IUserSession, Emitter {
}
/**
- * try to login with the provided credentials
+ * try to log in with the provided credentials
*
* @param string $uid
* @param string $password
@@ -327,6 +333,63 @@ class Session implements IUserSession, Emitter {
return false;
}
+ /**
+ * Tries to log in a client
+ *
+ * Checks token auth enforced
+ * Checks 2FA enabled
+ *
+ * @param string $user
+ * @param string $password
+ * @throws LoginException
+ * @return boolean
+ */
+ public function logClientIn($user, $password) {
+ $isTokenPassword = $this->isTokenPassword($password);
+ if (!$isTokenPassword && $this->isTokenAuthEnforced()) {
+ // TODO: throw LoginException instead (https://github.com/owncloud/core/pull/24616)
+ return false;
+ }
+ if (!$isTokenPassword && $this->isTwoFactorEnforced($user)) {
+ // TODO: throw LoginException instead (https://github.com/owncloud/core/pull/24616)
+ return false;
+ }
+ return $this->login($user, $password);
+ }
+
+ private function isTokenAuthEnforced() {
+ return $this->config->getSystemValue('token_auth_enforced', false);
+ }
+
+ protected function isTwoFactorEnforced($username) {
+ \OCP\Util::emitHook(
+ '\OCA\Files_Sharing\API\Server2Server',
+ 'preLoginNameUsedAsUserName',
+ array('uid' => &$username)
+ );
+ $user = $this->manager->get($username);
+ if (is_null($user)) {
+ return true;
+ }
+ // DI not possible due to cyclic dependencies :'-/
+ return OC::$server->getTwoFactorAuthManager()->isTwoFactorAuthenticated($user);
+ }
+
+ /**
+ * Check if the given 'password' is actually a device token
+ *
+ * @param type $password
+ * @return boolean
+ */
+ public function isTokenPassword($password) {
+ try {
+ $this->tokenProvider->getToken($password);
+ return true;
+ } catch (InvalidTokenException $ex) {
+ return false;
+ }
+ }
+
protected function prepareUserLogin() {
// TODO: mock/inject/use non-static
// Refresh the token
@@ -347,7 +410,7 @@ class Session implements IUserSession, Emitter {
*/
public function tryBasicAuthLogin(IRequest $request) {
if (!empty($request->server['PHP_AUTH_USER']) && !empty($request->server['PHP_AUTH_PW'])) {
- $result = $this->login($request->server['PHP_AUTH_USER'], $request->server['PHP_AUTH_PW']);
+ $result = $this->logClientIn($request->server['PHP_AUTH_USER'], $request->server['PHP_AUTH_PW']);
if ($result === true) {
/**
* Add DAV authenticated. This should in an ideal world not be
@@ -388,25 +451,23 @@ class Session implements IUserSession, Emitter {
*
* @param IRequest $request
* @param string $uid user UID
+ * @param string $loginName login name
* @param string $password
* @return boolean
*/
- public function createSessionToken(IRequest $request, $uid, $password) {
+ public function createSessionToken(IRequest $request, $uid, $loginName, $password) {
if (is_null($this->manager->get($uid))) {
// User does not exist
return false;
}
$name = isset($request->server['HTTP_USER_AGENT']) ? $request->server['HTTP_USER_AGENT'] : 'unknown browser';
- $loggedIn = $this->login($uid, $password);
- if ($loggedIn) {
- try {
- $sessionId = $this->session->getId();
- $this->tokenProvider->generateToken($sessionId, $uid, $password, $name);
- } catch (SessionNotAvailableException $ex) {
-
- }
+ try {
+ $sessionId = $this->session->getId();
+ $this->tokenProvider->generateToken($sessionId, $uid, $loginName, $password, $name);
+ } catch (SessionNotAvailableException $ex) {
+
}
- return $loggedIn;
+ return true;
}
/**