-
Notifications
You must be signed in to change notification settings - Fork 19
/
index.php
268 lines (218 loc) · 9.64 KB
/
index.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
<?php
/**
* This is the entry point for every request that should return HTML
* (one exception is that it also returns translated text for javascript).
*/
// Bootstrap the script
require_once 'server/includes/bootstrap.php';
/*
* Get the favicon either from theme or use the default.
*
* @param string theme the users theme
* @return string favicon
*/
function getFavicon($theme) {
$favicon = Theming::getFavicon($theme);
if (!isset($favicon) || $favicon === false) {
$favicon = 'client/resources/images/favicon.ico?kv2.2.0';
}
return $favicon;
}
// If the user wants to logout (and is not using single-signon)
// then destroy the session and redirect to this page, so the login page
// will be shown
if (isset($_GET['logout'])) {
if (isset($_SESSION['_keycloak_auth'])) {
$keycloak_auth = $_SESSION['_keycloak_auth']->logout();
header("Location:" . $keycloak_auth . "");
}
else {
// GET variable user will be set when the user was logged out because of session timeout
// or because he logged out in another window.
$username = sanitizeGetValue('user', '', USERNAME_REGEX);
$location = rtrim(dirname($_SERVER['PHP_SELF']), '/') . '/';
header('Location: ' . $location . ($username ? '?user=' . rawurlencode($username) : ''), true, 303);
}
$webappSession->destroy();
exit;
}
// Check if an action GET-parameter was sent with the request.
// This parameter is set when the webapp was opened by clicking on
// a mailto: link in the browser.
// If so, we will store it in the session, so we can use it later.
if (isset($_GET['action']) && !empty($_GET['action'])) {
storeURLDataToSession();
}
// Check if the continue parameter was set. This will be set e.g. when someone
// uses the grommunio Web to login to another application with OpenID Connect.
if (isset($_GET['continue']) && !empty($_GET['continue']) && !isset($_GET['wacontinue'])) {
$_SESSION['continue'] = $_GET['continue'];
}
// Try to authenticate the user
WebAppAuthentication::authenticate();
$webappTitle = defined('WEBAPP_TITLE') && WEBAPP_TITLE ? WEBAPP_TITLE : 'grommunio Web';
if (isset($_COOKIE['webapp_title'])) {
$webappTitle .= " – " . $_COOKIE['webapp_title'];
}
// If we could not authenticate the user, we will show the login page
if (!WebAppAuthentication::isAuthenticated()) {
// Get language from the cookie, or from the language that is set by the admin
$Language = new Language();
$lang = isset($_COOKIE['lang']) ? $_COOKIE['lang'] : LANG;
$lang = $Language->resolveLanguage($lang);
$Language->setLanguage($lang);
// If GET parameter 'load' is defined, we defer handling to the load.php script
if (isset($_GET['load']) && $_GET['load'] !== 'logon') {
include BASE_PATH . 'server/includes/load.php';
exit;
}
// Set some template variables for the login page
$version = 'grommunio Web ' . trim(file_get_contents('version'));
$user = sanitizeGetValue('user', '', USERNAME_REGEX);
$url = '?logon';
if (isset($_GET["logout"]) && $_GET["logout"] == "auto") {
$error = _("You have been automatically logged out");
}
else {
$error = WebAppAuthentication::getErrorMessage();
if (empty($error) && useSecureCookies() && getRequestProtocol() == 'http') {
header("HTTP/1.0 400 Bad Request");
include BASE_PATH . 'server/includes/templates/BadRequest.php';
error_log("Rejected insecure request as configuration for 'SECURE_COOKIES' is true.");
exit;
}
}
// If a username was passed as GET parameter we will prefill the username input
// of the login form with it.
$user = isset($_GET['user']) ? htmlentities($_GET['user']) : '';
// Lets add a header when login failed (DeskApp needs it to identify failed login attempts)
if (WebAppAuthentication::getErrorCode() !== NOERROR) {
header("X-grommunio-Hresult: " . get_mapi_error_name(WebAppAuthentication::getErrorCode()));
}
// Set a template variable for the favicon of the login, welcome, and webclient page
$theme = Theming::getActiveTheme();
$favicon = getFavicon(Theming::getActiveTheme());
include BASE_PATH . 'server/includes/templates/login.php';
exit;
}
// The user is authenticated! Let's get ready to start the webapp.
// If the user just logged in or if url data was stored in the session,
// we will redirect to make sure that a browser refresh will not post
// the credentials again, and that the url data is taken away from the
// url in the address bar (so a browser refresh will not pass them again)
if (isset($_GET['code']) || (WebAppAuthentication::isUsingLoginForm() || isset($_GET['action']) && !empty($_GET['action']))) {
$location = rtrim(dirname($_SERVER['PHP_SELF']), '/') . '/';
header('Location: ' . $location, true, 303);
exit;
}
// TODO: we could replace all references to $GLOBALS['mapisession']
// with WebAppAuthentication::getMAPISession(), that way we would
// lose at least one GLOBAL (because globals suck)
$GLOBALS['mapisession'] = WebAppAuthentication::getMAPISession();
// check if it's DB or LDAP for the password plugin
$result = @json_decode(@file_get_contents(ADMIN_API_STATUS_ENDPOINT, false), true);
if (isset($result['ldap']) && $result['ldap']) {
$GLOBALS['usersinldap'] = true;
}
// Instantiate Plugin Manager and init the plugins (btw: globals suck)
$GLOBALS['PluginManager'] = new PluginManager(ENABLE_PLUGINS);
$GLOBALS['PluginManager']->detectPlugins(DISABLED_PLUGINS_LIST);
// Initialize plugins and prevent any output which might be written as
// plugins might be uncleanly output white-space and other stuff. We must
// not allow this here as it can destroy the response data.
ob_start();
$GLOBALS['PluginManager']->initPlugins(DEBUG_LOADER);
ob_end_clean();
// Create globals settings object (btw: globals suck)
$GLOBALS["settings"] = new Settings();
// Create global operations object
$GLOBALS["operations"] = new Operations();
// If webapp feature is not enabled for the user,
// we will show the login page with appropriated error message.
if ($GLOBALS['mapisession']->isWebappDisableAsFeature()) {
header("X-grommunio-Hresult: " . get_mapi_error_name(MAPI_E_WEBAPP_FEATURE_DISABLED));
$error = _("Sorry, access to grommunio Web is not available with this user account. Please contact your system administrator.");
// Set some template variables for the login page
$user = sanitizeGetValue('user', '', USERNAME_REGEX);
$url = '?logon';
// Set a template variable for the favicon of the login, welcome, and webclient page
$theme = Theming::getActiveTheme();
$favicon = getFavicon(Theming::getActiveTheme());
$webappSession->destroy();
// Include the login template
include BASE_PATH . 'server/includes/templates/login.php';
exit;
}
$Language = new Language();
// Set session settings (language & style)
foreach ($GLOBALS["settings"]->getSessionSettings($Language) as $key => $value) {
$_SESSION[$key] = $value;
}
// Get language from the request, or the session, or the user settings, or the config
if (isset($_REQUEST["language"]) && $Language->is_language($_REQUEST["language"])) {
$lang = $_REQUEST["language"];
$GLOBALS["settings"]->set("zarafa/v1/main/language", $lang);
}
elseif (isset($_SESSION["lang"])) {
$lang = $_SESSION["lang"];
$GLOBALS["settings"]->set("zarafa/v1/main/language", $lang);
}
else {
$lang = $GLOBALS["settings"]->get("zarafa/v1/main/language");
if (empty($lang)) {
$lang = LANG;
$GLOBALS["settings"]->set("zarafa/v1/main/language", $lang);
}
}
$Language->setLanguage($lang);
setcookie('lang', $lang, [
'expires' => time() + 31536000,
'path' => '/',
'domain' => '',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict',
]);
// add extra header
header("X-grommunio: " . trim(file_get_contents('version')));
// Set a template variable for the favicon of the login, welcome, and webclient page
$theme = Theming::getActiveTheme();
$favicon = getFavicon(Theming::getActiveTheme());
$hideFavorites = $GLOBALS["settings"]->get("zarafa/v1/contexts/hierarchy/hide_favorites") ? 'hideFavorites' : '';
$scrollFavorites = $GLOBALS["settings"]->get("zarafa/v1/contexts/hierarchy/scroll_favorites") ? 'scrollFavorites' : '';
$unreadBorders = $GLOBALS["settings"]->get("zarafa/v1/main/unread_borders") === false ? '' : 'k-unreadborders';
// If GET parameter 'load' is defined, we defer handling to the load.php script
if (isset($_GET['load'])) {
include BASE_PATH . 'server/includes/load.php';
exit;
}
if (ENABLE_WELCOME_SCREEN && $GLOBALS["settings"]->get("zarafa/v1/main/show_welcome") !== false) {
// These hooks are defined twice (also when there is a "load" argument supplied)
$GLOBALS['PluginManager']->triggerHook("server.index.load.welcome.before");
include BASE_PATH . 'server/includes/templates/welcome.php';
$GLOBALS['PluginManager']->triggerHook("server.index.load.welcome.after");
}
else {
// Set the show_welcome to false, so that when the admin is changing the
// ENABLE_WELCOME_SCREEN option to false after some time, the users who are already
// using grommunio Web are not bothered with the Welcome Screen.
$GLOBALS["settings"]->set("zarafa/v1/main/show_welcome", false);
// Clean up old state files in tmp/session/
$state = new State("index");
$state->clean();
// Clean up old attachments in tmp/attachments/
$state = new AttachmentState();
$state->clean();
// Fetch the hierarchy state cache for unread counters notifications for subfolders
$counterState = new State('counters_sessiondata');
$counterState->open();
$counterState->write("sessionData", updateHierarchyCounters());
$counterState->close();
// clean search folders
cleanSearchFolders();
// These hooks are defined twice (also when there is a "load" argument supplied)
$GLOBALS['PluginManager']->triggerHook("server.index.load.main.before");
// Include webclient
include BASE_PATH . 'server/includes/templates/webclient.php';
$GLOBALS['PluginManager']->triggerHook("server.index.load.main.after");
}