Skip to content

Commit ded128e

Browse files
committed
Better RC integration
1 parent ea8d801 commit ded128e

2 files changed

Lines changed: 40 additions & 76 deletions

File tree

bridge.php

Lines changed: 36 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
11
<?php
2-
// Parts of this file are based on index.php (Roundcube version 1.4.8).
3-
// TODO Reduce amount of duplicate code from index.php. We may be able to do that by:
4-
// * removing authenticate hook logic using $_POST.
5-
// * moving login logic to a function provided by base Roundcube
6-
7-
// include environment
8-
require_once __DIR__ . '/../../program/include/iniset.php';
9-
10-
// init application, start session, init output class, etc.
11-
$RCMAIL = rcmail::get_instance(0, $GLOBALS['env']);
12-
13-
/// Auth hack BEGIN
14-
// TODO authenticate hook may actually be removed. Unclear if this is required for cPanel auth.
15-
// Set some global POST vars that would be usually set via HTML <input> tags are:
16-
// _task, _action, _timezone, _user, _pass, _token . We set all except for token.
17-
// Token should only be required for an existing session. Also disregarding Timezone for now
18-
$_POST['_user'] = $_SERVER['PHP_AUTH_USER'];
19-
$_POST['_pass'] = $_SERVER['PHP_AUTH_PW'];
20-
$_POST['_action'] = 'login';
21-
$_POST['_task'] = 'login';
2+
// Assuming we are inside RC's plugins/jmap dir
3+
define('INSTALL_PATH', realpath('../../') . '/');
4+
5+
// load the whole Roundcube Webmail code with its autoloader
6+
require_once INSTALL_PATH . '/program/include/iniset.php';
7+
$RCMAIL = rcmail::get_instance(rcube::INIT_WITH_DB | rcube::INIT_WITH_PLUGINS);
8+
9+
$user = $_SERVER['PHP_AUTH_USER'];
10+
$pass = $_SERVER['PHP_AUTH_PW'];
2211

2312
/// Impersonation / admin auth BEGIN
2413
// An array to store the admin user, as well the user-to-impersonate
@@ -28,41 +17,36 @@
2817
// Check if we're dealing with admin auth credentials
2918
// and if yes, then take the first part as the admin username
3019
// to use for login
31-
if (mb_strpos($_POST['_user'], "*")) {
32-
$users = explode("*", $_POST['_user']);
33-
$_POST['_user'] = $users[0];
20+
if (mb_strpos($user, "*")) {
21+
$users = explode("*", $user);
22+
$user = $users[0];
3423
}
35-
/// Impersonation / admin auth END
3624

25+
/// Authenticate hook
3726
$pass_charset = $RCMAIL->config->get('password_charset', 'UTF-8');
3827

3928
$auth = $RCMAIL->plugins->exec_hook('authenticate', array(
4029
'host' => $RCMAIL->autoselect_host(),
41-
'user' => trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST)),
42-
'pass' => rcube_utils::get_input_value('_pass', rcube_utils::INPUT_POST, true, $pass_charset),
30+
'user' => trim(rcube_utils::parse_input_value($user)),
31+
'pass' => rcube_utils::parse_input_value($pass, true, $pass_charset),
4332
'valid' => true, // It is always valid in Karlsruhe!
4433
'cookiecheck' => false, // No cookies for you in Karlsruhe!
4534
));
46-
/// Auth hack END
47-
48-
// Login
49-
// TODO The following contains quite a lot of duplicate code from RC's index.php.
50-
// It may be moved to an own function (except for returning errors via API)?
51-
if (
52-
$auth['valid'] && !$auth['abort']
53-
&& $RCMAIL->login($auth['user'], $auth['pass'], $auth['host'], $auth['cookiecheck'])
54-
) {
55-
$logger->info("Successfully logged in as " . $auth['user']);
56-
57-
// log successful login
58-
$RCMAIL->log_login();
59-
} else {
35+
36+
// IMAP Login
37+
$login_success = false;
38+
if ($auth['valid'] && !$auth['abort']){
39+
if($RCMAIL->login($auth['user'], $auth['pass'], $auth['host'], false, true)) {
40+
$logger->info("Successfully logged in as " . $auth['user']);
41+
$login_success = true;
42+
}
43+
}
44+
if (!$auth['valid'] || $auth['abort'] || !$login_success){
6045
if (!$auth['valid']) {
6146
$error_code = rcmail::ERROR_INVALID_REQUEST;
6247
} else {
6348
$error_code = is_numeric($auth['error']) ? $auth['error'] : $RCMAIL->login_error();
6449
}
65-
6650
$error_labels = array(
6751
rcmail::ERROR_STORAGE => 'storageerror',
6852
rcmail::ERROR_COOKIES_DISABLED => 'cookiesdisabled',
@@ -83,17 +67,17 @@
8367
$loginError = null;
8468

8569
switch ($error_code) {
86-
case rcmail::ERROR_RATE_LIMIT:
87-
$loginError = 'urn:ietf:params:jmap:error:limit';
88-
header('HTTP/1.0 429 Too Many Requests');
89-
break;
90-
case rcmail::ERROR_INVALID_REQUEST:
91-
$loginError = 'urn:ietf:params:jmap:error:notRequest';
92-
header('HTTP/1.0 400 Bad Request');
93-
break;
94-
default:
95-
$loginError = '401 Unauthorized';
96-
header('HTTP/1.0 401 Unauthorized');
70+
case rcmail::ERROR_RATE_LIMIT:
71+
$loginError = 'urn:ietf:params:jmap:error:limit';
72+
header('HTTP/1.0 429 Too Many Requests');
73+
break;
74+
case rcmail::ERROR_INVALID_REQUEST:
75+
$loginError = 'urn:ietf:params:jmap:error:notRequest';
76+
header('HTTP/1.0 400 Bad Request');
77+
break;
78+
default:
79+
$loginError = '401 Unauthorized';
80+
header('HTTP/1.0 401 Unauthorized');
9781
}
9882

9983
die($loginError);

jmap.php

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,11 @@
11
<?php
22

3-
use OpenXPort\Jmap\Contact\ContactsAccountCapability;
4-
use OpenXPort\Jmap\Core\CoreAccountCapability;
5-
use OpenXPort\Jmap\Mail\SubmissionAccountCapability;
63
use OpenXPort\Util\RoundcubeSessionUtil;
74

85
// Define version
9-
$oxpVersion = '1.4.0';
6+
$oxpVersion = '1.4.1';
107

11-
/**
12-
* Fix for a refactoring bug (due to usage of bridge.php)
13-
*
14-
* The problem is that $_SERVER['SCRIPT_FILENAME'] is used for setting the include_path for Roundcube,
15-
* but it references the currently executed script, which is jmap.php in our case.
16-
* Since jmap.php is not positioned as a file on the same level as index.php,
17-
* which is normally the running script, the include_path of Roundcube gets messed up.
18-
* That's why we have to explicitly hack $_SERVER['SCRIPT_FILENAME'] so roundcube gets the correct
19-
* include_path.
20-
* For more info, see: https://github.com/roundcube/roundcubemail/blob/master/program/include/iniset.php
21-
* (lines 27, 47 and 48)
22-
*/
23-
24-
$_SERVER['SCRIPT_FILENAME'] = realpath(__DIR__ . '/../../index.php');
25-
26-
/* START OF OPENXPORT Code only */
27-
// Use our composer autoload
8+
// Use OXP composer autoload
289
require_once __DIR__ . '/vendor/autoload.php';
2910

3011
// Build config
@@ -50,12 +31,11 @@
5031
OpenXPort\Util\Logger::init($oxpConfig, $jmapRequest);
5132
$logger = \OpenXPort\Util\Logger::getInstance();
5233

53-
// Reuse auth from webmailer
34+
// Initialize Webmailer
5435
require_once __DIR__ . '/bridge.php';
5536

5637
$logger->notice("Running PHP v" . phpversion() . ", RC v" . RCMAIL_VERSION . ", Plugin v" . $oxpVersion);
5738

58-
// TODO Probably from here on only
5939
$accessors = array(
6040
"Contacts" => null,
6141
"Calendars" => null,
@@ -111,7 +91,7 @@
11191

11292
$accountData = [
11393
'accountId' => $RCMAIL->user->ID,
114-
'username' => isset($users[1]) ? $users[1] : $_POST['_user'],
94+
'username' => isset($users[1]) ? $users[1] : $user,
11595
'accountCapabilities' => []
11696
];
11797
$session = RoundcubeSessionUtil::createSession($accountData);

0 commit comments

Comments
 (0)