xref: /plugin/oauth/action/login.php (revision d9be1cb5d4b89892fd7351309c9c9722836436f4)
137d2401aSAnna Dabrowska<?php
237d2401aSAnna Dabrowska
3*d9be1cb5SAnna Dabrowskause dokuwiki\plugin\oauth\SessionManager;
437d2401aSAnna Dabrowskause OAuth\Common\Http\Exception\TokenResponseException;
537d2401aSAnna Dabrowska
637d2401aSAnna Dabrowska/**
737d2401aSAnna Dabrowska * DokuWiki Plugin oauth (Action Component)
837d2401aSAnna Dabrowska *
937d2401aSAnna Dabrowska * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
1037d2401aSAnna Dabrowska * @author  Andreas Gohr <andi@splitbrain.org>
1137d2401aSAnna Dabrowska */
1237d2401aSAnna Dabrowskaclass action_plugin_oauth_login extends DokuWiki_Action_Plugin
1337d2401aSAnna Dabrowska{
1437d2401aSAnna Dabrowska    /** @var helper_plugin_oauth */
1537d2401aSAnna Dabrowska    protected $hlp;
1637d2401aSAnna Dabrowska
1737d2401aSAnna Dabrowska    /**
1837d2401aSAnna Dabrowska     * Constructor
1937d2401aSAnna Dabrowska     *
2037d2401aSAnna Dabrowska     * Initializes the helper
2137d2401aSAnna Dabrowska     */
2237d2401aSAnna Dabrowska    public function __construct()
2337d2401aSAnna Dabrowska    {
2437d2401aSAnna Dabrowska        $this->hlp = plugin_load('helper', 'oauth');
2537d2401aSAnna Dabrowska    }
2637d2401aSAnna Dabrowska
2737d2401aSAnna Dabrowska    /**
2837d2401aSAnna Dabrowska     * Registers a callback function for a given event
2937d2401aSAnna Dabrowska     *
3037d2401aSAnna Dabrowska     * @param Doku_Event_Handler $controller DokuWiki's event controller object
3137d2401aSAnna Dabrowska     * @return void
3237d2401aSAnna Dabrowska     */
3337d2401aSAnna Dabrowska    public function register(Doku_Event_Handler $controller)
3437d2401aSAnna Dabrowska    {
3537d2401aSAnna Dabrowska        global $conf;
3637d2401aSAnna Dabrowska        if ($conf['authtype'] != 'oauth') return;
3737d2401aSAnna Dabrowska
3837d2401aSAnna Dabrowska        $conf['profileconfirm'] = false; // password confirmation doesn't work with oauth only users
3937d2401aSAnna Dabrowska
4037d2401aSAnna Dabrowska        $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'handleStart');
4137d2401aSAnna Dabrowska        $controller->register_hook('HTML_LOGINFORM_OUTPUT', 'BEFORE', $this, 'handleLoginform');
4237d2401aSAnna Dabrowska        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleDoLogin');
4337d2401aSAnna Dabrowska    }
4437d2401aSAnna Dabrowska
4537d2401aSAnna Dabrowska    /**
4637d2401aSAnna Dabrowska     * Start an oAuth login or restore  environment after successful login
4737d2401aSAnna Dabrowska     *
4837d2401aSAnna Dabrowska     * @param Doku_Event $event
4937d2401aSAnna Dabrowska     * @return void
5037d2401aSAnna Dabrowska     */
5137d2401aSAnna Dabrowska    public function handleStart(Doku_Event $event)
5237d2401aSAnna Dabrowska    {
5337d2401aSAnna Dabrowska        global $INPUT;
5437d2401aSAnna Dabrowska
5537d2401aSAnna Dabrowska        // login has been done, but there's environment to be restored
56*d9be1cb5SAnna Dabrowska        // TODO when is this the case?
57*d9be1cb5SAnna Dabrowska        $sessionManager = SessionManager::getInstance();
58*d9be1cb5SAnna Dabrowska        if ($sessionManager->getDo() || $sessionManager->getRev()) {
5937d2401aSAnna Dabrowska            $this->restoreSessionEnvironment();
6037d2401aSAnna Dabrowska            return;
6137d2401aSAnna Dabrowska        }
6237d2401aSAnna Dabrowska
6337d2401aSAnna Dabrowska        // see if a login needs to be started
6437d2401aSAnna Dabrowska        $servicename = $INPUT->str('oauthlogin');
6537d2401aSAnna Dabrowska        if ($servicename) $this->startOAuthLogin($servicename);
6637d2401aSAnna Dabrowska    }
6737d2401aSAnna Dabrowska
6837d2401aSAnna Dabrowska    /**
69*d9be1cb5SAnna Dabrowska     * Add the oAuth login links to login form
7037d2401aSAnna Dabrowska     *
7137d2401aSAnna Dabrowska     * @param Doku_Event $event event object by reference
7237d2401aSAnna Dabrowska     * @return void
7337d2401aSAnna Dabrowska     */
7437d2401aSAnna Dabrowska    public function handleLoginform(Doku_Event $event)
7537d2401aSAnna Dabrowska    {
7637d2401aSAnna Dabrowska        /** @var Doku_Form $form */
7737d2401aSAnna Dabrowska        $form = $event->data;
7837d2401aSAnna Dabrowska        $html = '';
7937d2401aSAnna Dabrowska
8037d2401aSAnna Dabrowska        $validDomains = $this->hlp->getValidDomains();
8137d2401aSAnna Dabrowska
8237d2401aSAnna Dabrowska        if (count($validDomains) > 0) {
8337d2401aSAnna Dabrowska            $html .= sprintf($this->getLang('eMailRestricted'), join(', ', $validDomains));
8437d2401aSAnna Dabrowska        }
8537d2401aSAnna Dabrowska
8637d2401aSAnna Dabrowska        foreach ($this->hlp->listServices() as $service) {
8737d2401aSAnna Dabrowska            $html .= $service->loginButton();
8837d2401aSAnna Dabrowska        }
8937d2401aSAnna Dabrowska        if (!$html) return;
9037d2401aSAnna Dabrowska
9137d2401aSAnna Dabrowska        $form->_content[] = form_openfieldset(
9237d2401aSAnna Dabrowska            [
9337d2401aSAnna Dabrowska                '_legend' => $this->getLang('loginwith'),
9437d2401aSAnna Dabrowska                'class' => 'plugin_oauth',
9537d2401aSAnna Dabrowska            ]
9637d2401aSAnna Dabrowska        );
9737d2401aSAnna Dabrowska        $form->_content[] = $html;
9837d2401aSAnna Dabrowska        $form->_content[] = form_closefieldset();
9937d2401aSAnna Dabrowska    }
10037d2401aSAnna Dabrowska
10137d2401aSAnna Dabrowska    /**
10237d2401aSAnna Dabrowska     * When singleservice is wanted, do not show login, but execute login right away
10337d2401aSAnna Dabrowska     *
10437d2401aSAnna Dabrowska     * @param Doku_Event $event
10537d2401aSAnna Dabrowska     * @return bool
10637d2401aSAnna Dabrowska     */
10737d2401aSAnna Dabrowska    public function handleDoLogin(Doku_Event $event)
10837d2401aSAnna Dabrowska    {
10937d2401aSAnna Dabrowska        global $ID;
11037d2401aSAnna Dabrowska
11137d2401aSAnna Dabrowska        if ($event->data != 'login') return true;
11237d2401aSAnna Dabrowska
11337d2401aSAnna Dabrowska        $singleService = $this->getConf('singleService');
11437d2401aSAnna Dabrowska        if (!$singleService) return true;
11537d2401aSAnna Dabrowska
11637d2401aSAnna Dabrowska        $enabledServices = $this->hlp->listServices();
11737d2401aSAnna Dabrowska        if (count($enabledServices) !== 1) {
11837d2401aSAnna Dabrowska            msg($this->getLang('wrongConfig'), -1);
11937d2401aSAnna Dabrowska            return false;
12037d2401aSAnna Dabrowska        }
12137d2401aSAnna Dabrowska
12237d2401aSAnna Dabrowska        $service = array_shift($enabledServices);
12337d2401aSAnna Dabrowska
12437d2401aSAnna Dabrowska        $url = wl($ID, ['oauthlogin' => $service->getServiceID()], true, '&');
12537d2401aSAnna Dabrowska        send_redirect($url);
12637d2401aSAnna Dabrowska        return true; // never reached
12737d2401aSAnna Dabrowska    }
12837d2401aSAnna Dabrowska
12937d2401aSAnna Dabrowska    /**
13037d2401aSAnna Dabrowska     * start the oauth login
13137d2401aSAnna Dabrowska     *
13237d2401aSAnna Dabrowska     * This will redirect to the external service and stop processing in this request.
13337d2401aSAnna Dabrowska     * The second part of the login will happen in auth
13437d2401aSAnna Dabrowska     *
13537d2401aSAnna Dabrowska     * @see auth_plugin_oauth
13637d2401aSAnna Dabrowska     */
13737d2401aSAnna Dabrowska    protected function startOAuthLogin($servicename)
13837d2401aSAnna Dabrowska    {
13937d2401aSAnna Dabrowska        global $ID;
14037d2401aSAnna Dabrowska        $service = $this->hlp->loadService($servicename);
14137d2401aSAnna Dabrowska        if (is_null($service)) return;
14237d2401aSAnna Dabrowska
14337d2401aSAnna Dabrowska        // remember service in session
144*d9be1cb5SAnna Dabrowska        $sessionManager = SessionManager::getInstance();
145*d9be1cb5SAnna Dabrowska        $sessionManager->setServiceName($servicename);
146*d9be1cb5SAnna Dabrowska        $sessionManager->setPid($ID);
147*d9be1cb5SAnna Dabrowska        $sessionManager->saveState();
14837d2401aSAnna Dabrowska
14937d2401aSAnna Dabrowska        try {
15037d2401aSAnna Dabrowska            $service->login(); // redirects
15137d2401aSAnna Dabrowska        } catch (TokenResponseException $e) {
15237d2401aSAnna Dabrowska            $this->hlp->showException($e, 'login failed');
15337d2401aSAnna Dabrowska        }
15437d2401aSAnna Dabrowska    }
15537d2401aSAnna Dabrowska
15637d2401aSAnna Dabrowska    /**
15737d2401aSAnna Dabrowska     * Restore the request environment that had been set before the oauth shuffle
15837d2401aSAnna Dabrowska     */
15937d2401aSAnna Dabrowska    protected function restoreSessionEnvironment()
16037d2401aSAnna Dabrowska    {
16137d2401aSAnna Dabrowska        global $INPUT, $ACT, $TEXT, $PRE, $SUF, $SUM, $RANGE, $DATE_AT, $REV;
162*d9be1cb5SAnna Dabrowska
163*d9be1cb5SAnna Dabrowska        $sessionManager = SessionManager::getInstance();
164*d9be1cb5SAnna Dabrowska        $ACT = $sessionManager->getDo();
165*d9be1cb5SAnna Dabrowska        $_REQUEST = $sessionManager->getRequest();
16637d2401aSAnna Dabrowska
16737d2401aSAnna Dabrowska        $REV = $INPUT->int('rev');
16837d2401aSAnna Dabrowska        $DATE_AT = $INPUT->str('at');
16937d2401aSAnna Dabrowska        $RANGE = $INPUT->str('range');
17037d2401aSAnna Dabrowska        if ($INPUT->post->has('wikitext')) {
17137d2401aSAnna Dabrowska            $TEXT = cleanText($INPUT->post->str('wikitext'));
17237d2401aSAnna Dabrowska        }
17337d2401aSAnna Dabrowska        $PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1));
17437d2401aSAnna Dabrowska        $SUF = cleanText($INPUT->post->str('suffix'));
17537d2401aSAnna Dabrowska        $SUM = $INPUT->post->str('summary');
17637d2401aSAnna Dabrowska
177*d9be1cb5SAnna Dabrowska        $sessionManager->setDo('');
178*d9be1cb5SAnna Dabrowska        $sessionManager->setRequest([]);
179*d9be1cb5SAnna Dabrowska        $sessionManager->saveState();
18037d2401aSAnna Dabrowska    }
18137d2401aSAnna Dabrowska}
182