Subversion Repositories oidplus

Rev

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

Rev Author Line No. Line
329 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
511 daniel-mar 5
 * Copyright 2019 - 2021 Daniel Marschall, ViaThinkSoft
329 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
 
20
// ATTENTION: If you change something, please make sure that the changes
21
//            are synchronous with OIDplusPageAdminAutomatedAJAXCalls
22
 
511 daniel-mar 23
if (!defined('INSIDE_OIDPLUS')) die();
24
 
329 daniel-mar 25
class OIDplusPageRaAutomatedAJAXCalls extends OIDplusPagePluginRa {
26
 
27
        private static function getUnlockKey($user) {
28
                // This key prevents that the system gets hacked with brute
29
                // force of the user passwords.
392 daniel-mar 30
                return sha3_512('ANTI-BRUTEFORCE-AJAX/'.$user.'/'.OIDplus::baseConfig()->getValue('SERVER_SECRET',''));
329 daniel-mar 31
        }
32
 
33
        private $autoLoginList = array();
34
 
424 daniel-mar 35
        // Attention: Needs to be public, because otherwise register_shutdown_function() won't work
36
        public function shutdownLogout() {
329 daniel-mar 37
                foreach ($this->autoLoginList as $username) {
549 daniel-mar 38
                        OIDplus::authUtils()->raLogout($username);
329 daniel-mar 39
                }
40
        }
41
 
42
        public function init($html=true) {
43
                if (isset($_SERVER['SCRIPT_FILENAME']) && (basename($_SERVER['SCRIPT_FILENAME']) == 'ajax.php')) {
44
                        $input = array_merge($_POST,$_GET);
45
 
566 daniel-mar 46
                        if (isset($input['OIDPLUS_AUTH_JWT'])) {
47
 
426 daniel-mar 48
                                originHeaders(); // Allows queries from other domains
49
                                OIDplus::authUtils()->disableCSRF(); // allow access to ajax.php without valid CSRF token
329 daniel-mar 50
 
566 daniel-mar 51
                                // Nothing else to do. The OIDplusAuthUtils->getAuthContentStore() will automatically care if OIDPLUS_AUTH_JWT exists!
52
 
53
                        } else if (isset($input['batch_ajax_unlock_key']) && isset($input['batch_login_username']) && isset($input['batch_login_password'])) {
54
 
55
                                // batch_* fields are for backwards compatibility!
56
 
57
                                originHeaders(); // Allows queries from other domains
58
                                OIDplus::authUtils()->disableCSRF(); // allow access to ajax.php without valid CSRF token
59
 
426 daniel-mar 60
                                if ($input['batch_login_username'] != 'admin') {
61
                                        if ($input['batch_ajax_unlock_key'] != self::getUnlockKey($input['batch_login_username'])) {
62
                                                throw new OIDplusException(_L('Invalid AJAX unlock key'));
63
                                        }
424 daniel-mar 64
 
549 daniel-mar 65
                                        if (OIDplus::authUtils()->raCheckPassword($input['batch_login_username'], $input['batch_login_password'])) {
566 daniel-mar 66
                                                // OIDplusAuthUtils->getAuthContentStore() will use a OIDplusAuthContentStoreDummy instead of a OIDplusAuthContentStoreSession
67
                                                // if the argument "batch_ajax_unlock_key" exists. Therefore, the user session will be ignored and not modified.
549 daniel-mar 68
                                                OIDplus::authUtils()->raLogin($input['batch_login_username']);
426 daniel-mar 69
                                                $this->autoLoginList[] = $input['batch_login_username'];
70
                                                register_shutdown_function(array($this,'shutdownLogout'));
71
                                        } else {
72
                                                throw new OIDplusException(_L('Wrong RA username or password'));
73
                                        }
74
                                }
329 daniel-mar 75
                        }
76
                }
77
        }
78
 
79
        public function gui($id, &$out, &$handled) {
80
                if (explode('$',$id)[0] == 'oidplus:automated_ajax_information_ra') {
81
                        $handled = true;
82
 
83
                        $ra_email = explode('$',$id)[1];
84
 
360 daniel-mar 85
                        $out['title'] = _L('Automated AJAX calls');
329 daniel-mar 86
                        $out['icon'] = file_exists(__DIR__.'/icon_big.png') ? OIDplus::webpath(__DIR__).'icon_big.png' : '';
87
 
549 daniel-mar 88
                        if (!OIDplus::authUtils()->isRaLoggedIn($ra_email) && !OIDplus::authUtils()->isAdminLoggedIn()) {
329 daniel-mar 89
                                $out['icon'] = 'img/error_big.png';
559 daniel-mar 90
                                $out['text'] = '<p>'._L('You need to <a %1>log in</a> as the requested RA %2 or as admin.',OIDplus::gui()->link('oidplus:login$ra$'.$ra_email),'<b>'.htmlentities($ra_email).'</b>').'</p>';
329 daniel-mar 91
                                return;
92
                        }
93
 
566 daniel-mar 94
                        $authSimulation = new OIDplusAuthContentStoreJWT();
95
                        $authSimulation->raLogin($ra_email);
96
 
360 daniel-mar 97
                        $out['text'] .= '<p>'._L('You can make automated calls to your OIDplus account by calling the AJAX API.').'</p>';
98
                        $out['text'] .= '<p>'._L('The URL for the AJAX script is:').':</p>';
496 daniel-mar 99
                        $out['text'] .= '<p><b>'.OIDplus::webpath(null,false).'ajax.php</b></p>';
360 daniel-mar 100
                        $out['text'] .= '<p>'._L('You must at least provide following fields').':</p>';
329 daniel-mar 101
                        $out['text'] .= '<p><pre>';
566 daniel-mar 102
                        $out['text'] .= 'OIDPLUS_AUTH_JWT = "'.$authSimulation->GetJWTToken().'"'."\n";
329 daniel-mar 103
                        $out['text'] .= '</pre></p>';
360 daniel-mar 104
                        $out['text'] .= '<p>'._L('Please keep this information confidential!').'</p>';
566 daniel-mar 105
                        $out['text'] .= '<p>'._L('The JWT-token (secret!) will automatically perform a one-time-login to fulfill the request. The other fields are the normal fields which are called during the usual operation of OIDplus.').'</p>';
360 daniel-mar 106
                        $out['text'] .= '<p>'._L('Currently, there is no documentation for the AJAX calls. However, you can look at the <b>script.js</b> files of the plugins to see the field names being used. You can also enable network analysis in your web browser debugger (F12) to see the request headers sent to the server during the operation of OIDplus.').'</p>';
425 daniel-mar 107
 
360 daniel-mar 108
                        $out['text'] .= '<h2>'._L('Example for adding OID 2.999.123 using JavaScript').'</h2>';
424 daniel-mar 109
                        $cont = file_get_contents(__DIR__.'/examples/example_js.html');
496 daniel-mar 110
                        $cont = str_replace('<url>', OIDplus::webpath(null,false).'ajax.php', $cont);
424 daniel-mar 111
                        $cont = str_replace('<username>', $ra_email, $cont);
112
                        $cont = str_replace('<password>', '.........', $cont);
425 daniel-mar 113
                        $cont = str_replace('<unlock key>', $this->getUnlockKey($ra_email), $cont);
424 daniel-mar 114
                        $out['text'] .= '<pre>'.htmlentities($cont).'</pre>';
425 daniel-mar 115
 
360 daniel-mar 116
                        $out['text'] .= '<h2>'._L('Example for adding OID 2.999.123 using PHP (located at a foreign server)').'</h2>';
424 daniel-mar 117
                        $cont = file_get_contents(__DIR__.'/examples/example_php.phps');
496 daniel-mar 118
                        $cont = str_replace('<url>', OIDplus::webpath(null,false).'ajax.php', $cont);
424 daniel-mar 119
                        $cont = str_replace('<username>', $ra_email, $cont);
120
                        $cont = str_replace('<password>', '.........', $cont);
425 daniel-mar 121
                        $cont = str_replace('<unlock key>', $this->getUnlockKey($ra_email), $cont);
424 daniel-mar 122
                        $out['text'] .= '<pre>'.preg_replace("@<br.*>@ismU","",highlight_string($cont,true)).'</pre>';
123
 
425 daniel-mar 124
                        $out['text'] .= '<h2>'._L('Example for adding OID 2.999.123 using VBScript').'</h2>';
125
                        $cont = file_get_contents(__DIR__.'/examples/example_vbs.vbs');
496 daniel-mar 126
                        $cont = str_replace('<url>', OIDplus::webpath(null,false).'ajax.php', $cont);
425 daniel-mar 127
                        $cont = str_replace('<username>', $ra_email, $cont);
128
                        $cont = str_replace('<password>', '.........', $cont);
129
                        $cont = str_replace('<unlock key>', $this->getUnlockKey($ra_email), $cont);
130
                        $out['text'] .= '<pre>'.htmlentities($cont).'</pre>';
329 daniel-mar 131
                }
132
        }
133
 
134
        public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') {
135
                if (!$ra_email) return false;
549 daniel-mar 136
                if (!OIDplus::authUtils()->isRaLoggedIn($ra_email) && !OIDplus::authUtils()->isAdminLoggedIn()) return false;
329 daniel-mar 137
 
138
                if (file_exists(__DIR__.'/treeicon.png')) {
139
                        $tree_icon = OIDplus::webpath(__DIR__).'treeicon.png';
140
                } else {
141
                        $tree_icon = null; // default icon (folder)
142
                }
143
 
144
                $json[] = array(
145
                        'id' => 'oidplus:automated_ajax_information_ra$'.$ra_email,
146
                        'icon' => $tree_icon,
360 daniel-mar 147
                        'text' => _L('Automated AJAX calls')
329 daniel-mar 148
                );
149
 
150
                return true;
151
        }
152
 
153
        public function tree_search($request) {
154
                return false;
155
        }
426 daniel-mar 156
}