1<?php
2/**
3 * -----------------------------------------------------------------------
4 * vBSSO is a solution which helps you connect to different software platforms
5 * via secure Single Sign-On.
6 *
7 * Copyright (c) 2011-2017 vBSSO. All Rights Reserved.
8 * This software is the proprietary information of vBSSO.
9 *
10 * Author URI: http://www.vbsso.com
11 * License: GPL version 2 or later -
12 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
13 * -----------------------------------------------------------------------
14 */
15
16/**
17 * Report error
18 *
19 * @param mixed $error error message
20 *
21 * @return array
22 */
23function vbsso_listener_report_error($error) {
24    $message = !is_string($error) ? $error[0] : $error;
25
26    return array(SHAREDAPI_EVENT_FIELD_ERROR_CODE => '', SHAREDAPI_EVENT_FIELD_ERROR_MESSAGE => $message,
27        SHAREDAPI_EVENT_FIELD_ERROR_DATA => '');
28}
29
30/**
31 * Verify listener
32 *
33 * @param array $json array
34 *
35 * @return array
36 */
37function vbsso_listener_verify($json) {
38    global $conf;
39    $vbsso = new action_plugin_vbsso();
40    if (!$conf['useacl']) {
41        return array(SHAREDAPI_EVENT_FIELD_ERROR => $vbsso->getLang('acl_is_off'));
42    }
43
44    $supported = vbsso_get_supported_api_properties();
45    $settings = array();
46
47    foreach ($supported as $key => $item) {
48        $settings[$key] = $json[$item['field']];
49    }
50
51    vbsso_save_platform_settings($settings);
52
53    return array(SHAREDAPI_EVENT_FIELD_DATA => array(SHAREDAPI_EVENT_FIELD_VERIFY => TRUE));
54}
55
56
57/**
58 * User load
59 *
60 * @param array $json        array
61 * @param bool  $create_user flag
62 *
63 * @return bool
64 */
65function vbsso_listener_user_load($json, $create_user = FALSE) {
66    global $vbsso_settings;
67    $auth = (class_exists('auth_plugin_authplain')) ? new auth_plugin_authplain() : new auth_plain();
68
69    $usergroups = array();
70    $plugin_ugs = json_decode($vbsso_settings[VBSSO_NAMED_EVENT_FIELD_USERGROUPS_ASSOC]);
71
72    foreach (explode(',', $json[SHAREDAPI_EVENT_FIELD_USERGROUPS]) as $ug) {
73        $usergroups[] = (isset($plugin_ugs->$ug)) ? $plugin_ugs->$ug : 'user';
74    }
75
76    if (!$user = $auth->getUserData($json[SHAREDAPI_EVENT_FIELD_USERNAME]) and $create_user) {
77        if ($auth->createUser($json[SHAREDAPI_EVENT_FIELD_USERNAME], '', $json[SHAREDAPI_EVENT_FIELD_USERNAME],
78            $json[SHAREDAPI_EVENT_FIELD_EMAIL], array_unique($usergroups))) {
79            $user = $auth->getUserData($json[SHAREDAPI_EVENT_FIELD_USERNAME]);
80        }
81    }
82
83    return ($user and $user['mail'] == $json[SHAREDAPI_EVENT_FIELD_EMAIL]) ? $user : FALSE;
84}
85
86/**
87 * Listener register
88 *
89 * @param array $json array
90 *
91 * @return array
92 */
93function vbsso_listener_register($json) {
94    $u = vbsso_listener_user_load($json, TRUE);
95
96    if (is_array($u)) {
97        return array(SHAREDAPI_EVENT_FIELD_DATA => 'User ' . $json[SHAREDAPI_EVENT_FIELD_USERNAME]
98            . ' successfully created');
99    } else {
100        return array(SHAREDAPI_EVENT_FIELD_ERROR => $u);
101    }
102}
103
104/**
105 * Listener logout
106 *
107 * @return void
108 */
109function vbsso_listener_logout() {
110    auth_logoff(TRUE);
111}
112
113/**
114 * Listener auth
115 *
116 * @param array $json array
117 *
118 * @return void
119 */
120function vbsso_listener_authentication($json) {
121    if (vbsso_listener_user_load($json, TRUE)) {
122        $_SERVER['REMOTE_USER'] = $json[SHAREDAPI_EVENT_FIELD_USERNAME];
123        $secret = auth_cookiesalt(TRUE); //always sticky
124        vbsso_auth_setCookie($json[SHAREDAPI_EVENT_FIELD_USERNAME], PMA_blowfish_encrypt('', $secret),
125            $json[SHAREDAPI_EVENT_FIELD_REMEMBERME], $json[SHAREDAPI_EVENT_FIELD_TIMEOUT]);
126    }
127}
128
129/**
130 * Listener credentials
131 *
132 * @param array $json array
133 *
134 * @return array
135 */
136function vbsso_listener_credentials($json) {
137    global $vbsso_settings;
138    if ($u = vbsso_listener_user_load($json)) {
139        $update = FALSE;
140        $changes = array();
141
142        if (isset($json[SHAREDAPI_EVENT_FIELD_EMAIL2])) {
143            $changes['mail'] = $json[SHAREDAPI_EVENT_FIELD_EMAIL2];
144            $update = TRUE;
145        }
146
147        if (isset($json[SHAREDAPI_EVENT_FIELD_USERNAME2])) {
148            $changes['name'] = $json[SHAREDAPI_EVENT_FIELD_USERNAME2];
149            $update = TRUE;
150        }
151
152        if (isset($json[SHAREDAPI_EVENT_FIELD_USERGROUPS2])) {
153            $usergroups = array();
154            $plugin_ugs = json_decode($vbsso_settings[VBSSO_NAMED_EVENT_FIELD_USERGROUPS_ASSOC]);
155
156            foreach (explode(',', $json[SHAREDAPI_EVENT_FIELD_USERGROUPS2]) as $ug) {
157                $usergroups[] = (isset($plugin_ugs->$ug)) ? $plugin_ugs->$ug : 'user';
158            }
159            $changes['grps'] = array_unique($usergroups);
160            $update = TRUE;
161        }
162
163        if ($update) {
164            $auth = (class_exists('auth_plugin_authplain')) ? new auth_plugin_authplain() : new auth_plain();
165            $auth->modifyUser($json[SHAREDAPI_EVENT_FIELD_USERNAME], $changes);
166        }
167
168        return array(SHAREDAPI_EVENT_FIELD_DATA => 'User ' . $json[SHAREDAPI_EVENT_FIELD_USERNAME]
169            . ' successfully modified');
170    } else {
171        return array(SHAREDAPI_EVENT_FIELD_ERROR => vbsso_listener_report_error('Unable to update user login: '
172            . $json[SHAREDAPI_EVENT_FIELD_USERNAME]));
173    }
174}
175
176/**
177 * Generate password
178 *
179 * @return string
180 */
181function vbsso_generate_password() {
182    $password = "";
183    $possible = "1234567890abcdefghjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
184    for ($i = 0; $i < 20; $i++) {
185        $password .= substr($possible, mt_rand(0, strlen($possible) - 1), 1);
186    }
187
188    return $password;
189}
190
191/**
192 * Save platform settings
193 *
194 * @param mixed $settings settinhs
195 *
196 * @return void
197 */
198function vbsso_save_platform_settings($settings) {
199    file_put_contents(VBSSO_PLATFORM_CONFIG_FILE, base64_encode(serialize($settings)));
200}
201
202/**
203 * Get platform settings
204 *
205 * @return mixed
206 */
207function vbsso_get_platform_settings() {
208    if (!file_exists(VBSSO_PLATFORM_CONFIG_FILE)) {
209        file_put_contents(VBSSO_PLATFORM_CONFIG_FILE, '');
210    }
211
212    return unserialize(base64_decode(file_get_contents(VBSSO_PLATFORM_CONFIG_FILE)));
213}
214
215/**
216 * Get vB user groups
217 *
218 * @return array|mixed
219 */
220function vbsso_get_vb_usergroups() {
221    global $vbsso_platform_settings, $vbsso_settings;
222
223    $baa_username = sharedapi_decode_data($vbsso_settings[VBSSO_NAMED_EVENT_FIELD_API_KEY],
224        $vbsso_platform_settings[VBSSO_NAMED_EVENT_FIELD_BAA_USERNAME]);
225
226    $baa_password = sharedapi_decode_data($vbsso_settings[VBSSO_NAMED_EVENT_FIELD_API_KEY],
227        $vbsso_platform_settings[VBSSO_NAMED_EVENT_FIELD_BAA_PASSWORD]);
228
229    $vbug = sharedapi_post($vbsso_platform_settings[VBSSO_NAMED_EVENT_FIELD_USERGROUPS_URL], FALSE, $baa_username,
230        $baa_password);
231
232    return ($vbug['error_string']) ? $vbug : json_decode($vbug['response']);
233}
234
235/**
236 * Get alc groups
237 *
238 * @return array
239 */
240function vbsso_get_acl_groups() {
241    $groups = array();
242    foreach (auth_loadACL() as $a) {
243        // Don't parse comments
244        if (preg_match('/^#/', $a)) {
245            continue;
246        }
247        if (preg_match('/^[^\s]+\s@([^\s]+)/', $a, $matches)) {
248            $groups[urldecode($matches[1])] = $matches[1];
249        }
250    }
251
252    return $groups;
253}
254
255/**
256 * Set cookie
257 *
258 * @param object  $user            user
259 * @param string  $pass            password
260 * @param integer $sticky          glue
261 * @param integer $session_timeout timeout
262 *
263 * @return bool
264 */
265function vbsso_auth_setCookie($user, $pass, $sticky, $session_timeout) {
266    global $conf, $auth, $USERINFO;
267
268    if (!$auth) {
269        return FALSE;
270    }
271    $USERINFO = $auth->getUserData($user);
272
273    // set cookie
274    $cookie = base64_encode($user) . '|' . ((int)$sticky) . '|' . base64_encode($pass);
275    $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
276    $time = $sticky ? (time() + 60 * 60 * 24 * 365) : (time() + $session_timeout); //one year
277    if (version_compare(PHP_VERSION, '5.2.0', '>')) {
278        setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), TRUE);
279    } else {
280        setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()));
281    }
282    // set session
283    $_SESSION[DOKU_COOKIE]['auth']['user'] = $user;
284    $_SESSION[DOKU_COOKIE]['auth']['pass'] = sha1($pass);
285    $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid();
286    $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
287    //If an administrator was registered NOT by vBSSO,
288    //we don't know his pass, so he will logout every period, set in "auth_security_timeout".
289    //We will just increase this parameter
290    $_SESSION[DOKU_COOKIE]['auth']['time'] = time() + $time;
291
292    return TRUE;
293}
294
295/**
296 * Get Platform settings
297 *
298 * @return mixed
299 */
300function vbsso_get_dokuwiki_settings() {
301    if (!file_exists(VBSSO_VBSSO_CONFIG_FILE)) {
302        file_put_contents(VBSSO_VBSSO_CONFIG_FILE, '');
303    }
304
305    $settings = unserialize(base64_decode(file_get_contents(VBSSO_VBSSO_CONFIG_FILE)));
306
307    if (!isset($settings[VBSSO_NAMED_EVENT_FIELD_LOGIN_THROUGH_VB_PAGE])) {
308        $settings[VBSSO_NAMED_EVENT_FIELD_LOGIN_THROUGH_VB_PAGE] = TRUE;
309    }
310
311    if (!isset($settings[VBSSO_PLATFORM_FOOTER_LINK_PROPERTY])) {
312        $settings[VBSSO_PLATFORM_FOOTER_LINK_PROPERTY] = VBSSO_PLATFORM_FOOTER_LINK_SHOW_EVERYWHERE;
313    }
314    if (!isset($settings[VBSSO_NAMED_EVENT_FIELD_API_KEY])) {
315        $settings[VBSSO_NAMED_EVENT_FIELD_API_KEY] = SHAREDAPI_DEFAULT_API_KEY;
316    }
317
318    if (!isset($settings[VBSSO_NAMED_EVENT_FIELD_USERGROUPS_ASSOC])) {
319        $settings[VBSSO_NAMED_EVENT_FIELD_USERGROUPS_ASSOC] = FALSE;
320    }
321
322    return $settings;
323}
324
325/**
326 * Save platform settings
327 *
328 * @return void
329 */
330function vbsso_save_mediawiki_settings() {
331    global $vbsso_settings, $vbsso_platform_settings;
332
333    $settings = array();
334    $settings[VBSSO_PLATFORM_FOOTER_LINK_PROPERTY] =
335        (isset($_POST[VBSSO_PLATFORM_FOOTER_LINK_PROPERTY])) ? $_POST[VBSSO_PLATFORM_FOOTER_LINK_PROPERTY] : '1';
336    $settings[VBSSO_NAMED_EVENT_FIELD_API_KEY] =
337        (isset($_POST[VBSSO_NAMED_EVENT_FIELD_API_KEY]) && !empty($_POST[VBSSO_NAMED_EVENT_FIELD_API_KEY]))
338            ? $_POST[VBSSO_NAMED_EVENT_FIELD_API_KEY] : SHAREDAPI_DEFAULT_API_KEY;
339    $settings[VBSSO_NAMED_EVENT_FIELD_LOGIN_THROUGH_VB_PAGE] =
340        (isset($_POST[VBSSO_NAMED_EVENT_FIELD_LOGIN_THROUGH_VB_PAGE]))
341            ? $_POST[VBSSO_NAMED_EVENT_FIELD_LOGIN_THROUGH_VB_PAGE] : '0';
342
343    if ($vbsso_platform_settings[VBSSO_NAMED_EVENT_FIELD_USERGROUPS_URL]) {
344        $vb_usergroups = vbsso_get_vb_usergroups();
345        $vbsso_usergroups_assoc = array();
346
347        foreach ($vb_usergroups as $vb_usergroup) {
348            $vbsso_usergroups_assoc[$vb_usergroup->usergroupid] =
349                $_POST[VBSSO_NAMED_EVENT_FIELD_USERGROUPS_ASSOC . '_' . $vb_usergroup->usergroupid];
350        }
351
352        $settings[VBSSO_NAMED_EVENT_FIELD_USERGROUPS_ASSOC] = json_encode($vbsso_usergroups_assoc);
353    }
354
355    file_put_contents(VBSSO_VBSSO_CONFIG_FILE, base64_encode(serialize($settings)));
356    $vbsso_settings = $settings;
357}
358