1<?php
2
3use dokuwiki\Form\Form;
4
5/**
6 * DokuWiki Plugin oauth (Action Component)
7 *
8 * This manages profile changes and allows the user to change their oauth groups.
9 * We use group memberships to define if logins are okay with the given services.
10 *
11 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
12 * @author  Andreas Gohr <andi@splitbrain.org>
13 */
14class action_plugin_oauth_user extends DokuWiki_Action_Plugin
15{
16    /** @var helper_plugin_oauth */
17    protected $hlp;
18
19    /**
20     * Constructor
21     *
22     * Initializes the helper
23     */
24    public function __construct()
25    {
26        $this->hlp = plugin_load('helper', 'oauth');
27    }
28
29    /**
30     * Registers a callback function for a given event
31     *
32     * @param Doku_Event_Handler $controller DokuWiki's event controller object
33     * @return void
34     */
35    public function register(Doku_Event_Handler $controller)
36    {
37        global $conf;
38        if ($conf['authtype'] != 'oauth') return;
39
40        $conf['profileconfirm'] = false; // password confirmation doesn't work with oauth only users
41
42        $controller->register_hook('HTML_UPDATEPROFILEFORM_OUTPUT', 'BEFORE', $this,
43            'handleOldProfileform'); // deprecated
44        $controller->register_hook('FORM_UPDATEPROFILE_OUTPUT', 'BEFORE', $this, 'handleProfileform');
45        $controller->register_hook('AUTH_USER_CHANGE', 'BEFORE', $this, 'handleUsermod');
46    }
47
48    /**
49     * Save groups for all the services a user has enabled
50     *
51     * @param Doku_Event $event event object by reference
52     * @return void
53     */
54    public function handleUsermod(Doku_Event $event)
55    {
56        global $ACT;
57        global $USERINFO;
58        global $auth;
59        global $INPUT;
60
61        if ($event->data['type'] != 'modify') return;
62        if ($ACT != 'profile') return;
63
64        // we want to modify the user's groups
65        $groups = $USERINFO['grps']; //current groups
66        if (isset($event->data['params'][1]['grps'])) {
67            // something already defined new groups
68            $groups = $event->data['params'][1]['grps'];
69        }
70
71        // get enabled and configured services
72        $enabled = $INPUT->arr('oauth_group');
73        $services = array_keys($this->hlp->listServices());
74        $services = array_map([$auth, 'cleanGroup'], $services);
75
76        // add all enabled services as group, remove all disabled services
77        foreach ($services as $service) {
78            if (isset($enabled[$service])) {
79                $groups[] = $service;
80            } else {
81                $idx = array_search($service, $groups);
82                if ($idx !== false) unset($groups[$idx]);
83            }
84        }
85        $groups = array_unique($groups);
86
87        // add new group array to event data
88        $event->data['params'][1]['grps'] = $groups;
89    }
90
91    /**
92     * Add service selection to user profile
93     *
94     * @param Doku_Event $event event object by reference
95     * @return void
96     * @deprecated
97     */
98    public function handleOldProfileform(Doku_Event $event)
99    {
100        global $USERINFO;
101        /** @var auth_plugin_authplain $auth */
102        global $auth;
103
104        /** @var Doku_Form $form */
105        $form = $event->data;
106        $pos = $form->findElementByAttribute('type', 'submit');
107
108        $services = $this->hlp->listServices();
109        if (!$services) return;
110
111        $form->insertElement($pos, form_closefieldset());
112        $form->insertElement(
113            ++$pos,
114            form_openfieldset(['_legend' => $this->getLang('loginwith'), 'class' => 'plugin_oauth'])
115        );
116        foreach ($services as $service) {
117            $group = $auth->cleanGroup($service->getServiceID());
118            $elem = form_makeCheckboxField(
119                'oauth_group[' . $group . ']',
120                1, $service->getLabel(), '', 'simple',
121                [
122                    'checked' => (in_array($group, $USERINFO['grps'])) ? 'checked' : '',
123                ]
124            );
125
126            $form->insertElement(++$pos, $elem);
127        }
128        $form->insertElement(++$pos, form_closefieldset());
129        $form->insertElement(++$pos, form_openfieldset([]));
130    }
131
132    /**
133     * Add service selection to user profile
134     *
135     * @param Doku_Event $event event object by reference
136     * @return void
137     */
138    public function handleProfileform(Doku_Event $event)
139    {
140        global $USERINFO;
141        /** @var auth_plugin_authplain $auth */
142        global $auth;
143
144        /** @var Form $form */
145        $form = $event->data;
146        $pos = $form->findPositionByAttribute('type', 'submit');
147
148        $services = $this->hlp->listServices();
149        if (!$services) return;
150
151        $form->addFieldsetOpen($this->getLang('loginwith'), $pos)->addClass('plugin_oauth');
152
153        foreach ($services as $service) {
154            $group = $auth->cleanGroup($service->getServiceID());
155            $cb = $form->addCheckbox(
156                'oauth_group[' . $group . ']',
157                $service->getLabel(),
158                ++$pos
159            );
160            if (in_array($group, $USERINFO['grps'])) {
161                $cb->attr('checked', 'checked');
162            }
163        }
164        $form->addFieldsetClose(++$pos);
165    }
166}
167