3 use wcf\data\
object\type\ObjectType
;
4 use wcf\data\user\User
;
5 use wcf\form\AbstractFormBuilderForm
;
6 use wcf\system\application\ApplicationHandler
;
7 use wcf\system\cache\runtime\UserProfileRuntimeCache
;
8 use wcf\system\exception\IllegalLinkException
;
9 use wcf\system\exception\NamedUserException
;
10 use wcf\system\form\builder\TemplateFormNode
;
11 use wcf\system\request\LinkHandler
;
12 use wcf\system\user\multifactor\IMultifactorMethod
;
13 use wcf\system\user\multifactor\Setup
;
15 use wcf\util\HeaderUtil
;
18 * Represents the multi-factor authentication form.
20 * @author Tim Duesterhus
21 * @copyright 2001-2020 WoltLab GmbH
22 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
23 * @package WoltLabSuite\Core\Form
26 class MultifactorAuthenticationForm
extends AbstractFormBuilderForm
{
27 const AVAILABLE_DURING_OFFLINE_MODE
= true;
32 public $formAction = 'authenticate';
50 * @var IMultifactorMethod
67 public function readParameters() {
68 parent
::readParameters();
70 if (!empty($_GET['url']) && ApplicationHandler
::getInstance()->isInternalURL($_GET['url'])) {
71 $this->redirectUrl
= $_GET['url'];
74 if (WCF
::getUser()->userID
) {
75 $this->performRedirect();
78 $this->user
= WCF
::getSession()->getPendingUserChange();
80 throw new NamedUserException(WCF
::getLanguage()->getDynamicVariable(
81 'wcf.user.security.multifactor.authentication.noPendingUserChange'
85 $this->setups
= Setup
::getAllForUser($this->user
);
87 if (empty($this->setups
)) {
88 throw new NamedUserException(WCF
::getLanguage()->getDynamicVariable(
89 'wcf.user.security.multifactor.authentication.noSetup',
91 'user' => $this->user
,
96 \
uasort($this->setups
, function (Setup
$a, Setup
$b) {
97 return $b->getObjectType()->priority
<=> $a->getObjectType()->priority
;
100 $setupId = \array_keys
($this->setups
)[0];
101 if (isset($_GET['id'])) {
102 $setupId = intval($_GET['id']);
105 if (!isset($this->setups
[$setupId])) {
106 throw new IllegalLinkException();
109 $this->setup
= $this->setups
[$setupId];
110 $this->method
= $this->setup
->getObjectType();
111 \assert
($this->method
->getDefinition()->definitionName
=== 'com.woltlab.wcf.multifactor');
113 $this->processor
= $this->method
->getProcessor();
119 protected function createForm() {
120 parent
::createForm();
122 $this->form
->appendChild(
123 TemplateFormNode
::create('loginAs')
124 ->templateName('__multifactorAuthenticationLoginAs')
127 $this->processor
->createAuthenticationForm($this->form
, $this->setup
);
130 public function save() {
131 AbstractForm
::save();
133 WCF
::getDB()->beginTransaction();
135 $setup = $this->setup
->lock();
137 $this->processor
->processAuthenticationForm($this->form
, $setup);
139 WCF
::getDB()->commitTransaction();
141 WCF
::getSession()->applyPendingUserChange($this->user
);
149 public function saved() {
150 AbstractForm
::saved();
152 $this->performRedirect();
156 * Returns to the redirectUrl if given and to the landing page otherwise.
158 protected function performRedirect() {
159 if ($this->redirectUrl
) {
160 HeaderUtil
::redirect($this->redirectUrl
);
163 HeaderUtil
::redirect(LinkHandler
::getInstance()->getLink());
171 protected function setFormAction() {
172 $this->form
->action(LinkHandler
::getInstance()->getControllerLink(static::class, [
173 'object' => $this->setup
,
174 'url' => $this->redirectUrl
,
181 public function assignVariables() {
182 parent
::assignVariables();
184 WCF
::getTPL()->assign([
185 'setups' => $this->setups
,
186 'user' => $this->user
,
187 'userProfile' => UserProfileRuntimeCache
::getInstance()->getObject($this->user
->userID
),
188 'setup' => $this->setup
,
189 'redirectUrl' => $this->redirectUrl
,