@@ -34,6 +34,7 @@ $authBackend = new Auth( | |||
\OC::$server->getSession(), | |||
\OC::$server->getUserSession(), | |||
\OC::$server->getRequest(), | |||
\OC::$server->getTwoFactorAuthManager(), | |||
'principals/' | |||
); | |||
$principalBackend = new Principal( |
@@ -35,6 +35,7 @@ $authBackend = new Auth( | |||
\OC::$server->getSession(), | |||
\OC::$server->getUserSession(), | |||
\OC::$server->getRequest(), | |||
\OC::$server->getTwoFactorAuthManager(), | |||
'principals/' | |||
); | |||
$principalBackend = new Principal( |
@@ -42,6 +42,7 @@ $authBackend = new \OCA\DAV\Connector\Sabre\Auth( | |||
\OC::$server->getSession(), | |||
\OC::$server->getUserSession(), | |||
\OC::$server->getRequest(), | |||
\OC::$server->getTwoFactorAuthManager(), | |||
'principals/' | |||
); | |||
$requestUri = \OC::$server->getRequest()->getRequestUri(); |
@@ -31,9 +31,10 @@ namespace OCA\DAV\Connector\Sabre; | |||
use Exception; | |||
use OC\AppFramework\Http\Request; | |||
use OC\Authentication\TwoFactorAuth\Manager; | |||
use OC\User\Session; | |||
use OCP\IRequest; | |||
use OCP\ISession; | |||
use OC\User\Session; | |||
use Sabre\DAV\Auth\Backend\AbstractBasic; | |||
use Sabre\DAV\Exception\NotAuthenticated; | |||
use Sabre\DAV\Exception\ServiceUnavailable; | |||
@@ -41,6 +42,8 @@ use Sabre\HTTP\RequestInterface; | |||
use Sabre\HTTP\ResponseInterface; | |||
class Auth extends AbstractBasic { | |||
const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND'; | |||
/** @var ISession */ | |||
@@ -51,19 +54,24 @@ class Auth extends AbstractBasic { | |||
private $request; | |||
/** @var string */ | |||
private $currentUser; | |||
/** @var Manager */ | |||
private $twoFactorManager; | |||
/** | |||
* @param ISession $session | |||
* @param Session $userSession | |||
* @param IRequest $request | |||
* @param Manager $twoFactorManager | |||
* @param string $principalPrefix | |||
*/ | |||
public function __construct(ISession $session, | |||
Session $userSession, | |||
IRequest $request, | |||
Manager $twoFactorManager, | |||
$principalPrefix = 'principals/users/') { | |||
$this->session = $session; | |||
$this->userSession = $userSession; | |||
$this->twoFactorManager = $twoFactorManager; | |||
$this->request = $request; | |||
$this->principalPrefix = $principalPrefix; | |||
} | |||
@@ -197,6 +205,9 @@ class Auth extends AbstractBasic { | |||
if($forcedLogout) { | |||
$this->userSession->logout(); | |||
} else { | |||
if ($this->twoFactorManager->needsSecondFactor()) { | |||
throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.'); | |||
} | |||
if (\OC_User::handleApacheAuth() || | |||
//Fix for broken webdav clients | |||
($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) || |
@@ -25,7 +25,6 @@ | |||
namespace OCA\DAV; | |||
use OCA\DAV\CalDAV\Schedule\IMipPlugin; | |||
use OCA\DAV\Connector\FedAuth; | |||
use OCA\DAV\Connector\Sabre\Auth; | |||
use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin; | |||
use OCA\DAV\Connector\Sabre\DavAclPlugin; | |||
@@ -57,7 +56,8 @@ class Server { | |||
$authBackend = new Auth( | |||
\OC::$server->getSession(), | |||
\OC::$server->getUserSession(), | |||
\OC::$server->getRequest() | |||
\OC::$server->getRequest(), | |||
\OC::$server->getTwoFactorAuthManager() | |||
); | |||
// Set URL explicitly due to reverse-proxy situations |
@@ -27,11 +27,12 @@ | |||
namespace OCA\DAV\Tests\unit\Connector\Sabre; | |||
use OC\Authentication\TwoFactorAuth\Manager; | |||
use OC\User\Session; | |||
use OCP\IRequest; | |||
use OCP\ISession; | |||
use OCP\IUser; | |||
use Test\TestCase; | |||
use OCP\ISession; | |||
use OC\User\Session; | |||
/** | |||
* Class AuthTest | |||
@@ -48,6 +49,8 @@ class AuthTest extends TestCase { | |||
private $userSession; | |||
/** @var IRequest */ | |||
private $request; | |||
/** @var Manager */ | |||
private $twoFactorManager; | |||
public function setUp() { | |||
parent::setUp(); | |||
@@ -57,10 +60,14 @@ class AuthTest extends TestCase { | |||
->disableOriginalConstructor()->getMock(); | |||
$this->request = $this->getMockBuilder('\OCP\IRequest') | |||
->disableOriginalConstructor()->getMock(); | |||
$this->twoFactorManager = $this->getMockBuilder('\OC\Authentication\TwoFactorAuth\Manager') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$this->auth = new \OCA\DAV\Connector\Sabre\Auth( | |||
$this->session, | |||
$this->userSession, | |||
$this->request | |||
$this->request, | |||
$this->twoFactorManager | |||
); | |||
} | |||
@@ -295,6 +302,59 @@ class AuthTest extends TestCase { | |||
$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 | |||
* @expectedExceptionMessage CSRF check not passed. |