Subversion Repositories oidplus

Rev

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