Browse Source

Create session tokens for apache auth users

tags/v9.0.1beta2
Christoph Wurst 8 years ago
parent
commit
c58d8159d7
No account linked to committer's email address

+ 1
- 2
db_structure.xml View File

<name>password</name> <name>password</name>
<type>clob</type> <type>clob</type>
<default></default> <default></default>
<notnull>true</notnull>
<length>4000</length>
<notnull>false</notnull>
</field> </field>


<field> <field>

+ 29
- 0
lib/private/Authentication/Exceptions/PasswordlessTokenException.php View File

<?php

/**
* @author Christoph Wurst <christoph@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\Authentication\Exceptions;

use Exception;

class PasswordlessTokenException extends Exception {

}

+ 0
- 1
lib/private/Authentication/Token/DefaultToken.php View File

* @method void setId(int $id) * @method void setId(int $id)
* @method void setUid(string $uid); * @method void setUid(string $uid);
* @method void setLoginName(string $loginName) * @method void setLoginName(string $loginName)
* @method string getLoginName()
* @method void setPassword(string $password) * @method void setPassword(string $password)
* @method void setName(string $name) * @method void setName(string $name)
* @method string getName() * @method string getName()

+ 11
- 3
lib/private/Authentication/Token/DefaultTokenProvider.php View File



use Exception; use Exception;
use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Exceptions\PasswordlessTokenException;
use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory; use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IConfig; use OCP\IConfig;
* @param string $token * @param string $token
* @param string $uid * @param string $uid
* @param string $loginName * @param string $loginName
* @param string $password
* @param string|null $password
* @param string $name * @param string $name
* @param int $type token type * @param int $type token type
* @return IToken * @return IToken
$dbToken = new DefaultToken(); $dbToken = new DefaultToken();
$dbToken->setUid($uid); $dbToken->setUid($uid);
$dbToken->setLoginName($loginName); $dbToken->setLoginName($loginName);
$dbToken->setPassword($this->encryptPassword($password, $token));
if (!is_null($password)) {
$dbToken->setPassword($this->encryptPassword($password, $token));
}
$dbToken->setName($name); $dbToken->setName($name);
$dbToken->setToken($this->hashToken($token)); $dbToken->setToken($this->hashToken($token));
$dbToken->setType($type); $dbToken->setType($type);
* @param IToken $savedToken * @param IToken $savedToken
* @param string $tokenId session token * @param string $tokenId session token
* @throws InvalidTokenException * @throws InvalidTokenException
* @throws PasswordlessTokenException
* @return string * @return string
*/ */
public function getPassword(IToken $savedToken, $tokenId) { public function getPassword(IToken $savedToken, $tokenId) {
return $this->decryptPassword($savedToken->getPassword(), $tokenId);
$password = $savedToken->getPassword();
if (is_null($password)) {
throw new PasswordlessTokenException();
}
return $this->decryptPassword($password, $tokenId);
} }


/** /**

+ 3
- 1
lib/private/Authentication/Token/IProvider.php View File

namespace OC\Authentication\Token; namespace OC\Authentication\Token;


use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Exceptions\PasswordlessTokenException;
use OCP\IUser; use OCP\IUser;


interface IProvider { interface IProvider {
* @param string $token * @param string $token
* @param string $uid * @param string $uid
* @param string $loginName * @param string $loginName
* @param string $password
* @param string|null $password
* @param string $name * @param string $name
* @param int $type token type * @param int $type token type
* @return IToken * @return IToken
* @param IToken $token * @param IToken $token
* @param string $tokenId * @param string $tokenId
* @throws InvalidTokenException * @throws InvalidTokenException
* @throws PasswordlessTokenException
* @return string * @return string
*/ */
public function getPassword(IToken $token, $tokenId); public function getPassword(IToken $token, $tokenId);

+ 14
- 4
lib/private/User/Session.php View File



use OC; use OC;
use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Exceptions\PasswordlessTokenException;
use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken; use OC\Authentication\Token\IToken;
use OC\Hooks\Emitter; use OC\Hooks\Emitter;
use OCP\IUserManager; use OCP\IUserManager;
use OCP\IUserSession; use OCP\IUserSession;
use OCP\Session\Exceptions\SessionNotAvailableException; use OCP\Session\Exceptions\SessionNotAvailableException;
use OCP\Util;


/** /**
* Class Session * Class Session
// An invalid token password was used -> log user out // An invalid token password was used -> log user out
$this->logout(); $this->logout();
return; return;
} catch (PasswordlessTokenException $ex) {
// Token has no password, nothing to check
$this->session->set('last_login_check', $now);
return;
} }


if ($this->manager->checkPassword($token->getLoginName(), $pwd) === false if ($this->manager->checkPassword($token->getLoginName(), $pwd) === false
// When logging in with token, the password must be decrypted first before passing to login hook // When logging in with token, the password must be decrypted first before passing to login hook
try { try {
$token = $this->tokenProvider->getToken($password); $token = $this->tokenProvider->getToken($password);
$password = $this->tokenProvider->getPassword($token, $password);
$this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
try {
$password = $this->tokenProvider->getPassword($token, $password);
$this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
} catch (PasswordlessTokenException $ex) {
$this->manager->emit('\OC\User', 'preLogin', array($uid, ''));
}
} catch (InvalidTokenException $ex) { } catch (InvalidTokenException $ex) {
// Invalid token, nothing to do // Invalid token, nothing to do
} }
} }


protected function isTwoFactorEnforced($username) { protected function isTwoFactorEnforced($username) {
\OCP\Util::emitHook(
Util::emitHook(
'\OCA\Files_Sharing\API\Server2Server', '\OCA\Files_Sharing\API\Server2Server',
'preLoginNameUsedAsUserName', 'preLoginNameUsedAsUserName',
array('uid' => &$username) array('uid' => &$username)
* @param string $password * @param string $password
* @return boolean * @return boolean
*/ */
public function createSessionToken(IRequest $request, $uid, $loginName, $password) {
public function createSessionToken(IRequest $request, $uid, $loginName, $password = null) {
if (is_null($this->manager->get($uid))) { if (is_null($this->manager->get($uid))) {
// User does not exist // User does not exist
return false; return false;

+ 2
- 0
lib/private/legacy/user.php View File

self::setUserId($uid); self::setUserId($uid);
self::setDisplayName($uid); self::setDisplayName($uid);
self::getUserSession()->setLoginName($uid); self::getUserSession()->setLoginName($uid);
$request = OC::$server->getRequest();
self::getUserSession()->createSessionToken($request, $uid, $uid);
// setup the filesystem // setup the filesystem
OC_Util::setupFS($uid); OC_Util::setupFS($uid);
// first call the post_login hooks, the login-process needs to be // first call the post_login hooks, the login-process needs to be

+ 6
- 1
settings/Controller/AuthSettingsController.php View File



use OC\AppFramework\Http; use OC\AppFramework\Http;
use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Exceptions\PasswordlessTokenException;
use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken; use OC\Authentication\Token\IToken;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
try { try {
$sessionToken = $this->tokenProvider->getToken($sessionId); $sessionToken = $this->tokenProvider->getToken($sessionId);
$loginName = $sessionToken->getLoginName(); $loginName = $sessionToken->getLoginName();
$password = $this->tokenProvider->getPassword($sessionToken, $sessionId);
try {
$password = $this->tokenProvider->getPassword($sessionToken, $sessionId);
} catch (PasswordlessTokenException $ex) {
$password = null;
}
} catch (InvalidTokenException $ex) { } catch (InvalidTokenException $ex) {
$resp = new JSONResponse(); $resp = new JSONResponse();
$resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE); $resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE);

+ 11
- 0
tests/lib/Authentication/Token/DefaultTokenProviderTest.php View File

$this->assertEquals('passme', $actual); $this->assertEquals('passme', $actual);
} }


/**
* @expectedException \OC\Authentication\Exceptions\PasswordlessTokenException
*/
public function testGetPasswordPasswordLessToken() {
$token = 'token1234';
$tk = new DefaultToken();
$tk->setPassword(null);

$this->tokenProvider->getPassword($tk, $token);
}

/** /**
* @expectedException \OC\Authentication\Exceptions\InvalidTokenException * @expectedException \OC\Authentication\Exceptions\InvalidTokenException
*/ */

+ 38
- 0
tests/lib/User/SessionTest.php View File

$this->invokePrivate($userSession, 'validateSession', [$user]); $this->invokePrivate($userSession, 'validateSession', [$user]);
} }


public function testValidateSessionNoPassword() {
$userManager = $this->getMock('\OCP\IUserManager');
$session = $this->getMock('\OCP\ISession');
$timeFactory = $this->getMock('\OCP\AppFramework\Utility\ITimeFactory');
$tokenProvider = $this->getMock('\OC\Authentication\Token\IProvider');
$userSession = $this->getMockBuilder('\OC\User\Session')
->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config])
->setMethods(['logout'])
->getMock();

$user = $this->getMock('\OCP\IUser');
$token = $this->getMock('\OC\Authentication\Token\IToken');

$session->expects($this->once())
->method('getId')
->will($this->returnValue('sessionid'));
$tokenProvider->expects($this->once())
->method('getToken')
->with('sessionid')
->will($this->returnValue($token));
$session->expects($this->once())
->method('get')
->with('last_login_check')
->will($this->returnValue(1000));
$timeFactory->expects($this->once())
->method('getTime')
->will($this->returnValue(5000));
$tokenProvider->expects($this->once())
->method('getPassword')
->with($token, 'sessionid')
->will($this->throwException(new \OC\Authentication\Exceptions\PasswordlessTokenException()));
$session->expects($this->once())
->method('set')
->with('last_login_check', 5000);

$this->invokePrivate($userSession, 'validateSession', [$user]);
}

} }

+ 1
- 1
version.php View File

// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number. // when updating major/minor version number.
$OC_Version = array(9, 1, 0, 6);
$OC_Version = array(9, 1, 0, 7);


// The human readable string // The human readable string
$OC_VersionString = '9.1.0 beta 1'; $OC_VersionString = '9.1.0 beta 1';

Loading…
Cancel
Save