TwoFactorChallengeController.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Christoph Wurst <christoph@owncloud.com>
  6. * @author Joas Schilling <coding@schilljs.com>
  7. *
  8. * @license AGPL-3.0
  9. *
  10. * This code is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License, version 3,
  12. * as published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License, version 3,
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>
  21. *
  22. */
  23. namespace OC\Core\Controller;
  24. use OC\Authentication\TwoFactorAuth\Manager;
  25. use OC_User;
  26. use OC_Util;
  27. use OCP\AppFramework\Controller;
  28. use OCP\AppFramework\Http\RedirectResponse;
  29. use OCP\AppFramework\Http\TemplateResponse;
  30. use OCP\IRequest;
  31. use OCP\ISession;
  32. use OCP\IURLGenerator;
  33. use OCP\IUserSession;
  34. class TwoFactorChallengeController extends Controller {
  35. /** @var Manager */
  36. private $twoFactorManager;
  37. /** @var IUserSession */
  38. private $userSession;
  39. /** @var ISession */
  40. private $session;
  41. /** @var IURLGenerator */
  42. private $urlGenerator;
  43. /**
  44. * @param string $appName
  45. * @param IRequest $request
  46. * @param Manager $twoFactorManager
  47. * @param IUserSession $userSession
  48. * @param ISession $session
  49. * @param IURLGenerator $urlGenerator
  50. */
  51. public function __construct($appName, IRequest $request, Manager $twoFactorManager, IUserSession $userSession,
  52. ISession $session, IURLGenerator $urlGenerator) {
  53. parent::__construct($appName, $request);
  54. $this->twoFactorManager = $twoFactorManager;
  55. $this->userSession = $userSession;
  56. $this->session = $session;
  57. $this->urlGenerator = $urlGenerator;
  58. }
  59. /**
  60. * @return string
  61. */
  62. protected function getLogoutAttribute() {
  63. return OC_User::getLogoutAttribute();
  64. }
  65. /**
  66. * @NoAdminRequired
  67. * @NoCSRFRequired
  68. *
  69. * @param string $redirect_url
  70. * @return TemplateResponse
  71. */
  72. public function selectChallenge($redirect_url) {
  73. $user = $this->userSession->getUser();
  74. $providers = $this->twoFactorManager->getProviders($user);
  75. $backupProvider = $this->twoFactorManager->getBackupProvider($user);
  76. $data = [
  77. 'providers' => $providers,
  78. 'backupProvider' => $backupProvider,
  79. 'redirect_url' => $redirect_url,
  80. 'logout_attribute' => $this->getLogoutAttribute(),
  81. ];
  82. return new TemplateResponse($this->appName, 'twofactorselectchallenge', $data, 'guest');
  83. }
  84. /**
  85. * @NoAdminRequired
  86. * @NoCSRFRequired
  87. * @UseSession
  88. *
  89. * @param string $challengeProviderId
  90. * @param string $redirect_url
  91. * @return TemplateResponse|RedirectResponse
  92. */
  93. public function showChallenge($challengeProviderId, $redirect_url) {
  94. $user = $this->userSession->getUser();
  95. $provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
  96. if (is_null($provider)) {
  97. return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
  98. }
  99. $backupProvider = $this->twoFactorManager->getBackupProvider($user);
  100. if (!is_null($backupProvider) && $backupProvider->getId() === $provider->getId()) {
  101. // Don't show the backup provider link if we're already showing that provider's challenge
  102. $backupProvider = null;
  103. }
  104. if ($this->session->exists('two_factor_auth_error')) {
  105. $this->session->remove('two_factor_auth_error');
  106. $error = true;
  107. } else {
  108. $error = false;
  109. }
  110. $tmpl = $provider->getTemplate($user);
  111. $tmpl->assign('redirect_url', $redirect_url);
  112. $data = [
  113. 'error' => $error,
  114. 'provider' => $provider,
  115. 'backupProvider' => $backupProvider,
  116. 'logout_attribute' => $this->getLogoutAttribute(),
  117. 'redirect_url' => $redirect_url,
  118. 'template' => $tmpl->fetchPage(),
  119. ];
  120. return new TemplateResponse($this->appName, 'twofactorshowchallenge', $data, 'guest');
  121. }
  122. /**
  123. * @NoAdminRequired
  124. * @NoCSRFRequired
  125. * @UseSession
  126. *
  127. * @param string $challengeProviderId
  128. * @param string $challenge
  129. * @param string $redirect_url
  130. * @return RedirectResponse
  131. */
  132. public function solveChallenge($challengeProviderId, $challenge, $redirect_url = null) {
  133. $user = $this->userSession->getUser();
  134. $provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
  135. if (is_null($provider)) {
  136. return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
  137. }
  138. if ($this->twoFactorManager->verifyChallenge($challengeProviderId, $user, $challenge)) {
  139. if (!is_null($redirect_url)) {
  140. return new RedirectResponse($this->urlGenerator->getAbsoluteURL(urldecode($redirect_url)));
  141. }
  142. return new RedirectResponse(OC_Util::getDefaultPageUrl());
  143. }
  144. $this->session->set('two_factor_auth_error', true);
  145. return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.showChallenge', [
  146. 'challengeProviderId' => $provider->getId(),
  147. 'redirect_url' => $redirect_url,
  148. ]));
  149. }
  150. }