Subversion Repositories oidplus

Rev

Rev 496 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
104 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
511 daniel-mar 5
 * Copyright 2019 - 2021 Daniel Marschall, ViaThinkSoft
104 daniel-mar 6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
511 daniel-mar 20
if (!defined('INSIDE_OIDPLUS')) die();
21
 
256 daniel-mar 22
class OIDplusPagePublicLogin extends OIDplusPagePluginPublic {
104 daniel-mar 23
 
321 daniel-mar 24
        public function action($actionID, $params) {
104 daniel-mar 25
                // === RA LOGIN/LOGOUT ===
26
 
321 daniel-mar 27
                if ($actionID == 'ra_login') {
261 daniel-mar 28
                        if (OIDplus::baseConfig()->getValue('RECAPTCHA_ENABLED', false)) {
29
                                $secret=OIDplus::baseConfig()->getValue('RECAPTCHA_PRIVATE', '');
321 daniel-mar 30
                                $response=$params["captcha"];
104 daniel-mar 31
                                $verify=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret={$secret}&response={$response}");
32
                                $captcha_success=json_decode($verify);
33
                                if ($captcha_success->success==false) {
360 daniel-mar 34
                                        throw new OIDplusException(_L('CAPTCHA not successfully verified'));
104 daniel-mar 35
                                }
36
                        }
37
 
430 daniel-mar 38
                        $email = $params['email'];
39
                        $ra = new OIDplusRA($email);
40
 
41
                        if (empty($email)) {
42
                                throw new OIDplusException(_L('Please enter a valid email address'));
43
                        }
44
 
321 daniel-mar 45
                        if ($ra->checkPassword($params['password'])) {
288 daniel-mar 46
                                OIDplus::logger()->log("[OK]RA($email)!", "RA '$email' logged in");
119 daniel-mar 47
                                OIDplus::authUtils()::raLogin($email);
104 daniel-mar 48
 
264 daniel-mar 49
                                OIDplus::db()->query("UPDATE ###ra set last_login = ".OIDplus::db()->sqlDate()." where email = ?", array($email));
104 daniel-mar 50
 
328 daniel-mar 51
                                return array("status" => 0);
104 daniel-mar 52
                        } else {
300 daniel-mar 53
                                if (OIDplus::config()->getValue('log_failed_ra_logins', false)) {
298 daniel-mar 54
                                        if ($ra->existing()) {
55
                                                OIDplus::logger()->log("[WARN]A!", "Failed login to RA account '$email' (wrong password)");
56
                                        } else {
57
                                                OIDplus::logger()->log("[WARN]A!", "Failed login to RA account '$email' (RA not existing)");
58
                                        }
295 daniel-mar 59
                                }
355 daniel-mar 60
                                throw new OIDplusException(_L('Wrong password or user not registered'));
104 daniel-mar 61
                        }
150 daniel-mar 62
 
321 daniel-mar 63
                } else if ($actionID == 'ra_logout') {
119 daniel-mar 64
 
321 daniel-mar 65
                        $email = $params['email'];
66
 
288 daniel-mar 67
                        OIDplus::logger()->log("[OK]RA($email)!", "RA '$email' logged out");
119 daniel-mar 68
                        OIDplus::authUtils()::raLogout($email);
328 daniel-mar 69
                        return array("status" => 0);
104 daniel-mar 70
                }
71
 
72
                // === ADMIN LOGIN/LOGOUT ===
73
 
321 daniel-mar 74
                else if ($actionID == 'admin_login') {
261 daniel-mar 75
                        if (OIDplus::baseConfig()->getValue('RECAPTCHA_ENABLED', false)) {
76
                                $secret=OIDplus::baseConfig()->getValue('RECAPTCHA_PRIVATE', '');
321 daniel-mar 77
                                $response=$params["captcha"];
104 daniel-mar 78
                                $verify=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret={$secret}&response={$response}");
79
                                $captcha_success=json_decode($verify);
80
                                if ($captcha_success->success==false) {
360 daniel-mar 81
                                        throw new OIDplusException(_L('CAPTCHA not successfully verified'));
104 daniel-mar 82
                                }
83
                        }
84
 
321 daniel-mar 85
                        if (OIDplus::authUtils()::adminCheckPassword($params['password'])) {
288 daniel-mar 86
                                OIDplus::logger()->log("[OK]A!", "Admin logged in");
104 daniel-mar 87
                                OIDplus::authUtils()::adminLogin();
328 daniel-mar 88
                                return array("status" => 0);
104 daniel-mar 89
                        } else {
300 daniel-mar 90
                                if (OIDplus::config()->getValue('log_failed_admin_logins', false)) {
298 daniel-mar 91
                                        OIDplus::logger()->log("[WARN]A!", "Failed login to admin account");
92
                                }
360 daniel-mar 93
                                throw new OIDplusException(_L('Wrong password'));
104 daniel-mar 94
                        }
95
                }
321 daniel-mar 96
                else if ($actionID == 'admin_logout') {
288 daniel-mar 97
                        OIDplus::logger()->log("[OK]A!", "Admin logged out");
104 daniel-mar 98
                        OIDplus::authUtils()::adminLogout();
328 daniel-mar 99
                        return array("status" => 0);
104 daniel-mar 100
                }
321 daniel-mar 101
                else {
360 daniel-mar 102
                        throw new OIDplusException(_L('Unknown action ID'));
321 daniel-mar 103
                }
104 daniel-mar 104
        }
105
 
106
        public function init($html=true) {
295 daniel-mar 107
                OIDplus::config()->prepareConfigKey('log_failed_ra_logins', 'Log failed RA logins', '0', OIDplusConfig::PROTECTION_EDITABLE, function($value) {
108
                        if (!is_numeric($value) || (($value != 0) && (($value != 1)))) {
360 daniel-mar 109
                                throw new OIDplusException(_L('Valid values: 0 (off) or 1 (on).'));
295 daniel-mar 110
                        }
111
                });
112
                OIDplus::config()->prepareConfigKey('log_failed_admin_logins', 'Log failed Admin logins', '0', OIDplusConfig::PROTECTION_EDITABLE, function($value) {
113
                        if (!is_numeric($value) || (($value != 0) && (($value != 1)))) {
360 daniel-mar 114
                                throw new OIDplusException(_L('Valid values: 0 (off) or 1 (on).'));
295 daniel-mar 115
                        }
116
                });
104 daniel-mar 117
        }
118
 
119
        public function gui($id, &$out, &$handled) {
382 daniel-mar 120
                $ary = explode('$', $id);
121
                if (isset($ary[1])) {
122
                        $id = $ary[0];
123
                        $tab = $ary[1];
124
                } else {
125
                        $tab = 'ra';
126
                }
104 daniel-mar 127
                if ($id === 'oidplus:login') {
128
                        $handled = true;
360 daniel-mar 129
                        $out['title'] = _L('Login');
241 daniel-mar 130
                        $out['icon']  = OIDplus::webpath(__DIR__).'login_big.png';
104 daniel-mar 131
 
431 daniel-mar 132
                        $out['text'] = '';
133
 
104 daniel-mar 134
                        $out['text'] .= '<noscript>';
355 daniel-mar 135
                        $out['text'] .= '<p>'._L('You need to enable JavaScript to use the login area.').'</p>';
104 daniel-mar 136
                        $out['text'] .= '</noscript>';
137
 
219 daniel-mar 138
                        $out['text'] .= '<div id="loginArea" style="visibility: hidden"><div id="loginTab" class="container" style="width:100%;">';
261 daniel-mar 139
                        $out['text'] .= (OIDplus::baseConfig()->getValue('RECAPTCHA_ENABLED', false) ?
140
                                        '<script> grecaptcha.render(document.getElementById("g-recaptcha"), { "sitekey" : "'.OIDplus::baseConfig()->getValue('RECAPTCHA_PUBLIC', '').'" }); </script>'.
360 daniel-mar 141
                                        '<p>'._L('Before logging in, please solve the following CAPTCHA').'</p>'.
142
                                        '<div id="g-recaptcha" class="g-recaptcha" data-sitekey="'.OIDplus::baseConfig()->getValue('RECAPTCHA_PUBLIC', '').'"></div>' : '');
104 daniel-mar 143
                        $out['text'] .= '<br>';
144
 
420 daniel-mar 145
                        // ---------------- Tab control
146
                        $out['text'] .= OIDplus::gui()->tabBarStart();
147
                        $out['text'] .= OIDplus::gui()->tabBarElement('ra',    _L('Login as RA'),            $tab === 'ra');
148
                        $out['text'] .= OIDplus::gui()->tabBarElement('admin', _L('Login as administrator'), $tab === 'admin');
149
                        $out['text'] .= OIDplus::gui()->tabBarEnd();
150
                        $out['text'] .= OIDplus::gui()->tabContentStart();
151
                        // ---------------- "RA" tab
152
                        $tabcont = '<h2>'._L('Login as RA').'</h2>';
104 daniel-mar 153
                        $login_list = OIDplus::authUtils()->loggedInRaList();
154
                        if (count($login_list) > 0) {
115 daniel-mar 155
                                foreach ($login_list as $x) {
420 daniel-mar 156
                                        $tabcont .= '<p>'._L('You are logged in as %1','<b>'.$x->raEmail().'</b>').' (<a href="#" onclick="return raLogout('.js_escape($x->raEmail()).');">'._L('Logout').'</a>)</p>';
104 daniel-mar 157
                                }
420 daniel-mar 158
                                $tabcont .= '<p>'._L('If you have more accounts, you can log in with another account here.').'</p>';
104 daniel-mar 159
                        } else {
420 daniel-mar 160
                                $tabcont .= '<p>'._L('Enter your email address and your password to log in as Registration Authority.').'</p>';
104 daniel-mar 161
                        }
428 daniel-mar 162
                        $tabcont .= '<form action="javascript:void(0);" onsubmit="return raLoginOnSubmit(this);">';
420 daniel-mar 163
                        $tabcont .= '<div><label class="padding_label">'._L('E-Mail').':</label><input type="text" name="email" value="" id="raLoginEMail"></div>';
164
                        $tabcont .= '<div><label class="padding_label">'._L('Password').':</label><input type="password" name="password" value="" id="raLoginPassword"></div>';
165
                        $tabcont .= '<br><input type="submit" value="'._L('Login').'"><br><br>';
166
                        $tabcont .= '</form>';
167
                        $tabcont .= '<p><a '.OIDplus::gui()->link('oidplus:forgot_password').'>'._L('Forgot password?').'</a><br>';
104 daniel-mar 168
 
380 daniel-mar 169
                        $invitePlugin = OIDplus::getPluginByOid('1.3.6.1.4.1.37476.2.5.2.4.2.92'); // OIDplusPageRaInvite
170
                        if (!is_null($invitePlugin) && OIDplus::config()->getValue('ra_invitation_enabled')) {
420 daniel-mar 171
                                $tabcont .= '<abbr title="'._L('To receive login data, the superior RA needs to send you an invitation. After creating or updating your OID, the system will ask them if they want to send you an invitation. If they accept, you will receive an email with an activation link. Alternatively, the system admin can create your account manually in the administrator control panel.').'">'._L('How to register?').'</abbr></p>';
156 daniel-mar 172
                        } else {
420 daniel-mar 173
                                $tabcont .= '<abbr title="'._L('Since invitations are disabled at this OIDplus system, the system administrator needs to create your account manually in the administrator control panel.').'">'._L('How to register?').'</abbr></p>';
156 daniel-mar 174
                        }
430 daniel-mar 175
 
431 daniel-mar 176
                        if ($tab === 'ra') {
177
                                $alt_logins_html = array();
178
                                foreach (OIDplus::getPagePlugins() as $plugin) {
179
                                        if ($plugin->implementsFeature('1.3.6.1.4.1.37476.2.5.2.3.5')) {
180
                                                $logins = $plugin->alternativeLoginMethods();
181
                                                foreach ($logins as $data) {
182
                                                        if (isset($data[2]) && !empty($data[2])) {
183
                                                                $img = '<img src="'.$data[2].'" alt="'.htmlentities($data[1]).'"> ';
184
                                                        } else {
185
                                                                $img = '';
186
                                                        }
187
                                                        $alt_logins_html[] = $img.'<a '.OIDplus::gui()->link($data[0]).'>'.htmlentities($data[1]).'</a>';
430 daniel-mar 188
                                                }
189
                                        }
190
                                }
431 daniel-mar 191
                                if (count($alt_logins_html) > 0) {
192
                                        $tabcont .= '<p>'._L('Alternative login methods').':<br>';
193
                                        foreach ($alt_logins_html as $alt_login) {
194
                                                $tabcont .= $alt_login.'<br>';
195
                                        }
196
                                        $tabcont .= '</p>';
430 daniel-mar 197
                                }
198
                        }
199
 
431 daniel-mar 200
                        $out['text'] .= OIDplus::gui()->tabContentPage('ra', $tabcont, $tab === 'ra');
420 daniel-mar 201
                        // ---------------- "Administrator" tab
202
                        $tabcont = '<h2>'._L('Login as administrator').'</h2>';
104 daniel-mar 203
                        if (OIDplus::authUtils()::isAdminLoggedIn()) {
420 daniel-mar 204
                                $tabcont .= '<p>'._L('You are logged in as administrator.').'</p>';
205
                                $tabcont .= '<a href="#" onclick="return adminLogout();">'._L('Logout').'</a>';
104 daniel-mar 206
                        } else {
428 daniel-mar 207
                                $tabcont .= '<form action="javascript:void(0);" onsubmit="return adminLoginOnSubmit(this);">';
420 daniel-mar 208
                                $tabcont .= '<div><label class="padding_label">'._L('Password').':</label><input type="password" name="password" value="" id="adminLoginPassword"></div>';
209
                                $tabcont .= '<br><input type="submit" value="'._L('Login').'"><br><br>';
210
                                $tabcont .= '</form>';
211
                                $tabcont .= '<p><a '.OIDplus::gui()->link('oidplus:forgot_password_admin').'>'._L('Forgot password?').'</a><br>';
104 daniel-mar 212
                        }
420 daniel-mar 213
                        $out['text'] .= OIDplus::gui()->tabContentPage('admin', $tabcont, $tab === 'admin');
214
                        $out['text'] .= OIDplus::gui()->tabContentEnd();
215
                        // ---------------- Tab control END
104 daniel-mar 216
 
420 daniel-mar 217
                        $out['text'] .= '</div><br>';
218
 
360 daniel-mar 219
                        $mins = ceil(OIDplus::baseConfig()->getValue('SESSION_LIFETIME', 30*60)/60);
220
                        $out['text'] .= '<p><font size="-1">'._L('<i>Privacy information</i>: By using the login functionality, you are accepting that a "session cookie" is temporarily stored in your browser. The session cookie is a small text file that is sent to this website every time you visit it, to identify you as an already logged in user. It does not track any of your online activities outside OIDplus. The cookie will be destroyed when you log out or after an inactivity of %1 minutes.', $mins);
296 daniel-mar 221
                        $privacy_document_file = 'OIDplus/privacy_documentation.html';
380 daniel-mar 222
                        $resourcePlugin = OIDplus::getPluginByOid('1.3.6.1.4.1.37476.2.5.2.4.1.500'); // OIDplusPagePublicResources
496 daniel-mar 223
                        if (!is_null($resourcePlugin) && file_exists(OIDplus::localpath().'res/'.$privacy_document_file)) {
470 daniel-mar 224
                                $out['text'] .= ' <a '.OIDplus::gui()->link('oidplus:resources$'.$privacy_document_file.'#cookies').'>'._L('More information about the cookies used').'</a>';
219 daniel-mar 225
                        }
226
                        $out['text'] .= '</font></p></div>';
107 daniel-mar 227
 
228
                        $out['text'] .= '<script>document.getElementById("loginArea").style.visibility = "visible";</script>';
104 daniel-mar 229
                }
230
        }
295 daniel-mar 231
 
282 daniel-mar 232
        public function publicSitemap(&$out) {
360 daniel-mar 233
                $out[] = 'oidplus:login';
282 daniel-mar 234
        }
104 daniel-mar 235
 
106 daniel-mar 236
        public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') {
104 daniel-mar 237
                $loginChildren = array();
238
 
239
                if (OIDplus::authUtils()::isAdminLoggedIn()) {
240
                        $ra_roots = array();
241
 
281 daniel-mar 242
                        foreach (OIDplus::getPagePlugins() as $plugin) {
243
                                if (is_subclass_of($plugin, OIDplusPagePluginAdmin::class)) {
244
                                        $plugin->tree($ra_roots);
245
                                }
104 daniel-mar 246
                        }
247
 
248
                        $ra_roots[] = array(
249
                                'id'       => 'oidplus:logout$admin',
241 daniel-mar 250
                                'icon'     => OIDplus::webpath(__DIR__).'treeicon_logout.png',
225 daniel-mar 251
                                'conditionalselect' => 'adminLogout()', // defined in oidplus_base.js
355 daniel-mar 252
                                'text'     => _L('Log out')
104 daniel-mar 253
                        );
254
                        $loginChildren[] = array(
255
                                'id'       => 'oidplus:dummy$'.md5(rand()),
355 daniel-mar 256
                                'text'     => _L("Logged in as admin"),
241 daniel-mar 257
                                'icon'     => OIDplus::webpath(__DIR__).'treeicon_admin.png',
104 daniel-mar 258
                                'conditionalselect' => 'false', // dummy node that can't be selected
259
                                'state'    => array("opened" => true),
260
                                'children' => $ra_roots
261
                        );
262
                }
263
 
115 daniel-mar 264
                foreach (OIDplus::authUtils()::loggedInRaList() as $ra) {
265
                        $ra_email = $ra->raEmail();
104 daniel-mar 266
                        $ra_roots = array();
267
 
281 daniel-mar 268
                        foreach (OIDplus::getPagePlugins() as $plugin) {
269
                                if (is_subclass_of($plugin, OIDplusPagePluginRa::class)) {
270
                                        $plugin->tree($ra_roots, $ra_email);
271
                                }
104 daniel-mar 272
                        }
273
 
274
                        $ra_roots[] = array(
275
                                'id'       => 'oidplus:logout$'.$ra_email,
225 daniel-mar 276
                                'conditionalselect' => 'raLogout('.js_escape($ra_email).')', // defined in oidplus_base.js
241 daniel-mar 277
                                'icon'     => OIDplus::webpath(__DIR__).'treeicon_logout.png',
355 daniel-mar 278
                                'text'     => _L('Log out')
104 daniel-mar 279
                        );
280
                        foreach (OIDplusObject::getRaRoots($ra_email) as $loc_root) {
281
                                $ico = $loc_root->getIcon();
282
                                $ra_roots[] = array(
283
                                        'id' => 'oidplus:raroot$'.$loc_root->nodeId(),
360 daniel-mar 284
                                        'text' => _L('Jump to RA root %1',$loc_root->objectTypeTitleShort().' '.$loc_root->crudShowId(OIDplusObject::parse($loc_root::root()))),
110 daniel-mar 285
                                        'conditionalselect' => 'openOidInPanel('.js_escape($loc_root->nodeId()).', true);',
241 daniel-mar 286
                                        'icon' => !is_null($ico) ? $ico : OIDplus::webpath(__DIR__).'treeicon_link.png'
104 daniel-mar 287
                                );
288
                        }
289
                        $ra_email_or_name = (new OIDplusRA($ra_email))->raName();
290
                        if ($ra_email_or_name == '') $ra_email_or_name = $ra_email;
291
                        $loginChildren[] = array(
292
                                'id'       => 'oidplus:dummy$'.md5(rand()),
360 daniel-mar 293
                                'text'     => _L('Logged in as %1',htmlentities($ra_email_or_name)),
241 daniel-mar 294
                                'icon'     => OIDplus::webpath(__DIR__).'treeicon_ra.png',
104 daniel-mar 295
                                'conditionalselect' => 'false', // dummy node that can't be selected
296
                                'state'    => array("opened" => true),
297
                                'children' => $ra_roots
298
                        );
299
                }
300
 
301
                $json[] = array(
302
                        'id'       => 'oidplus:login',
241 daniel-mar 303
                        'icon'     => OIDplus::webpath(__DIR__).'treeicon_login.png',
355 daniel-mar 304
                        'text'     => _L('Login'),
104 daniel-mar 305
                        'state'    => array("opened" => count($loginChildren)>0),
306
                        'children' => $loginChildren
307
                );
308
 
309
                return true;
310
        }
108 daniel-mar 311
 
312
        public function tree_search($request) {
313
                return false;
314
        }
382 daniel-mar 315
}