block DAV if 2FA challenge needs to be solved first
This commit is contained in:
parent
0f2017c7da
commit
da03a85c3c
|
@ -34,6 +34,7 @@ $authBackend = new Auth(
|
||||||
\OC::$server->getSession(),
|
\OC::$server->getSession(),
|
||||||
\OC::$server->getUserSession(),
|
\OC::$server->getUserSession(),
|
||||||
\OC::$server->getRequest(),
|
\OC::$server->getRequest(),
|
||||||
|
\OC::$server->getTwoFactorAuthManager(),
|
||||||
'principals/'
|
'principals/'
|
||||||
);
|
);
|
||||||
$principalBackend = new Principal(
|
$principalBackend = new Principal(
|
||||||
|
|
|
@ -35,6 +35,7 @@ $authBackend = new Auth(
|
||||||
\OC::$server->getSession(),
|
\OC::$server->getSession(),
|
||||||
\OC::$server->getUserSession(),
|
\OC::$server->getUserSession(),
|
||||||
\OC::$server->getRequest(),
|
\OC::$server->getRequest(),
|
||||||
|
\OC::$server->getTwoFactorAuthManager(),
|
||||||
'principals/'
|
'principals/'
|
||||||
);
|
);
|
||||||
$principalBackend = new Principal(
|
$principalBackend = new Principal(
|
||||||
|
|
|
@ -42,6 +42,7 @@ $authBackend = new \OCA\DAV\Connector\Sabre\Auth(
|
||||||
\OC::$server->getSession(),
|
\OC::$server->getSession(),
|
||||||
\OC::$server->getUserSession(),
|
\OC::$server->getUserSession(),
|
||||||
\OC::$server->getRequest(),
|
\OC::$server->getRequest(),
|
||||||
|
\OC::$server->getTwoFactorAuthManager(),
|
||||||
'principals/'
|
'principals/'
|
||||||
);
|
);
|
||||||
$requestUri = \OC::$server->getRequest()->getRequestUri();
|
$requestUri = \OC::$server->getRequest()->getRequestUri();
|
||||||
|
|
|
@ -31,9 +31,10 @@ namespace OCA\DAV\Connector\Sabre;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use OC\AppFramework\Http\Request;
|
use OC\AppFramework\Http\Request;
|
||||||
|
use OC\Authentication\TwoFactorAuth\Manager;
|
||||||
|
use OC\User\Session;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use OCP\ISession;
|
use OCP\ISession;
|
||||||
use OC\User\Session;
|
|
||||||
use Sabre\DAV\Auth\Backend\AbstractBasic;
|
use Sabre\DAV\Auth\Backend\AbstractBasic;
|
||||||
use Sabre\DAV\Exception\NotAuthenticated;
|
use Sabre\DAV\Exception\NotAuthenticated;
|
||||||
use Sabre\DAV\Exception\ServiceUnavailable;
|
use Sabre\DAV\Exception\ServiceUnavailable;
|
||||||
|
@ -41,6 +42,8 @@ use Sabre\HTTP\RequestInterface;
|
||||||
use Sabre\HTTP\ResponseInterface;
|
use Sabre\HTTP\ResponseInterface;
|
||||||
|
|
||||||
class Auth extends AbstractBasic {
|
class Auth extends AbstractBasic {
|
||||||
|
|
||||||
|
|
||||||
const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';
|
const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';
|
||||||
|
|
||||||
/** @var ISession */
|
/** @var ISession */
|
||||||
|
@ -51,19 +54,24 @@ class Auth extends AbstractBasic {
|
||||||
private $request;
|
private $request;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $currentUser;
|
private $currentUser;
|
||||||
|
/** @var Manager */
|
||||||
|
private $twoFactorManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ISession $session
|
* @param ISession $session
|
||||||
* @param Session $userSession
|
* @param Session $userSession
|
||||||
* @param IRequest $request
|
* @param IRequest $request
|
||||||
|
* @param Manager $twoFactorManager
|
||||||
* @param string $principalPrefix
|
* @param string $principalPrefix
|
||||||
*/
|
*/
|
||||||
public function __construct(ISession $session,
|
public function __construct(ISession $session,
|
||||||
Session $userSession,
|
Session $userSession,
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
|
Manager $twoFactorManager,
|
||||||
$principalPrefix = 'principals/users/') {
|
$principalPrefix = 'principals/users/') {
|
||||||
$this->session = $session;
|
$this->session = $session;
|
||||||
$this->userSession = $userSession;
|
$this->userSession = $userSession;
|
||||||
|
$this->twoFactorManager = $twoFactorManager;
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
$this->principalPrefix = $principalPrefix;
|
$this->principalPrefix = $principalPrefix;
|
||||||
}
|
}
|
||||||
|
@ -197,6 +205,9 @@ class Auth extends AbstractBasic {
|
||||||
if($forcedLogout) {
|
if($forcedLogout) {
|
||||||
$this->userSession->logout();
|
$this->userSession->logout();
|
||||||
} else {
|
} else {
|
||||||
|
if ($this->twoFactorManager->needsSecondFactor()) {
|
||||||
|
throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.');
|
||||||
|
}
|
||||||
if (\OC_User::handleApacheAuth() ||
|
if (\OC_User::handleApacheAuth() ||
|
||||||
//Fix for broken webdav clients
|
//Fix for broken webdav clients
|
||||||
($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) ||
|
($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) ||
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
namespace OCA\DAV;
|
namespace OCA\DAV;
|
||||||
|
|
||||||
use OCA\DAV\CalDAV\Schedule\IMipPlugin;
|
use OCA\DAV\CalDAV\Schedule\IMipPlugin;
|
||||||
use OCA\DAV\Connector\FedAuth;
|
|
||||||
use OCA\DAV\Connector\Sabre\Auth;
|
use OCA\DAV\Connector\Sabre\Auth;
|
||||||
use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin;
|
use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin;
|
||||||
use OCA\DAV\Connector\Sabre\DavAclPlugin;
|
use OCA\DAV\Connector\Sabre\DavAclPlugin;
|
||||||
|
@ -57,7 +56,8 @@ class Server {
|
||||||
$authBackend = new Auth(
|
$authBackend = new Auth(
|
||||||
\OC::$server->getSession(),
|
\OC::$server->getSession(),
|
||||||
\OC::$server->getUserSession(),
|
\OC::$server->getUserSession(),
|
||||||
\OC::$server->getRequest()
|
\OC::$server->getRequest(),
|
||||||
|
\OC::$server->getTwoFactorAuthManager()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set URL explicitly due to reverse-proxy situations
|
// Set URL explicitly due to reverse-proxy situations
|
||||||
|
|
|
@ -27,11 +27,12 @@
|
||||||
|
|
||||||
namespace OCA\DAV\Tests\unit\Connector\Sabre;
|
namespace OCA\DAV\Tests\unit\Connector\Sabre;
|
||||||
|
|
||||||
|
use OC\Authentication\TwoFactorAuth\Manager;
|
||||||
|
use OC\User\Session;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
use OCP\ISession;
|
||||||
use OCP\IUser;
|
use OCP\IUser;
|
||||||
use Test\TestCase;
|
use Test\TestCase;
|
||||||
use OCP\ISession;
|
|
||||||
use OC\User\Session;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AuthTest
|
* Class AuthTest
|
||||||
|
@ -48,6 +49,8 @@ class AuthTest extends TestCase {
|
||||||
private $userSession;
|
private $userSession;
|
||||||
/** @var IRequest */
|
/** @var IRequest */
|
||||||
private $request;
|
private $request;
|
||||||
|
/** @var Manager */
|
||||||
|
private $twoFactorManager;
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
@ -57,10 +60,14 @@ class AuthTest extends TestCase {
|
||||||
->disableOriginalConstructor()->getMock();
|
->disableOriginalConstructor()->getMock();
|
||||||
$this->request = $this->getMockBuilder('\OCP\IRequest')
|
$this->request = $this->getMockBuilder('\OCP\IRequest')
|
||||||
->disableOriginalConstructor()->getMock();
|
->disableOriginalConstructor()->getMock();
|
||||||
|
$this->twoFactorManager = $this->getMockBuilder('\OC\Authentication\TwoFactorAuth\Manager')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
$this->auth = new \OCA\DAV\Connector\Sabre\Auth(
|
$this->auth = new \OCA\DAV\Connector\Sabre\Auth(
|
||||||
$this->session,
|
$this->session,
|
||||||
$this->userSession,
|
$this->userSession,
|
||||||
$this->request
|
$this->request,
|
||||||
|
$this->twoFactorManager
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +302,59 @@ class AuthTest extends TestCase {
|
||||||
$this->auth->check($request, $response);
|
$this->auth->check($request, $response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Sabre\DAV\Exception\NotAuthenticated
|
||||||
|
* @expectedExceptionMessage 2FA challenge not passed.
|
||||||
|
*/
|
||||||
|
public function testAuthenticateAlreadyLoggedInWithoutTwoFactorChallengePassed() {
|
||||||
|
$request = $this->getMockBuilder('Sabre\HTTP\RequestInterface')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$this->userSession
|
||||||
|
->expects($this->any())
|
||||||
|
->method('isLoggedIn')
|
||||||
|
->willReturn(true);
|
||||||
|
$this->request
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getMethod')
|
||||||
|
->willReturn('PROPFIND');
|
||||||
|
$this->request
|
||||||
|
->expects($this->any())
|
||||||
|
->method('isUserAgent')
|
||||||
|
->with([
|
||||||
|
'/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/',
|
||||||
|
'/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/',
|
||||||
|
'/^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/',
|
||||||
|
])
|
||||||
|
->willReturn(false);
|
||||||
|
$this->session
|
||||||
|
->expects($this->any())
|
||||||
|
->method('get')
|
||||||
|
->with('AUTHENTICATED_TO_DAV_BACKEND')
|
||||||
|
->will($this->returnValue('LoggedInUser'));
|
||||||
|
$user = $this->getMockBuilder('\OCP\IUser')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$user->expects($this->any())
|
||||||
|
->method('getUID')
|
||||||
|
->will($this->returnValue('LoggedInUser'));
|
||||||
|
$this->userSession
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getUser')
|
||||||
|
->will($this->returnValue($user));
|
||||||
|
$this->request
|
||||||
|
->expects($this->once())
|
||||||
|
->method('passesCSRFCheck')
|
||||||
|
->willReturn(true);
|
||||||
|
$this->twoFactorManager->expects($this->once())
|
||||||
|
->method('needsSecondFactor')
|
||||||
|
->will($this->returnValue(true));
|
||||||
|
$this->auth->check($request, $response);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Sabre\DAV\Exception\NotAuthenticated
|
* @expectedException \Sabre\DAV\Exception\NotAuthenticated
|
||||||
* @expectedExceptionMessage CSRF check not passed.
|
* @expectedExceptionMessage CSRF check not passed.
|
||||||
|
|
Loading…
Reference in New Issue