Skip to content

Commit

Permalink
Replace Kronolith-specific caldav_url hook with global davusername hook.
Browse files Browse the repository at this point in the history
It's much simpler, sufficient for the most use cases, and has the big advantage that we can translate the user names back too.

The other DAV APIs beside Kronolith's CalDAV API still need to be updated to use this hook.

I wonder if we should generalize it even further to a "rpcusername" hook, because any RPC request suffers from the problem that users cannot select an authentication backend (IMAP server), which is what this hook is trying to solve.
  • Loading branch information
yunosh committed May 2, 2016
1 parent 197ec3e commit 4b6001d
Show file tree
Hide file tree
Showing 16 changed files with 236 additions and 112 deletions.
41 changes: 41 additions & 0 deletions framework/Core/lib/Horde/Core/Dav/Auth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
/**
* Copyright 2016 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Jan Schneider <jan@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Core
*/

/**
* Extends Horde's authentication backend for Sabre to support username hooks.
*
* @author Jan Schneider <jan@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Core
*/
class Horde_Core_Dav_Auth extends Horde_Dav_Auth
{
/**
* Returns information about the currently logged in username.
*
* If nobody is currently logged in, this method should return null.
*
* @return string|null
*/
public function getCurrentUser()
{
$user = $this->_auth->getCredential('userId');
try {
$user = $GLOBALS['injector']->getInstance('Horde_Core_Hooks')
->callHook('davusername', 'horde', array($user, false));
} catch (Horde_Exception_HookNotSet $e) {
}
return $user;
}
}
4 changes: 2 additions & 2 deletions framework/Core/lib/Horde/Core/Factory/DavServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function create(Horde_Injector $injector)
->create()
)
),
$injector->getInstance('Horde_Core_Factory_Identity_UsernameHook')
$injector->getInstance('Horde_Core_Factory_Identity_DavUsernameHook')
);
$principals = new DAVACL\PrincipalCollection($principalBackend);
$principals->disableListing = $conf['auth']['list_users'] == 'input';
Expand All @@ -62,7 +62,7 @@ public function create(Horde_Injector $injector)
);
$server->addPlugin(
new DAV\Auth\Plugin(
new Horde_Dav_Auth(
new Horde_Core_Dav_Auth(
$injector->getInstance('Horde_Core_Factory_Auth')->create()
),
'Horde DAV Server'
Expand Down
44 changes: 44 additions & 0 deletions framework/Core/lib/Horde/Core/Factory/Identity/DavUsernameHook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* Copyright 2016 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @package Core
* @author Jan Schneider <jan@horde.org>
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
*/

/**
* A Horde_Injector based Horde_Identity factory that converts the user name
* through the davusername hook.
*
* @category Horde
* @package Core
* @author Jan Schneider <jan@horde.org>
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
*/
class Horde_Core_Factory_Identity_DavUsernameHook extends Horde_Core_Factory_Identity_UsernameHook
{
/**
* Returns the Horde_Identity instance.
*
* @param string $user The user to use, if not the current user.
* @param string $driver The identity driver. Either empty (use default
* driver) or an application name.
*
* @return Horde_Identity The singleton identity instance.
* @throws Horde_Exception
*/
public function create($user = null, $driver = null)
{
try {
$user = $this->_injector->getInstance('Horde_Core_Hooks')
->callHook('davusername', 'horde', array($user, true));
} catch (Horde_Exception_HookNotSet $e) {
}
return parent::create($user, $driver);
}
}
20 changes: 14 additions & 6 deletions framework/Core/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,18 @@
<email>mrubinsk@horde.org</email>
<active>yes</active>
</developer>
<date>2016-03-08</date>
<date>2016-05-02</date>
<version>
<release>2.23.1</release>
<api>2.23.0</api>
<release>2.24.0</release>
<api>2.24.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
* [jan] Add classes to support the Horde 6 davusername hook.
* [jan] Fix session_regenerate_id() warnings with PHP 7.
* [jan] Fix running garbage collection on cached CSS and JS files (Bug #14285).
</notes>
Expand Down Expand Up @@ -400,6 +401,9 @@
<dir name="Data">
<file name="Storage.php" role="php" />
</dir> <!-- /lib/Horde/Core/Data -->
<dir name="Dav">
<file name="Auth.php" role="php" />
</dir> <!-- /lib/Horde/Core/Dav -->
<dir name="Db">
<file name="Migration.php" role="php" />
</dir> <!-- /lib/Horde/Core/Db -->
Expand All @@ -408,6 +412,7 @@
</dir> <!-- /lib/Horde/Core/Editor -->
<dir name="Factory">
<dir name="Identity">
<file name="DavUsernameHook.php" role="php" />
<file name="UsernameHook.php" role="php" />
</dir> <!-- /lib/Horde/Core/Factory/Identity -->
<dir name="Secret">
Expand Down Expand Up @@ -1821,6 +1826,7 @@
<install as="Horde/Core/Controller/RequestMapper.php" name="lib/Horde/Core/Controller/RequestMapper.php" />
<install as="Horde/Core/Controller/SettingsFinder.php" name="lib/Horde/Core/Controller/SettingsFinder.php" />
<install as="Horde/Core/Data/Storage.php" name="lib/Horde/Core/Data/Storage.php" />
<install as="Horde/Core/Dav/Auth.php" name="lib/Horde/Core/Dav/Auth.php" />
<install as="Horde/Core/Db/Migration.php" name="lib/Horde/Core/Db/Migration.php" />
<install as="Horde/Core/Editor/Ckeditor.php" name="lib/Horde/Core/Editor/Ckeditor.php" />
<install as="Horde/Core/Factory/ActiveSyncBackend.php" name="lib/Horde/Core/Factory/ActiveSyncBackend.php" />
Expand Down Expand Up @@ -1897,6 +1903,7 @@
<install as="Horde/Core/Factory/Vfs.php" name="lib/Horde/Core/Factory/Vfs.php" />
<install as="Horde/Core/Factory/View.php" name="lib/Horde/Core/Factory/View.php" />
<install as="Horde/Core/Factory/Weather.php" name="lib/Horde/Core/Factory/Weather.php" />
<install as="Horde/Core/Factory/Identity/DavUsernameHook.php" name="lib/Horde/Core/Factory/Identity/DavUsernameHook.php" />
<install as="Horde/Core/Factory/Identity/UsernameHook.php" name="lib/Horde/Core/Factory/Identity/UsernameHook.php" />
<install as="Horde/Core/Factory/Secret/Cbc.php" name="lib/Horde/Core/Factory/Secret/Cbc.php" />
<install as="Horde/Core/Group/Ldap.php" name="lib/Horde/Core/Group/Ldap.php" />
Expand Down Expand Up @@ -4166,14 +4173,15 @@
</release>
<release>
<version>
<release>2.23.1</release>
<api>2.23.0</api></version>
<release>2.24.0</release>
<api>2.24.0</api></version>
<stability>
<release>stable</release>
<api>stable</api></stability>
<date>2016-03-08</date>
<date>2016-05-02</date>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
* [jan] Add classes to support the Horde 6 davusername hook.
* [jan] Fix session_regenerate_id() warnings with PHP 7.
* [jan] Fix running garbage collection on cached CSS and JS files (Bug #14285).
</notes>
Expand Down
74 changes: 74 additions & 0 deletions horde/config/hooks.php.dist
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,22 @@
* [throw Horde_Auth_Exception] - Fatal error.
* (string) - The converted username.
*
* davusername
* -----------
* This hook is used to dynamically convert between a username for DAV clients
* and a Horde username.
*
* May for example be used to add some realm to user names referring to an IMAP
* server that would otherwise be picked from the login screen.
*
* Parameters in:
* $userId (string): The username.
* $toHorde (boolean): If true, convert from DAV ID to Horde ID.
* Otherwise, do the reverse conversion.
*
* The return value from this hook is as follows:
* (string) - The converted username.
*
* x509_validate
* -------------
* This hook is called during initial authentication when using the X509 client
Expand Down Expand Up @@ -619,6 +635,64 @@ class Horde_Hooks
// }


// // DAV USERNAME HOOK: See above for description of format.
// public function davusername($userId, $toHorde)
// {
// // Example: append realm to user name
// global $registry;
//
// if (!$userId) {
// return $userId;
// }
//
// $server = $registry->mail->server();
// $realm = $server['hostspec'];
// if ($toHorde) {
// return (substr($userId, -strlen($realm)) == $realm)
// ? substr($userId, 0, -strlen($realm) - 1)
// : $userId;
// }
//
// return Horde_String::lower($userId) . '@' . $realm;
// }
//
// // The following hook examples may pick up the realm information from
// // above:
// //
// // public function pushapp()
// // {
// // if (strpos($_SERVER['REQUEST_URI'], '/rpc') &&
// // preg_match('/@([^\/]*)/', $_SERVER['REQUEST_URI'], $m)) {
// // // Parse the domain part from the user name in the URL, and
// // // save it as the realm.
// // putenv('REALM=' . basename($m[1]));
// // }
// // }
// //
// // public function preauthenticate($userId, $credentials)
// // {
// // global $registry;
// // $result = array('userId' => $userId, 'credentials' => $credentials);
// // if ($credentials['authMethod'] == 'authenticate' &&
// // strpos($_SERVER['REQUEST_URI'], '/rpc') &&
// // ($realm = getenv('REALM'))) {
// // // If this was realm'ed RPC request, pick the correct server
// // // from IMP's backend configuration.
// // $servers = $registry
// // ->loadConfigFile('backends.php', 'servers', 'imp')
// // ->config['servers'];
// // foreach ($servers as $key => $server) {
// // if (empty($server['disabled']) &&
// // $server['hostspec'] == $realm) {
// // $result['credentials']['server'] = $key;
// // break;
// // }
// // }
// // }
// // return $result;
// // }


// // APPLICATION AUTHENTICATED HOOK: See above for format.
// public function appauthenticated()
// {
Expand Down
1 change: 1 addition & 0 deletions horde/docs/CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
v5.3.0-git
----------

[jan] Add hook to customize user names for DAV clients.
[jan] Show users' full names in user lists.
[jan] Only show languages on login page that are supported by the system
(Request #10457).
Expand Down
10 changes: 10 additions & 0 deletions horde/docs/UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ The 'maps' configuration options have been moved to the ``horde`` application
configuration.


Hooks (hooks.php)
-----------------

The following hooks have been added::

davusername

See ``config/hooks.php.dist`` for further details.


Upgrading Horde from 5.1.x to 5.2
=================================

Expand Down
2 changes: 2 additions & 0 deletions horde/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
</stability>
<license uri="http://www.horde.org/licenses/lgpl">LGPL-2</license>
<notes>
* [jan] Add hook to customize user names for DAV clients.
* [jan] Show users&apos; full names in user lists.
* [jan] Only show languages on login page that are supported by the system (Request #10457).
* [jan] Add option to always lowercase user names after logging in.
Expand Down Expand Up @@ -4213,6 +4214,7 @@
<date>2016-04-05</date>
<license uri="http://www.horde.org/licenses/lgpl">LGPL-2</license>
<notes>
* [jan] Add hook to customize user names for DAV clients.
* [jan] Show users&apos; full names in user lists.
* [jan] Only show languages on login page that are supported by the system (Request #10457).
* [jan] Add option to always lowercase user names after logging in.
Expand Down
51 changes: 0 additions & 51 deletions kronolith/config/hooks.php.dist
Original file line number Diff line number Diff line change
Expand Up @@ -31,55 +31,4 @@ class Kronolith_Hooks
//
// throw new Horde_Exception('Unknown action');
// }

/**
* Customizes the original CalDAV URLs presented in the user interface.
*
* May for example be used to add some realm to user names that would
* otherwise be picked from the login screen.
*
* The following Horde hook examples may pick this information up, when
* using IMP for authentication:
*
* <code>
* public function pushapp()
* {
* if (strpos($_SERVER['REQUEST_URI'], '/rpc') &&
* preg_match('/^(.*)@([^\/]*)(.*)$/', $_SERVER['REQUEST_URI'], $m)) {
* // Restore to the original URL that Horde understands, but save
* // the realm part.
* $_SERVER['REQUEST_URI'] = $m[1] . $m[3];
* putenv('REALM=' . basename($m[2]));
* }
* }
*
* public function preauthenticate($userId, $credentials)
* {
* $result = array($userId, $credentials);
* if ($credentials['authMethod'] == 'authenticate' &&
* strpos($_SERVER['REQUEST_URI'], '/rpc') &&
* ($realm = getenv('REALM'))) {
* // If this was realm'ed RPC request, pick the correct server
* // from IMP's backend configuration. Assuming that the used
* // realms match backend keys.
* $result['credentials']['server'] = $realm;
* }
* return $result;
* }
* </code>
*
* @param string $base The base part of the URL.
* @param string $user The user part of the URL.
* @param string $resource The resource part of the URL.
*/
// public function caldav_url($base, $user, $resource)
// {
// // Example 1: return unaltered
// //return $base . '/' . $user . '/' . $resource;
//
// // Example 2: append realm to user name
// $server = $GLOBALS['registry']->mail->server();
// return $base . '/' . $user . '@' . $server['hostspec'] . '/' . $resource;
// }

}
1 change: 0 additions & 1 deletion kronolith/docs/CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ v4.3.0-git
[mjr] Enforce case on attendee user part, but add attendee to event if only
only the case differs (Bug #13905).
[jan] Keep original file names when PUTing events via WebDAV.
[jan] Add hook to customize CalDAV URLs.
[jan] Remove configuration options for database tables.
[mjr] Honor the UID value sent from EAS clients directly in the message
structure.
Expand Down
9 changes: 1 addition & 8 deletions kronolith/docs/UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ configurations and database schemes. Log in as an administrator, go to
Administration => Configuration and update anything that's highlighted as
outdated.


Upgrading Kronolith from 4.x to 5.x
===================================

Expand All @@ -58,14 +59,6 @@ Resources are now share-based and no longer require an explicit driver
selection. The configuration options have been changed to reflect this.


Hooks (hooks.php)
-----------------

The following hooks have been added::

caldav_url


Upgrading Kronolith from 2.3.x to 3.x
=====================================

Expand Down
Loading

0 comments on commit 4b6001d

Please sign in to comment.