xref: /plugin/oauth/action/login.php (revision 45fc651dfa4d39f84fada97824bab8f6b1e7782c)
137d2401aSAnna Dabrowska<?php
237d2401aSAnna Dabrowska
31fad6988SAndreas Gohruse dokuwiki\Form\Form;
4e170f465SAndreas Gohruse dokuwiki\plugin\oauth\OAuthManager;
537d2401aSAnna Dabrowskause OAuth\Common\Http\Exception\TokenResponseException;
637d2401aSAnna Dabrowska
737d2401aSAnna Dabrowska/**
837d2401aSAnna Dabrowska * DokuWiki Plugin oauth (Action Component)
937d2401aSAnna Dabrowska *
1074b4d4a4SAndreas Gohr * This adds buttons to the login page and initializes the oAuth flow by redirecting the user
1174b4d4a4SAndreas Gohr * to the third party service
1274b4d4a4SAndreas Gohr *
1337d2401aSAnna Dabrowska * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
1437d2401aSAnna Dabrowska * @author  Andreas Gohr <andi@splitbrain.org>
1537d2401aSAnna Dabrowska */
1637d2401aSAnna Dabrowskaclass action_plugin_oauth_login extends DokuWiki_Action_Plugin
1737d2401aSAnna Dabrowska{
1837d2401aSAnna Dabrowska    /** @var helper_plugin_oauth */
1937d2401aSAnna Dabrowska    protected $hlp;
2037d2401aSAnna Dabrowska
2137d2401aSAnna Dabrowska    /**
2237d2401aSAnna Dabrowska     * Constructor
2337d2401aSAnna Dabrowska     *
2437d2401aSAnna Dabrowska     * Initializes the helper
2537d2401aSAnna Dabrowska     */
2637d2401aSAnna Dabrowska    public function __construct()
2737d2401aSAnna Dabrowska    {
2837d2401aSAnna Dabrowska        $this->hlp = plugin_load('helper', 'oauth');
2937d2401aSAnna Dabrowska    }
3037d2401aSAnna Dabrowska
3137d2401aSAnna Dabrowska    /**
3237d2401aSAnna Dabrowska     * Registers a callback function for a given event
3337d2401aSAnna Dabrowska     *
3437d2401aSAnna Dabrowska     * @param Doku_Event_Handler $controller DokuWiki's event controller object
3537d2401aSAnna Dabrowska     * @return void
3637d2401aSAnna Dabrowska     */
3737d2401aSAnna Dabrowska    public function register(Doku_Event_Handler $controller)
3837d2401aSAnna Dabrowska    {
3937d2401aSAnna Dabrowska        global $conf;
4037d2401aSAnna Dabrowska        if ($conf['authtype'] != 'oauth') return;
4137d2401aSAnna Dabrowska
4237d2401aSAnna Dabrowska        $conf['profileconfirm'] = false; // password confirmation doesn't work with oauth only users
4337d2401aSAnna Dabrowska
4437d2401aSAnna Dabrowska        $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'handleStart');
451fad6988SAndreas Gohr        $controller->register_hook('HTML_LOGINFORM_OUTPUT', 'BEFORE', $this, 'handleOldLoginForm'); // @deprecated
461fad6988SAndreas Gohr        $controller->register_hook('FORM_LOGIN_OUTPUT', 'BEFORE', $this, 'handleLoginForm');
4737d2401aSAnna Dabrowska        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleDoLogin');
4837d2401aSAnna Dabrowska    }
4937d2401aSAnna Dabrowska
5037d2401aSAnna Dabrowska    /**
5137d2401aSAnna Dabrowska     * Start an oAuth login or restore  environment after successful login
5237d2401aSAnna Dabrowska     *
5337d2401aSAnna Dabrowska     * @param Doku_Event $event
5437d2401aSAnna Dabrowska     * @return void
5537d2401aSAnna Dabrowska     */
5637d2401aSAnna Dabrowska    public function handleStart(Doku_Event $event)
5737d2401aSAnna Dabrowska    {
5837d2401aSAnna Dabrowska        global $INPUT;
5937d2401aSAnna Dabrowska
6037d2401aSAnna Dabrowska        // see if a login needs to be started
6137d2401aSAnna Dabrowska        $servicename = $INPUT->str('oauthlogin');
626d9a8a49SAndreas Gohr        if (!$servicename) return;
636d9a8a49SAndreas Gohr
646d9a8a49SAndreas Gohr        try {
65e170f465SAndreas Gohr            $om = new OAuthManager();
666d9a8a49SAndreas Gohr            $om->startFlow($servicename);
676d9a8a49SAndreas Gohr        } catch (TokenResponseException|Exception $e) {
686d9a8a49SAndreas Gohr            $this->hlp->showException($e, 'login failed');
696d9a8a49SAndreas Gohr        }
7037d2401aSAnna Dabrowska    }
7137d2401aSAnna Dabrowska
7237d2401aSAnna Dabrowska    /**
73d9be1cb5SAnna Dabrowska     * Add the oAuth login links to login form
7437d2401aSAnna Dabrowska     *
7537d2401aSAnna Dabrowska     * @param Doku_Event $event event object by reference
7637d2401aSAnna Dabrowska     * @return void
7774b4d4a4SAndreas Gohr     * @deprecated can be removed in the future
7837d2401aSAnna Dabrowska     */
791fad6988SAndreas Gohr    public function handleOldLoginForm(Doku_Event $event)
8037d2401aSAnna Dabrowska    {
8137d2401aSAnna Dabrowska        /** @var Doku_Form $form */
8237d2401aSAnna Dabrowska        $form = $event->data;
831fad6988SAndreas Gohr        $html = $this->prepareLoginButtons();
841fad6988SAndreas Gohr        if (!$html) return;
851fad6988SAndreas Gohr
86*45fc651dSAnna Dabrowska        // remove login form if single service is set
87*45fc651dSAnna Dabrowska        $singleService = $this->getConf('singleService');
88*45fc651dSAnna Dabrowska        if ($singleService) {
89*45fc651dSAnna Dabrowska            $form->_content = [];
90*45fc651dSAnna Dabrowska        }
91*45fc651dSAnna Dabrowska
921fad6988SAndreas Gohr        $form->_content[] = form_openfieldset(
931fad6988SAndreas Gohr            [
941fad6988SAndreas Gohr                '_legend' => $this->getLang('loginwith'),
951fad6988SAndreas Gohr                'class' => 'plugin_oauth',
961fad6988SAndreas Gohr            ]
971fad6988SAndreas Gohr        );
981fad6988SAndreas Gohr        $form->_content[] = $html;
991fad6988SAndreas Gohr        $form->_content[] = form_closefieldset();
1001fad6988SAndreas Gohr    }
1011fad6988SAndreas Gohr
1021fad6988SAndreas Gohr    /**
1031fad6988SAndreas Gohr     * Add the oAuth login links to login form
1041fad6988SAndreas Gohr     *
1051fad6988SAndreas Gohr     * @param Doku_Event $event event object by reference
1061fad6988SAndreas Gohr     * @return void
10774b4d4a4SAndreas Gohr     * @deprecated can be removed in the future
1081fad6988SAndreas Gohr     */
1091fad6988SAndreas Gohr    public function handleLoginForm(Doku_Event $event)
1101fad6988SAndreas Gohr    {
1111fad6988SAndreas Gohr        /** @var Form $form */
1121fad6988SAndreas Gohr        $form = $event->data;
1131fad6988SAndreas Gohr        $html = $this->prepareLoginButtons();
1141fad6988SAndreas Gohr        if (!$html) return;
1151fad6988SAndreas Gohr
116*45fc651dSAnna Dabrowska        // remove login form if single service is set
117*45fc651dSAnna Dabrowska        $singleService = $this->getConf('singleService');
118*45fc651dSAnna Dabrowska        if ($singleService) {
119*45fc651dSAnna Dabrowska            do {
120*45fc651dSAnna Dabrowska                $form->removeElement(0);
121*45fc651dSAnna Dabrowska            } while ($form->elementCount() > 0);
122*45fc651dSAnna Dabrowska        }
123*45fc651dSAnna Dabrowska
1241fad6988SAndreas Gohr        $form->addFieldsetOpen($this->getLang('loginwith'))->addClass('plugin_oauth');
1251fad6988SAndreas Gohr        $form->addHTML($html);
1261fad6988SAndreas Gohr        $form->addFieldsetClose();
1271fad6988SAndreas Gohr    }
1281fad6988SAndreas Gohr
1291fad6988SAndreas Gohr    /**
1301fad6988SAndreas Gohr     * Create HTML for the various login buttons
1311fad6988SAndreas Gohr     *
1321fad6988SAndreas Gohr     * @return string the HTML
1331fad6988SAndreas Gohr     */
13474b4d4a4SAndreas Gohr    protected function prepareLoginButtons()
13574b4d4a4SAndreas Gohr    {
13637d2401aSAnna Dabrowska        $html = '';
13737d2401aSAnna Dabrowska
13837d2401aSAnna Dabrowska        $validDomains = $this->hlp->getValidDomains();
13937d2401aSAnna Dabrowska
14037d2401aSAnna Dabrowska        if (count($validDomains) > 0) {
1416f3a59e8SAndreas Gohr            $html .= '<p class="plugin-oauth-emailrestriction">' . sprintf(
1426f3a59e8SAndreas Gohr                    $this->getLang('eMailRestricted'),
1436f3a59e8SAndreas Gohr                    '<b>' . join(', ', $validDomains) . '</b>'
1446f3a59e8SAndreas Gohr                ) . '</p>';
14537d2401aSAnna Dabrowska        }
14637d2401aSAnna Dabrowska
147ef19de6cSAndreas Gohr        $html .= '<div>';
14837d2401aSAnna Dabrowska        foreach ($this->hlp->listServices() as $service) {
14937d2401aSAnna Dabrowska            $html .= $service->loginButton();
15037d2401aSAnna Dabrowska        }
151ef19de6cSAndreas Gohr        $html .= '</div>';
15237d2401aSAnna Dabrowska
1531fad6988SAndreas Gohr        return $html;
15437d2401aSAnna Dabrowska    }
15537d2401aSAnna Dabrowska
15637d2401aSAnna Dabrowska    /**
15737d2401aSAnna Dabrowska     * When singleservice is wanted, do not show login, but execute login right away
15837d2401aSAnna Dabrowska     *
15937d2401aSAnna Dabrowska     * @param Doku_Event $event
16037d2401aSAnna Dabrowska     * @return bool
16137d2401aSAnna Dabrowska     */
16237d2401aSAnna Dabrowska    public function handleDoLogin(Doku_Event $event)
16337d2401aSAnna Dabrowska    {
16437d2401aSAnna Dabrowska        global $ID;
16537d2401aSAnna Dabrowska
16637d2401aSAnna Dabrowska        if ($event->data != 'login') return true;
16737d2401aSAnna Dabrowska
16837d2401aSAnna Dabrowska        $singleService = $this->getConf('singleService');
16937d2401aSAnna Dabrowska        if (!$singleService) return true;
17037d2401aSAnna Dabrowska
17137d2401aSAnna Dabrowska        $enabledServices = $this->hlp->listServices();
17237d2401aSAnna Dabrowska        if (count($enabledServices) !== 1) {
17337d2401aSAnna Dabrowska            msg($this->getLang('wrongConfig'), -1);
17437d2401aSAnna Dabrowska            return false;
17537d2401aSAnna Dabrowska        }
17637d2401aSAnna Dabrowska
17737d2401aSAnna Dabrowska        $service = array_shift($enabledServices);
17837d2401aSAnna Dabrowska
17937d2401aSAnna Dabrowska        $url = wl($ID, ['oauthlogin' => $service->getServiceID()], true, '&');
18037d2401aSAnna Dabrowska        send_redirect($url);
18137d2401aSAnna Dabrowska        return true; // never reached
18237d2401aSAnna Dabrowska    }
18337d2401aSAnna Dabrowska
18437d2401aSAnna Dabrowska}
185