-
Notifications
You must be signed in to change notification settings - Fork 97
/
json.php
151 lines (136 loc) · 5.13 KB
/
json.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<?php
/**
* EGroupware - general JSON handler for EGroupware
*
* @link http://www.egroupware.org
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage ajax
* @author Andreas Stoeckel <[email protected]>
*/
use EGroupware\Api;
use EGroupware\Api\Egw;
use EGroupware\Api\Json;
/**
* callback if the session-check fails, redirects to login.php, if no valid basic auth credentials given
*
* @param array &$anon_account anon account_info with keys 'login', 'passwd' and optional 'passwd_type'
* @return boolean|string true if we allow anon access and anon_account is set, a sessionid or false otherwise
*/
function login_redirect(&$anon_account)
{
// allow to make json calls via basic auth
if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW']) &&
($session_id = Api\Header\Authenticate::autocreate_session_callback($anon_account)))
{
return $session_id;
}
Json\Request::isJSONRequest(true); // because Api\Json\Request::parseRequest() is not (yet) called
$response = Json\Response::get();
$response->apply('framework.callOnLogout');
$response->redirect($GLOBALS['egw_info']['server']['webserver_url'].'/login.php?cd=10', true);
// under PHP 8 the destructor is called to late and the response is not send
$GLOBALS['egw']->__destruct();
exit();
}
/**
* Exception handler for xajax, return the message (and trace, if enabled) as alert() to the user
*
* Does NOT return!
*
* @param Exception|Error $e
*/
function ajax_exception_handler($e)
{
// handle redirects without logging
if (is_a($e, 'EGroupware\\Api\\Exception\\Redirect'))
{
Egw::redirect($e->url, $e->app);
}
// logging all exceptions to the error_log
$message = null;
if (function_exists('_egw_log_exception'))
{
_egw_log_exception($e,$message);
}
$response = Json\Response::get();
$message .= ($message ? "\n\n" : '').$e->getMessage();
$message .= "\n\n".$e->getFile().' ('.$e->getLine().')';
// only show trace (incl. function arguments) if explicitly enabled, eg. on a development system
if ($GLOBALS['egw_info']['server']['exception_show_trace'])
{
$message .= "\n\n".$e->getTraceAsString();
}
$response->message($message, 'error');
// under PHP 8 the destructor is called to late and the response is not send
$GLOBALS['egw']->__destruct();
exit;
}
// set our own exception handler, to not get the html from eGW's default one
set_exception_handler('ajax_exception_handler');
try {
if (!isset($_GET['menuaction']))
{
throw new InvalidArgumentException('Missing menuaction GET parameter', 998);
}
if (strpos($_GET['menuaction'],'::') !== false && strpos($_GET['menuaction'],'.') === false) // static method name app_something::method
{
@list($className,$functionName,$handler) = explode('::',$_GET['menuaction'])+[2 => null];
if (substr($className, 0, 11) == 'EGroupware\\')
{
list(,$appName) = explode('\\', strtolower($className));
}
else
{
list($appName) = explode('_',$className);
}
}
else
{
@list($appName, $className, $functionName, $handler) = explode('.',$_GET['menuaction']);
}
//error_log("json.php: appName=$appName, className=$className, functionName=$functionName, handler=$handler");
$GLOBALS['egw_info'] = array(
'flags' => array(
'currentapp' => $appName,
'noheader' => True,
'disable_Template_class' => True,
'autocreate_session_callback' => 'login_redirect',
'no_exception_handler' => true, // we already installed our own
// only log ajax requests which represent former GET requests or submits
// cuts down updates to egw_access_log table
'no_dla_update' => !preg_match('/(Etemplate::ajax_process_content|\.jdots_framework\.ajax_exec\.template)/', $_GET['menuaction']),
)
);
include_once('./header.inc.php');
//Create a new json handler
$json = new Json\Request();
//Check whether the request data is set
if (isset($GLOBALS['egw_unset_vars']['_POST[json_data]']))
{
$json->isJSONRequest(true); // otherwise exception is not send back to client, as we have not yet called parseRequest()
throw new Json\Exception\ScriptTags("JSON Data contains script tags. Aborting...");
}
// check if we have a real json request
if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') === 0)
{
$json->parseRequest($_GET['menuaction'], file_get_contents('php://input'));
}
else
{
$json->parseRequest($_GET['menuaction'], $_REQUEST['json_data']);
}
Json\Response::get();
// run egw destructor now explicit, in case a (notification) email is send via Egw::on_shutdown(),
// as stream-wrappers used by Horde Smtp fail when PHP is already in destruction
$GLOBALS['egw']->__destruct();
}
// missing menuaction GET parameter or request:parameters object or unparsable JSON
catch (\InvalidArgumentException $e) {
if (isset($json)) $json->isJSONRequest(false); // no regular json request processing
// give a proper HTTP status 400 Bad Request with some JSON payload explaining the problem
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(array('error' => $e->getMessage(), 'errno' => $e->getCode()));
}
// other exceptions are handled by our ajax_exception_handler sending them back as alerts to client-side