Subversion Repositories oidplus

Rev

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

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