锻造车间 - 日历共享
在过去的几个月里,我们探讨了 iCalendar 标准以及它允许我们创建自己的日历和使用远程日历的方式。
但是,如果您稍微思考一下,您会意识到我们缺少一个关键的功能。我们已经了解了创建本地日历有多么容易。我们已经了解了如何检索远程日历。我们甚至已经了解了如何创建和分发远程日历,从 Web/数据库应用程序动态生成事件。但是我们从未考虑过 Sunbird 的个人用户如何才能与其他人共享他或她的日历。
任何在即使是中型组织工作过的人都知道,安排预约可能很困难。能够访问每个人的日历并为他们安排会议,对于我们的软件来说是一项越来越有用的功能。如果我对日历所做的每一项更改都对所有人可见,那么他们就更容易在我有空时安排会议。(或者如果他们想对我保密,就在我没空的时候安排。)我过去常常问客户,鉴于有优秀的开源替代品,他们为什么要使用 Microsoft Exchange 作为邮件服务器;不可避免地,答案更多与 Outlook 和 Exchange 中的日历支持有关,而不是电子邮件功能。
本月,我们结束对 Sunbird 和 iCalendar 的探索,着眼于如何将日历发布到中央存储库以供他人共享。结果可能不如某些商业替代品那样流畅或顺畅,但与开源世界的许多其他类型的软件一样,我相信这种情况正在迅速改变,我们很快就会看到与专有产品同等或更优秀的开源日历服务器。
在我们尝试共享日历之前,我们应该准确定义共享的含义。您可能会认为共享日历存储在一个地方,并由多个日历程序同时访问。虽然理论上可以在 Sunbird 或任何其他 iCalendar 兼容程序(例如 Evolution)中以这种方式进行配置,但这并不是我们通常期望的方式。
基本上,iCalendar 世界中的共享日历是一个 iCalendar 文件,可以从公共可访问的服务器检索。该 iCalendar 文件可能每小时更新一次或每年更新一次;就像 RSS 源或博客一样,无法知道特定日历文件可能更新的频率。因此,我们需要做出几个假设:1) 每个对这个特定日历感兴趣的人都订阅了它;2) 每个订阅者定期下载日历的更新版本,至少每天一次;3) 日历管理器在做出所有更改和更新后立即将其发布到公共服务器。
换句话说,共享根本不是实时发生的,而是取决于所有参与用户定期发布和检索更新。在更新之间,日历用户只能看到最近下载的 iCalendar 文件,该文件存储在他或她的本地计算机上。如果日历订阅者计划每天只检索一次更新,那么他或她很可能会错过日历的最后一分钟更新。某人应该多久订阅一次日历更新取决于组织的性质、获取更新的重要性以及可能给服务器带来的负载。毕竟,一台可以为 100 人提供每日更新的服务器可能难以向 10,000 人提供每小时更新。
在 Web 上发布文件的最简单方法是使用旧的文件传输标准 FTP。FTP 在我的服务器上几乎已经有一段时间没有使用了,这在很大程度上是出于安全考虑,但是如果您正在处理一个受到适当保护的系统,或者如果您不想使用 WebDAV(如下所述),FTP 是一种可行且简单的共享 Web 日历的方式。
在我的服务器上,运行 ProFTPd,我决定创建一个新用户 (calendar) 并设置密码 (cal4atf)。为了确保此用户不能用于远程登录或其他恶意行为,我想给它一个 /sbin/nologin 或许是 /bin/false 的 shell——这两个程序都只是简单地退出,而不会给恶意用户任何机会登录并利用我的系统。这种方法的问题在于,FTP 服务器只允许其 shell 在 /etc/shells 中的用户登录。这给我们带来了一些困境。我们想给日历用户一个非交互式 shell,但我们也希望用户能够使用 FTP。但是,将 /sbin/nlogin 添加到 /etc/shells 可能会在我们的系统上打开一个安全漏洞。一个简单的解决方案是将 /sbin/nologin 复制到 /sbin/nologin-but-yesftp,并在 /etc/shells 中添加一行,其中包含后者的 shell 名称。
通常,通过 FTP 登录的非匿名用户会看到他们自己的主目录。默认情况下,ProFTPd 更进一步,禁止用户超出他们自己的主目录。因此,我们可以放心,即使恶意用户获得了我们的日历用户名和密码,他或她最坏的情况也只能破坏或修改我们的日历文件。这显然不是我们想要鼓励的事情,在生产环境中,您无疑会想要更好的安全性——例如,为每个人提供唯一的用户名和密码。但是对于这个简单的演示,我们将继续使用我们的单个日历用户,知道安全漏洞很可能会带走我们的共享日历文件。
假设我们已经正确配置了 FTP,我们如何发布我们的日历?在 Sunbird 中,我们选择我们要发布的日历,默认情况下称为“我的日历”。会弹出一个菜单,最后一个选项是“发布整个日历”。如果您选择此选项,将打开一个小对话框,询问您打算将日历发布到的 URL。
不用说,URL 将以 ftp:// 开头,但之后是什么呢?假设用户名和密码与我们上面指示的一样,并且服务器是 calendar.lerner.co.il,我们可以使用 ftp://calendar:cal4atf@calendar.lerner.co.il/calendar.ics 访问它。
如您所见,我们用冒号分隔用户名和密码,然后在密码和服务器名称之间放置一个 @ 符号。服务器之后是我们想要保存的文件名。虽然理论上它可以有任何名称或后缀,但 .ics 后缀被认为是相当标准的,并确保所有涉及的程序都将理解 MIME 类型。
现在,假设我对我的日历进行了更改。我现在必须手动将其上传到服务器,再次执行相同的过程吗?不,有一种方法可以解决这个问题。单击日历的名称以获取您已经看到的相同菜单。不要选择“发布整个日历”,而是选择“编辑日历”。这将打开一个对话框,其中包括一个文本字段,您可以在其中输入 URL,以及一个复选框,指示每当进行更改时都应发布日历。我使用此功能的结果好坏参半,尽管它通常比不工作的时候多,并且在保持我的约会在不同系统上同步方面做得很好。
订阅共享日历类似于发布日历。输入完整的 URL,包括用户名和密码,任何 iCalendar 兼容程序都应该检索并显示它。当然,我们已经设置好的配置要求程序可以处理 HTTP 身份验证。
FTP 对于某些任务来说很好,但它有许多缺点。首先,鉴于 FTP 的安全问题历史,您可能不想在您的计算机上运行 FTP 服务器。您也可能出于性能原因,或者因为您可以通过 SSL 加密传输,而更喜欢一切都通过 HTTP 运行。因此,出于各种原因,您可能需要考虑另一种替代方案:mod_dav。
DAV,或分布式创作和版本控制,使得在服务器上创建和修改文件成为可能,而不仅仅是检索和读取它们。也就是说,DAV 将 HTTP 变成了一个读写协议。DAV 已经存在多年,并且 Apache 1.x 和 2.x 的 mod_dav 模块也已经存在一段时间了。我仍然在我的主服务器上使用 Apache 1.x,但是为 Apache 2.x 安装和使用 mod_dav 应该同样容易。
首先,您需要下载 mod_dav(请参阅在线资源)。因为我已经使用 DSO(共享对象)功能编译了 Apache,所以我不需要从头开始重新编译它才能合并 mod_dav。我只需要告诉它在哪里找到 apxs,这是一个自动生成的 Perl 程序,它为 Apache 模块提供了编译所需的所有信息,而无需 Apache 源代码。解压缩 mod_dav 源代码后,我输入了
./configure --with-apxs=/usr/local/apache/bin/apxs
完成后,我编译并安装了 mod_dav
make make install
我仔细检查以确保我的 Apache 配置文件 httpd.conf 在make install提供的修改后仍然完好无损。之后,我配置 Apache 以包含一个新的命名虚拟服务器,我将其称为 davcal.lerner.co.il
<VirtualHost 69.55.225.93> ServerName davcal.lerner.co.il ServerAdmin calendar@lerner.co.il # Directory and file names not beginning with / # are relative to ServerRoot ServerRoot /usr/local/apache/v-sites/davcal.lerner.co.il DocumentRoot www ErrorLog logs/error-log CustomLog logs/access-log combined CustomLog logs/referer-log referer DAVLockDB DAVLock <Directory /usr/local/apache/v-sites/davcal.lerner.co.il/www/> DAV On <Limit PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK> AuthName "Calendar DAV access" AuthType basic AuthUserFile passwd Require user calendar </Limit> </Directory> </VirtualHost>
请注意上面配置部分中特定于 DAV 的指令。我已经设置了 DAV 锁定将驻留的位置,使用 DAVLockDB,显然是在 HTTP 可访问的 DocumentRoot 目录之外。然后我为一个特定目录打开 DAV,并将 DAV 访问限制为日历用户,密码在外部文件中指定。该密码文件也位于网站的根目录之外,使用标准的 htpasswd 程序创建和更新,默认情况下位于 /usr/local/apache/bin 中。
最后,请注意我们的 <Limit> 部分仅指定了对潜在危险请求的限制。相比之下,标准的 HTTP GET 请求不需要用户名或密码。如果您想让任何人订阅您的日历,但限制发布和修改日历文件的访问权限,这是一个很好的配置。如果这个日历要用于商业用途,您可能也希望限制对其的访问,或许可以为每个用户提供他或她自己的密码。
我们可以通过(再次)调出特定日历的“发布整个日历”对话框来发布此日历。这次,我们使用 HTTP URL,不指定用户名或密码:http:// davcal.lerner.co.il/calendar.ics。
这将日历发布到站点,正如您可以通过查看服务器上的相应目录来判断的那样。您可以类似地在每次日历更新时使用 WebDAV 发布日历,就像我们之前看到的那样。
最后,我们可以使用我们在前几个月中看到的相同技术来订阅此日历。从“文件”菜单中选择“订阅远程日历”,然后输入此日历文件的 URL。感谢 WebDAV 的魔力,我们甚至可以使用相同的 URL 来写入和读取文件。
尽管开源世界可能没有像 Microsoft Exchange 这样花哨的后端日历系统,但现有的解决方案更加灵活,并且对于大多数团队来说已经足够好。
我应该注意到,Sunbird 在发布和订阅方面似乎存在一些问题;如果不出意外,当文件上传时,在我 Sunbird 应用程序上列为私有的会议仍然以这种方式标记——并且当我使用不同的程序订阅日历时,它们仍然显示为私有。此外,Sunbird 在处理大型日历时仍然很慢;但是,Sunbird 开发人员已经注意到了这个问题,并可能在未来几个月内修复。
Novell 的 Hula 项目也承诺将推出一个新的服务器来处理 iCalendar 文件。自从 Novell 收购了 Ximian 和 SUSE 以来,Hula 是从该组合中出现的最受炒作的新项目之一。如果 Hula 确实包含 iCalendar 支持,我将很好奇它将如何在我在上面概述的 FTP 和 WebDAV 解决方案的基础上进行改进。在那之前,存在可行的解决方案,可以满足我自己的需求,以及许多其他希望相互协作的小型组织的需求。
本文的资源: /article/8323。
Reuven M. Lerner,一位长期的 Web/数据库顾问和开发人员,现在是西北大学学习科学项目的研究生。他的博客位于 altneuland.lerner.co.il,您可以通过 reuven@lerner.co.il 与他联系。