1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This is the entry point for every request that should return HTML |
||
5 | * (one exception is that it also returns translated text for javascript). |
||
6 | */ |
||
7 | |||
8 | // Bootstrap the script |
||
9 | require_once 'server/includes/bootstrap.php'; |
||
10 | |||
11 | // Added in 3.4.0, remove check in 3.5.0 |
||
12 | if (!function_exists('gitversion')) { |
||
13 | /** |
||
14 | * Obtain the current Git working branch. |
||
15 | * |
||
16 | * @return string the current git working branch |
||
17 | */ |
||
18 | function gitversion() { |
||
19 | if (is_dir(BASE_PATH . DIRECTORY_SEPARATOR . '.git')) { |
||
20 | return trim(@shell_exec("git symbolic-ref --short HEAD || git rev-parse --short HEAD .")); |
||
21 | } |
||
22 | |||
23 | return ''; |
||
24 | } |
||
25 | } |
||
26 | else { |
||
27 | error_log('Remove gitversion() function in debug.php it\'s deprecated'); |
||
28 | } |
||
29 | |||
30 | /* |
||
31 | * Get the favicon either from theme or use the default. |
||
32 | * |
||
33 | * @param string theme the users theme |
||
34 | * @return string favicon |
||
35 | */ |
||
36 | function getFavicon($theme) { |
||
37 | $favicon = Theming::getFavicon($theme); |
||
38 | |||
39 | if (!isset($favicon) || $favicon === false) { |
||
40 | $favicon = 'client/resources/images/favicon.ico?kv2.2.0'; |
||
41 | } |
||
42 | |||
43 | return $favicon; |
||
44 | } |
||
45 | |||
46 | // If the user wants to logout (and is not using single-signon) |
||
47 | // then destroy the session and redirect to this page, so the login page |
||
48 | // will be shown |
||
49 | if (isset($_GET['logout'])) { |
||
50 | // GET variable user will be set when the user was logged out because of session timeout |
||
51 | // or because he logged out in another window. |
||
52 | $username = sanitizeGetValue('user', '', USERNAME_REGEX); |
||
53 | $webappSession->destroy(); |
||
54 | $location = rtrim(dirname($_SERVER['PHP_SELF']), '/') . '/'; |
||
55 | header('Location: ' . $location . ($username ? '?user=' . rawurlencode($username) : ''), true, 303); |
||
56 | |||
57 | exit(); |
||
58 | } |
||
59 | |||
60 | // Check if an action GET-parameter was sent with the request. |
||
61 | // This parameter is set when the webapp was opened by clicking on |
||
62 | // a mailto: link in the browser. |
||
63 | // If so, we will store it in the session, so we can use it later. |
||
64 | if (isset($_GET['action']) && !empty($_GET['action'])) { |
||
65 | storeURLDataToSession(); |
||
66 | } |
||
67 | |||
68 | // Check if the continue parameter was set. This will be set e.g. when someone |
||
69 | // uses the grommunio Web to login to another application with OpenID Connect. |
||
70 | if (isset($_GET['continue']) && !empty($_GET['continue']) && !isset($_GET['wacontinue'])) { |
||
71 | $_SESSION['continue'] = $_GET['continue']; |
||
72 | } |
||
73 | |||
74 | // Try to authenticate the user |
||
75 | WebAppAuthentication::authenticate(); |
||
76 | |||
77 | $webappTitle = defined('WEBAPP_TITLE') && WEBAPP_TITLE ? WEBAPP_TITLE : 'grommunio Web'; |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
78 | if (isset($_COOKIE['webapp_title'])) { |
||
79 | $webappTitle .= " – " . $_COOKIE['webapp_title']; |
||
80 | } |
||
81 | |||
82 | // If we could not authenticate the user, we will show the login page |
||
83 | if (!WebAppAuthentication::isAuthenticated()) { |
||
84 | // Get language from the cookie, or from the language that is set by the admin |
||
85 | $Language = new Language(); |
||
86 | $lang = isset($_COOKIE['lang']) ? $_COOKIE['lang'] : LANG; |
||
0 ignored issues
–
show
|
|||
87 | $lang = $Language->resolveLanguage($lang); |
||
88 | $Language->setLanguage($lang); |
||
89 | |||
90 | // If GET parameter 'load' is defined, we defer handling to the load.php script |
||
91 | if (isset($_GET['load']) && $_GET['load'] !== 'logon') { |
||
92 | include BASE_PATH . 'server/includes/load.php'; |
||
93 | |||
94 | exit(); |
||
95 | } |
||
96 | |||
97 | // Set some template variables for the login page |
||
98 | $branch = DEBUG_LOADER === LOAD_SOURCE ? gitversion() : ''; |
||
99 | $version = 'grommunio Web ' . trim(file_get_contents('version')); |
||
100 | $user = sanitizeGetValue('user', '', USERNAME_REGEX); |
||
101 | |||
102 | $url = '?logon'; |
||
103 | |||
104 | if (isset($_GET["logout"]) && $_GET["logout"] == "auto") { |
||
105 | $error = _("You have been automatically logged out"); |
||
106 | } |
||
107 | else { |
||
108 | $error = WebAppAuthentication::getErrorMessage(); |
||
109 | if (empty($error) && useSecureCookies() && getRequestProtocol() == 'http') { |
||
110 | header("HTTP/1.0 400 Bad Request"); |
||
111 | include BASE_PATH . 'server/includes/templates/BadRequest.php'; |
||
112 | error_log("Rejected insecure request as configuration for 'SECURE_COOKIES' is true."); |
||
113 | |||
114 | exit(); |
||
115 | } |
||
116 | } |
||
117 | |||
118 | // If a username was passed as GET parameter we will prefill the username input |
||
119 | // of the login form with it. |
||
120 | $user = isset($_GET['user']) ? htmlentities($_GET['user']) : ''; |
||
121 | |||
122 | // Lets add a header when login failed (DeskApp needs it to identify failed login attempts) |
||
123 | if (WebAppAuthentication::getErrorCode() !== NOERROR) { |
||
124 | header("X-grommunio-Hresult: " . get_mapi_error_name(WebAppAuthentication::getErrorCode())); |
||
125 | } |
||
126 | |||
127 | // Set a template variable for the favicon of the login, welcome, and webclient page |
||
128 | $theme = Theming::getActiveTheme(); |
||
129 | $favicon = getFavicon(Theming::getActiveTheme()); |
||
130 | include BASE_PATH . 'server/includes/templates/login.php'; |
||
131 | |||
132 | exit(); |
||
133 | } |
||
134 | |||
135 | // The user is authenticated! Let's get ready to start the webapp. |
||
136 | |||
137 | // If the user just logged in or if url data was stored in the session, |
||
138 | // we will redirect to make sure that a browser refresh will not post |
||
139 | // the credentials again, and that the url data is taken away from the |
||
140 | // url in the address bar (so a browser refresh will not pass them again) |
||
141 | if (WebAppAuthentication::isUsingLoginForm() || isset($_GET['action']) && !empty($_GET['action'])) { |
||
142 | $location = rtrim(dirname($_SERVER['PHP_SELF']), '/') . '/'; |
||
143 | header('Location: ' . $location, true, 303); |
||
144 | |||
145 | exit(); |
||
146 | } |
||
147 | |||
148 | // TODO: we could replace all references to $GLOBALS['mapisession'] |
||
149 | // with WebAppAuthentication::getMapiSession(), that way we would |
||
150 | // lose at least one GLOBAL (because globals suck) |
||
151 | $GLOBALS['mapisession'] = WebAppAuthentication::getMapiSession(); |
||
152 | |||
153 | // check if it's DB or LDAP for the password plugin |
||
154 | $result = @json_decode(@file_get_contents(ADMIN_API_STATUS_ENDPOINT, false), true); |
||
0 ignored issues
–
show
|
|||
155 | if (isset($result['ldap']) && $result['ldap']) { |
||
156 | $GLOBALS['usersinldap'] = true; |
||
157 | } |
||
158 | |||
159 | // Instantiate Plugin Manager and init the plugins (btw: globals suck) |
||
160 | $GLOBALS['PluginManager'] = new PluginManager(ENABLE_PLUGINS); |
||
161 | $GLOBALS['PluginManager']->detectPlugins(DISABLED_PLUGINS_LIST); |
||
0 ignored issues
–
show
|
|||
162 | |||
163 | // Initialize plugins and prevent any output which might be written as |
||
164 | // plugins might be uncleanly output white-space and other stuff. We must |
||
165 | // not allow this here as it can destroy the response data. |
||
166 | ob_start(); |
||
167 | $GLOBALS['PluginManager']->initPlugins(DEBUG_LOADER); |
||
168 | ob_end_clean(); |
||
169 | |||
170 | // Create globals settings object (btw: globals suck) |
||
171 | $GLOBALS["settings"] = new Settings(); |
||
172 | |||
173 | // Create global operations object |
||
174 | $GLOBALS["operations"] = new Operations(); |
||
175 | |||
176 | // If webapp feature is not enabled for the user, |
||
177 | // we will show the login page with appropriated error message. |
||
178 | if ($GLOBALS['mapisession']->isWebappDisableAsFeature()) { |
||
179 | header("X-grommunio-Hresult: " . get_mapi_error_name(MAPI_E_WEBAPP_FEATURE_DISABLED)); |
||
180 | |||
181 | $error = _("Sorry, access to grommunio Web is not available with this user account. Please contact your system administrator."); |
||
182 | // Set some template variables for the login page |
||
183 | $user = sanitizeGetValue('user', '', USERNAME_REGEX); |
||
184 | |||
185 | $url = '?logon'; |
||
186 | // Set a template variable for the favicon of the login, welcome, and webclient page |
||
187 | $theme = Theming::getActiveTheme(); |
||
188 | $favicon = getFavicon(Theming::getActiveTheme()); |
||
189 | $webappSession->destroy(); |
||
190 | // Include the login template |
||
191 | include BASE_PATH . 'server/includes/templates/login.php'; |
||
192 | |||
193 | exit(); |
||
194 | } |
||
195 | |||
196 | $Language = new Language(); |
||
197 | |||
198 | // Set session settings (language & style) |
||
199 | foreach ($GLOBALS["settings"]->getSessionSettings($Language) as $key => $value) { |
||
200 | $_SESSION[$key] = $value; |
||
201 | } |
||
202 | |||
203 | // Get language from the request, or the session, or the user settings, or the config |
||
204 | if (isset($_REQUEST["language"]) && $Language->is_language($_REQUEST["language"])) { |
||
205 | $lang = $_REQUEST["language"]; |
||
206 | $GLOBALS["settings"]->set("zarafa/v1/main/language", $lang); |
||
207 | } |
||
208 | elseif (isset($_SESSION["lang"])) { |
||
209 | $lang = $_SESSION["lang"]; |
||
210 | $GLOBALS["settings"]->set("zarafa/v1/main/language", $lang); |
||
211 | } |
||
212 | else { |
||
213 | $lang = $GLOBALS["settings"]->get("zarafa/v1/main/language"); |
||
214 | if (empty($lang)) { |
||
215 | $lang = LANG; |
||
216 | $GLOBALS["settings"]->set("zarafa/v1/main/language", $lang); |
||
217 | } |
||
218 | } |
||
219 | |||
220 | $Language->setLanguage($lang); |
||
221 | setcookie('lang', $lang, time() + 31536000, '/', '', getRequestProtocol() === 'https'); |
||
222 | |||
223 | // add extra header |
||
224 | header("X-grommunio: " . trim(file_get_contents('version'))); |
||
225 | |||
226 | // Set a template variable for the favicon of the login, welcome, and webclient page |
||
227 | $theme = Theming::getActiveTheme(); |
||
228 | $favicon = getFavicon(Theming::getActiveTheme()); |
||
229 | $hideFavorites = $GLOBALS["settings"]->get("zarafa/v1/contexts/hierarchy/hide_favorites") ? 'hideFavorites' : ''; |
||
230 | $scrollFavorites = $GLOBALS["settings"]->get("zarafa/v1/contexts/hierarchy/scroll_favorites") ? 'scrollFavorites' : ''; |
||
231 | $unreadBorders = $GLOBALS["settings"]->get("zarafa/v1/main/unread_borders") === false ? '' : 'k-unreadborders'; |
||
232 | |||
233 | // If GET parameter 'load' is defined, we defer handling to the load.php script |
||
234 | if (isset($_GET['load'])) { |
||
235 | include BASE_PATH . 'server/includes/load.php'; |
||
236 | |||
237 | exit(); |
||
238 | } |
||
239 | |||
240 | if (ENABLE_WELCOME_SCREEN && $GLOBALS["settings"]->get("zarafa/v1/main/show_welcome") !== false) { |
||
241 | // These hooks are defined twice (also when there is a "load" argument supplied) |
||
242 | $GLOBALS['PluginManager']->triggerHook("server.index.load.welcome.before"); |
||
243 | include BASE_PATH . 'server/includes/templates/welcome.php'; |
||
244 | $GLOBALS['PluginManager']->triggerHook("server.index.load.welcome.after"); |
||
245 | } |
||
246 | else { |
||
247 | // Set the show_welcome to false, so that when the admin is changing the |
||
248 | // ENABLE_WELCOME_SCREEN option to false after some time, the users who are already |
||
249 | // using grommunio Web are not bothered with the Welcome Screen. |
||
250 | $GLOBALS["settings"]->set("zarafa/v1/main/show_welcome", false); |
||
251 | |||
252 | // Clean up old state files in tmp/session/ |
||
253 | $state = new State("index"); |
||
254 | $state->clean(); |
||
255 | |||
256 | // Clean up old attachments in tmp/attachments/ |
||
257 | $state = new AttachmentState(); |
||
258 | $state->clean(); |
||
259 | |||
260 | // Fetch the hierarchy state cache for unread counters notifications for subfolders |
||
261 | $counterState = new State('counters_sessiondata'); |
||
262 | $counterState->open(); |
||
263 | $counterState->write("sessionData", updateHierarchyCounters()); |
||
264 | $counterState->close(); |
||
265 | |||
266 | // clean search folders |
||
267 | cleanSearchFolders(); |
||
268 | |||
269 | // These hooks are defined twice (also when there is a "load" argument supplied) |
||
270 | $GLOBALS['PluginManager']->triggerHook("server.index.load.main.before"); |
||
271 | |||
272 | // Include webclient |
||
273 | include BASE_PATH . 'server/includes/templates/webclient.php'; |
||
274 | $GLOBALS['PluginManager']->triggerHook("server.index.load.main.after"); |
||
275 | } |
||
276 |