Merge pull request #25082 from owncloud/fix-sessionless-clients

Fix sessionless clients
This commit is contained in:
Vincent Petry 2016-06-15 10:45:55 +02:00 committed by GitHub
commit 3e9353dd69
5 changed files with 68 additions and 20 deletions

View File

@ -115,8 +115,7 @@ class Auth extends AbstractBasic {
return true; return true;
} else { } else {
\OC_Util::setupFS(); //login hooks may need early access to the filesystem \OC_Util::setupFS(); //login hooks may need early access to the filesystem
if($this->userSession->logClientIn($username, $password)) { if($this->userSession->logClientIn($username, $password, $this->request)) {
$this->userSession->createSessionToken($this->request, $this->userSession->getUser()->getUID(), $username, $password);
\OC_Util::setupFS($this->userSession->getUser()->getUID()); \OC_Util::setupFS($this->userSession->getUser()->getUID());
$this->session->set(self::DAV_AUTHENTICATED, $this->userSession->getUser()->getUID()); $this->session->set(self::DAV_AUTHENTICATED, $this->userSession->getUser()->getUID());
$this->session->close(); $this->session->close();

View File

@ -159,7 +159,7 @@ class AuthTest extends TestCase {
$user = $this->getMockBuilder('\OCP\IUser') $user = $this->getMockBuilder('\OCP\IUser')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$user->expects($this->exactly(4)) $user->expects($this->exactly(3))
->method('getUID') ->method('getUID')
->will($this->returnValue('MyTestUser')); ->will($this->returnValue('MyTestUser'));
$this->userSession $this->userSession
@ -167,7 +167,7 @@ class AuthTest extends TestCase {
->method('isLoggedIn') ->method('isLoggedIn')
->will($this->returnValue(true)); ->will($this->returnValue(true));
$this->userSession $this->userSession
->expects($this->exactly(4)) ->expects($this->exactly(3))
->method('getUser') ->method('getUser')
->will($this->returnValue($user)); ->will($this->returnValue($user));
$this->session $this->session
@ -178,12 +178,8 @@ class AuthTest extends TestCase {
$this->userSession $this->userSession
->expects($this->once()) ->expects($this->once())
->method('logClientIn') ->method('logClientIn')
->with('MyTestUser', 'MyTestPassword') ->with('MyTestUser', 'MyTestPassword', $this->request)
->will($this->returnValue(true)); ->will($this->returnValue(true));
$this->userSession
->expects($this->once())
->method('createSessionToken')
->with($this->request, 'MyTestUser', 'MyTestUser', 'MyTestPassword');
$this->session $this->session
->expects($this->once()) ->expects($this->once())
->method('set') ->method('set')
@ -626,17 +622,14 @@ class AuthTest extends TestCase {
->method('logClientIn') ->method('logClientIn')
->with('username', 'password') ->with('username', 'password')
->will($this->returnValue(true)); ->will($this->returnValue(true));
$this->userSession
->expects($this->once())
->method('createSessionToken');
$user = $this->getMockBuilder('\OCP\IUser') $user = $this->getMockBuilder('\OCP\IUser')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$user->expects($this->exactly(4)) $user->expects($this->exactly(3))
->method('getUID') ->method('getUID')
->will($this->returnValue('MyTestUser')); ->will($this->returnValue('MyTestUser'));
$this->userSession $this->userSession
->expects($this->exactly(4)) ->expects($this->exactly(3))
->method('getUser') ->method('getUser')
->will($this->returnValue($user)); ->will($this->returnValue($user));
$response = $this->auth->check($server->httpRequest, $server->httpResponse); $response = $this->auth->check($server->httpRequest, $server->httpResponse);

View File

@ -89,7 +89,7 @@ class CORSMiddleware extends Middleware {
$pass = $this->request->server['PHP_AUTH_PW']; $pass = $this->request->server['PHP_AUTH_PW'];
$this->session->logout(); $this->session->logout();
if(!$this->session->logClientIn($user, $pass)) { if(!$this->session->logClientIn($user, $pass, $this->request)) {
throw new SecurityException('CORS requires basic auth', Http::STATUS_UNAUTHORIZED); throw new SecurityException('CORS requires basic auth', Http::STATUS_UNAUTHORIZED);
} }
} }

View File

@ -348,10 +348,11 @@ class Session implements IUserSession, Emitter {
* *
* @param string $user * @param string $user
* @param string $password * @param string $password
* @param IRequest $request
* @throws LoginException * @throws LoginException
* @return boolean * @return boolean
*/ */
public function logClientIn($user, $password) { public function logClientIn($user, $password, IRequest $request) {
$isTokenPassword = $this->isTokenPassword($password); $isTokenPassword = $this->isTokenPassword($password);
if (!$isTokenPassword && $this->isTokenAuthEnforced()) { if (!$isTokenPassword && $this->isTokenAuthEnforced()) {
// TODO: throw LoginException instead (https://github.com/owncloud/core/pull/24616) // TODO: throw LoginException instead (https://github.com/owncloud/core/pull/24616)
@ -368,9 +369,22 @@ class Session implements IUserSession, Emitter {
} }
return false; return false;
} }
if ($this->supportsCookies($request)) {
$this->createSessionToken($request, $this->getUser()->getUID(), $user, $password);
}
return true; return true;
} }
protected function supportsCookies(IRequest $request) {
if (!is_null($request->getCookie('cookie_test'))) {
return true;
}
setcookie('cookie_test', 'test', $this->timeFacory->getTime() + 3600);
return false;
}
private function isTokenAuthEnforced() { private function isTokenAuthEnforced() {
return $this->config->getSystemValue('token_auth_enforced', false); return $this->config->getSystemValue('token_auth_enforced', false);
} }
@ -428,7 +442,7 @@ class Session implements IUserSession, Emitter {
*/ */
public function tryBasicAuthLogin(IRequest $request) { public function tryBasicAuthLogin(IRequest $request) {
if (!empty($request->server['PHP_AUTH_USER']) && !empty($request->server['PHP_AUTH_PW'])) { if (!empty($request->server['PHP_AUTH_USER']) && !empty($request->server['PHP_AUTH_PW'])) {
$result = $this->logClientIn($request->server['PHP_AUTH_USER'], $request->server['PHP_AUTH_PW']); $result = $this->logClientIn($request->server['PHP_AUTH_USER'], $request->server['PHP_AUTH_PW'], $request);
if ($result === true) { if ($result === true) {
/** /**
* Add DAV authenticated. This should in an ideal world not be * Add DAV authenticated. This should in an ideal world not be

View File

@ -311,11 +311,13 @@ class SessionTest extends \Test\TestCase {
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$session = $this->getMock('\OCP\ISession'); $session = $this->getMock('\OCP\ISession');
$request = $this->getMock('\OCP\IRequest');
$user = $this->getMock('\OCP\IUser');
/** @var \OC\User\Session $userSession */ /** @var \OC\User\Session $userSession */
$userSession = $this->getMockBuilder('\OC\User\Session') $userSession = $this->getMockBuilder('\OC\User\Session')
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config])
->setMethods(['login']) ->setMethods(['login', 'supportsCookies', 'createSessionToken', 'getUser'])
->getMock(); ->getMock();
$this->tokenProvider->expects($this->once()) $this->tokenProvider->expects($this->once())
@ -327,7 +329,46 @@ class SessionTest extends \Test\TestCase {
->with('token_auth_enforced', false) ->with('token_auth_enforced', false)
->will($this->returnValue(true)); ->will($this->returnValue(true));
$this->assertFalse($userSession->logClientIn('john', 'doe')); $this->assertFalse($userSession->logClientIn('john', 'doe', $request));
}
public function testLogClientInWithTokenPassword() {
$manager = $this->getMockBuilder('\OC\User\Manager')
->disableOriginalConstructor()
->getMock();
$session = $this->getMock('\OCP\ISession');
$request = $this->getMock('\OCP\IRequest');
$user = $this->getMock('\OCP\IUser');
/** @var \OC\User\Session $userSession */
$userSession = $this->getMockBuilder('\OC\User\Session')
->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config])
->setMethods(['isTokenPassword', 'login', 'supportsCookies', 'createSessionToken', 'getUser'])
->getMock();
$userSession->expects($this->once())
->method('isTokenPassword')
->will($this->returnValue(true));
$userSession->expects($this->once())
->method('login')
->with('john', 'doe')
->will($this->returnValue(true));
$userSession->expects($this->once())
->method('supportsCookies')
->with($request)
->will($this->returnValue(true));
$userSession->expects($this->once())
->method('getUser')
->will($this->returnValue($user));
$user->expects($this->once())
->method('getUID')
->will($this->returnValue('user123'));
$userSession->expects($this->once())
->method('createSessionToken')
->with($request, 'user123', 'john', 'doe');
$this->assertTrue($userSession->logClientIn('john', 'doe', $request));
} }
public function testLogClientInNoTokenPasswordNo2fa() { public function testLogClientInNoTokenPasswordNo2fa() {
@ -336,6 +377,7 @@ class SessionTest extends \Test\TestCase {
->getMock(); ->getMock();
$session = $this->getMock('\OCP\ISession'); $session = $this->getMock('\OCP\ISession');
$user = $this->getMock('\OCP\IUser'); $user = $this->getMock('\OCP\IUser');
$request = $this->getMock('\OCP\IRequest');
/** @var \OC\User\Session $userSession */ /** @var \OC\User\Session $userSession */
$userSession = $this->getMockBuilder('\OC\User\Session') $userSession = $this->getMockBuilder('\OC\User\Session')
@ -357,7 +399,7 @@ class SessionTest extends \Test\TestCase {
->with('john') ->with('john')
->will($this->returnValue(true)); ->will($this->returnValue(true));
$this->assertFalse($userSession->logClientIn('john', 'doe')); $this->assertFalse($userSession->logClientIn('john', 'doe', $request));
} }
public function testRememberLoginValidToken() { public function testRememberLoginValidToken() {