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