xref: /plugin/oauth/action/login.php (revision ef19de6c1639a03fb1fe37ad0d720a82c66b9cf7)
1<?php
2
3use dokuwiki\Form\Form;
4use dokuwiki\plugin\oauth\OAuthManager;
5use OAuth\Common\Http\Exception\TokenResponseException;
6
7/**
8 * DokuWiki Plugin oauth (Action Component)
9 *
10 * This adds buttons to the login page and initializes the oAuth flow by redirecting the user
11 * to the third party service
12 *
13 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
14 * @author  Andreas Gohr <andi@splitbrain.org>
15 */
16class action_plugin_oauth_login extends DokuWiki_Action_Plugin
17{
18    /** @var helper_plugin_oauth */
19    protected $hlp;
20
21    /**
22     * Constructor
23     *
24     * Initializes the helper
25     */
26    public function __construct()
27    {
28        $this->hlp = plugin_load('helper', 'oauth');
29    }
30
31    /**
32     * Registers a callback function for a given event
33     *
34     * @param Doku_Event_Handler $controller DokuWiki's event controller object
35     * @return void
36     */
37    public function register(Doku_Event_Handler $controller)
38    {
39        global $conf;
40        if ($conf['authtype'] != 'oauth') return;
41
42        $conf['profileconfirm'] = false; // password confirmation doesn't work with oauth only users
43
44        $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'handleStart');
45        $controller->register_hook('HTML_LOGINFORM_OUTPUT', 'BEFORE', $this, 'handleOldLoginForm'); // @deprecated
46        $controller->register_hook('FORM_LOGIN_OUTPUT', 'BEFORE', $this, 'handleLoginForm');
47        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleDoLogin');
48    }
49
50    /**
51     * Start an oAuth login or restore  environment after successful login
52     *
53     * @param Doku_Event $event
54     * @return void
55     */
56    public function handleStart(Doku_Event $event)
57    {
58        global $INPUT;
59
60        // see if a login needs to be started
61        $servicename = $INPUT->str('oauthlogin');
62        if (!$servicename) return;
63
64        try {
65            $om = new OAuthManager();
66            $om->startFlow($servicename);
67        } catch (TokenResponseException|Exception $e) {
68            $this->hlp->showException($e, 'login failed');
69        }
70    }
71
72    /**
73     * Add the oAuth login links to login form
74     *
75     * @param Doku_Event $event event object by reference
76     * @return void
77     * @deprecated can be removed in the future
78     */
79    public function handleOldLoginForm(Doku_Event $event)
80    {
81        /** @var Doku_Form $form */
82        $form = $event->data;
83        $html = $this->prepareLoginButtons();
84        if (!$html) return;
85
86        $form->_content[] = form_openfieldset(
87            [
88                '_legend' => $this->getLang('loginwith'),
89                'class' => 'plugin_oauth',
90            ]
91        );
92        $form->_content[] = $html;
93        $form->_content[] = form_closefieldset();
94    }
95
96    /**
97     * Add the oAuth login links to login form
98     *
99     * @param Doku_Event $event event object by reference
100     * @return void
101     * @deprecated can be removed in the future
102     */
103    public function handleLoginForm(Doku_Event $event)
104    {
105        /** @var Form $form */
106        $form = $event->data;
107        $html = $this->prepareLoginButtons();
108        if (!$html) return;
109
110        $form->addFieldsetOpen($this->getLang('loginwith'))->addClass('plugin_oauth');
111        $form->addHTML($html);
112        $form->addFieldsetClose();
113    }
114
115    /**
116     * Create HTML for the various login buttons
117     *
118     * @return string the HTML
119     */
120    protected function prepareLoginButtons()
121    {
122        $html = '';
123
124        $validDomains = $this->hlp->getValidDomains();
125
126        if (count($validDomains) > 0) {
127            $html .= '<p class="plugin-oauth-emailrestriction">' . sprintf(
128                    $this->getLang('eMailRestricted'),
129                    '<b>' . join(', ', $validDomains) . '</b>'
130                ) . '</p>';
131        }
132
133        $html .= '<div>';
134        foreach ($this->hlp->listServices() as $service) {
135            $html .= $service->loginButton();
136        }
137        $html .= '</div>';
138
139        return $html;
140    }
141
142    /**
143     * When singleservice is wanted, do not show login, but execute login right away
144     *
145     * @param Doku_Event $event
146     * @return bool
147     */
148    public function handleDoLogin(Doku_Event $event)
149    {
150        global $ID;
151
152        if ($event->data != 'login') return true;
153
154        $singleService = $this->getConf('singleService');
155        if (!$singleService) return true;
156
157        $enabledServices = $this->hlp->listServices();
158        if (count($enabledServices) !== 1) {
159            msg($this->getLang('wrongConfig'), -1);
160            return false;
161        }
162
163        $service = array_shift($enabledServices);
164
165        $url = wl($ID, ['oauthlogin' => $service->getServiceID()], true, '&');
166        send_redirect($url);
167        return true; // never reached
168    }
169
170}
171