Рекомендации к построению Web-приложений на платформе Lotus Notes/Domino R6x

Источник: IBM

Введение

По моему мнению, грамотно построенное Web-приложение на платформе Lotus Notes позволяет пользователю выполнять лишь те действия, которые предусмотрел разработчик, - ничего более. В частности, в нем должны быть закрыты следующие возможности:

  • создать документы по непредусмотренным формам;
  • открыть неинтерфейсное представления или запустить поиск по непредусмотренным представлениям;
  • увидеть интерфейсные сообщения на разных языках, например, описания ошибок Web-сервера на английском языке в русскоязычном приложении и т. д.

Этой статьей я хотел бы поделиться своим опытом в разработке Web-приложений на платформе Lotus Notes. На примерах постараюсь показать последствия несоблюдения перечисленных требований и дать рекомендации, следуя которым вы сможете защитить ваши приложения от перечисленных проблем с тем, чтобы они стали качественнее.

Предлагаемые здесь решения выкристаллизовались в ходе практической работы коллектива программистов, создававших Web-приложение в рамках разработки СЭД БОСС-Референт v.3 (компания Аплана, группа компаний АйТи). Поэтому есть уверенность, что статья будет полезна как начинающим, так и опытным Web-разработчикам на платформе Lotus Notes.

Работа с непредусмотренными формами

Практически в любом Web-приложении, реализованном на платформе Lotus Notes, используются формы. В базе Lotus Notes у формы может быть включено свойство Default database form. Визуально такая форма помечена синей стрелочкой (рис.1)

Рис. 1.Пример Default-формы.

Бывают ситуации, когда это свойство реально необходимо для корректной работы приложения: default-форма нужна для открытия документов, не ассоциированных с имеющимися в базе данных формами

Браузер позволяет «достучаться» до default-формы следующими командами (все они описаны в help-базе Lotus Notes):

http://hostname/database/$defaultform?OpenForm
http://hostname/database/$defaultform?ReadForm
http://hostname/database/$defaultform?CreateDocument

Источники ошибок

Успешное выполнение первых двух команд - это проверка качества работы разработчика. Например, выполнение такого запроса на ресурсе www.lotus.com приведет к появлению предупреждения RESTRICTED AREA или вас молча перенаправят на предусмотренную страницу.

Таблица 1. Способы доступа к содержимому представлений, закрытых $$ViewTemplateDefault.

Команда Результат Условие
*по ACL >= Reader
http://hostname/database/ViewName/$first Откроется первый документ представления Если нет ограничений полями типа Readers
http://hostname/database/ViewName/$searchForm?SearchView Откроется стандартная форма поиска по данному представлению.
Запустив поиск, вы получите выборку документов.
Если нет ограничений полями типа Readers и база имеет Full-Text index
http://hostname/database/ViewName?SearchView&Query=*a* Отобразится выборка документов с латинской буквой “a” (для примера). Если нет ограничений полями типа Readers, и база имеет Full-Text index
http://hostname/database/ViewName?ReadViewEntries Отобразится содержимое представления в XML-виде.
http://hostname/database/ViewName?ReadDesign Команда не документирована. Отобразится дизайн представления в XML-виде.

Большую опасность несет последняя команда. Ее выполнение при некоторых условиях может очень сильно увеличить размер базы со всеми вытекающими отсюда последствиями. Рассмотрим эти условия.

  • Web-пользователи после авторизации или даже без нее имеют права создавать документы в базе через браузер (отзыв, вопрос, запись в гостевой книге и т. д.), т. е. при определенных условиях получают права Author на базу с привилегией создания документов;
  • Default-форма явно не скрыта от Web-браузеров на предпоследней закладке ее свойств и не имеет поля SaveOptions с итоговым значением 0.

Если при таких условиях кто-то надолго оставит в адресной строке браузера что-то вроде:

javascript: for(var i=1; i>0; i=1)
document.location.href='http://hostname/database.nsf/$defaultform?createdocument'

это приведет к значительному увеличению размера базы!!!.

Так, например, мне пришлось столкнуться с Web-каталогом продукции некой компании с такой ошибкой. Данные в приложение вносились из клиента Lotus Notes путем создания документов по default-форме. Эта форма задумывалась для использования только из толстого клиента администратором ресурса, поэтому разработчик, видимо, поленился или просто упустил скрытие формы от Web-браузеров и при этом не добавил в форму вычисляемое поле SaveOptions.

Созданные в клиенте Lotus Notes документы отображались в Web уже по другой форме - с корректно установленным SaveOptions. В приложении был раздел, где Web-пользователь по предусмотренной форме мог оставить отзыв о продукции компании, т. е. создать Lotus-документ с правами Author. В этой форме отзыва, разработчик добавил и проверку на корректность заполнения полей, и вычисляемое поле SaveOptions, т. е. сделал все, чтобы команда http://hostname/database/form?createdocument была не страшна. Но вот халатность с default-формой порождала серьезную «дыру».

Естественно, вышеописанная проблема может возникнуть при неправильном конфигурировании любых форм, необязательно default-формы. Более высокий риск применительно к default-форме связан с:

  1. более высокой вероятностью, что в приложении будет включено свойтство Default database form именно для одной из форм толстого клиента:
    • разработчику может быть поставлена задача дописать Web-интерфейс для уже существующего в компании Lotus Notes приложения;
    • разработчику может быть поставлена задача написать два интерфейса для нового приложения: из опыта предположу, что врядли он начнет с Web-интерфейса.
  2. двумя ошибочными решениями разработчиков:
    • никто из пользователей не знает имен или алиасов клиентских форм, явно не используемых Web-интерфейсом, поэтому их можно тщательно не конфигурировать;
    • Default-формой будут пользоваться лишь адекватные модераторы сайта из клиента Lotus Notes, именно поэтому скрытие default-формы от Web-браузеров и добавление вычисляемого поля SaveOptions выглядит, на их взгляд, некритичным.

Как показано выше, оба эти предположения не выдерживают критики.

Рекомендации по работе с формами

 

Привожу простые рекомендации, которым следовали специалисты компании Аплана Софтвер при разработке СЭД БОСС-Референт v.3.

  • По каждой базе необходимо принять принципиальное решение: давать Web-пользователям права Author с привилегией создания документов или реализовать изменения содержимого базы агентами от имени сервера. При первом решении потребуется тщательно конфигурировать формы: их видимость, наличие и содержимое иногда вычисляемых полей SaveOptions и т. д. Второе решение означает увеличение нагрузки на сервер из-за необходимости использовать агенты, а также усложнение использования полей типа Authors и Readers.
  • Не использовать формы там, где от них можно отказаться. Например, некоторые формы можно заменить страницами (Page).
  • Формы, которые не должны быть доступны пользователю Web-приложения, необходимо явно скрывать от Web-браузеров, устанавливая соответствующий параметр на предпоследней закладке свойств формы.
  • Лучше выключать свойство Default database form, если оно не используется.
  • Быть крайне осторожным с «временным храненением» в базе форм для отладки с именами Temp, Test, Untitled и т. д., которые должным образом не конфигурируются, так как их предполагается удалить в будущем.
  • Если для улучшения читабельности дизайна приложения Web-формы называются по определенному правилу, например Web_FormName, то нужно иметь в виду, что пользователи приложения могут вычислить имя формы в Lotus Notes-интерфейсе и, после получения права Author на базу, попытаться применить к ней Get-запрос вида http://hostname/database/form?createdocument.
  • Если Web-пользователи могут получить права Author с привилегией создания документов, то все доступные из Web формы в каждой такой базе должны иметь поле SaveOptions и/или механизм проверки на корректное заполнение обязательных полей. Облегчающие сервер JS-проверки на стороне тонкого клиента должны дублироваться «контрольной» серверной проверкой для предотвращения вмешательства в JS-код страницы. Например, если отсутствует проверка сервером, всегда можно «на лету» подчистить содержимое события onSubmit (см. рис. 2) и нарушить логику работы системы.

Рис. 2.Удаление JS-кода из обработчика события onSubmit формы.

Работа с непредусмотренными представлениями

Известно, что в Lotus Notes для изменения стандартного отображения представления в Web-приложении используются специальные формы с именами $$ViewTemplate for viewname и $$ViewTemplateDefault. Напомню, что эти формы помогают лишь кастомизировать вид представлений, генерируемый Domino Web-сервером по умолчанию, - на них нельзя рассчитывать, если нужно скрыть содержимое представлений!

Рекомендации по работе с формами

Предположим, в Web-приложении созданы четыре $$ViewTemplate-формы для четырех UI-представлений приложения. Все остальные служебные и вспомогательные представления закрыты формой $$ViewTemplateDefault, на которой поле $$ViewBody заменено статическим текстом «Нет доступа».

Приведу простые способы доступа к содержимому закрытых вспомогательных представлений (таблица 1).

Отсюда вывод: получить доступ к содержимому представлений, отображение которых кастомизировано специальными формами, легко, так как $$ViewTemplate-форма - это не средство управления доступом к данным, а лишь способ оформления приложения.

Тем не менее, использовать $$ViewTemplate-формы необходимо. Возможность открыть представление в стандартном исполнении HTTP-задачи (см. рис. 3) внутри законченного Web-приложения, говорит многое об аккуратности разработчика. Пользователь может разочароваться в качестве приложения, когда его озадачат непонятным содержимым страницы, непохожей по стилю на все остальные да еще и с англоязычными ссылками, хотя все приложение выполнено на русском языке. $$ViewTemplate-формы позволяют предотвратить доступ к представлениям в таком виде.

Рис. 3.Пример стандартного исполнения представления Web-сервером Domino.

Работа с непредусмотренными представлениями

Известно, что в Lotus Notes для изменения стандартного отображения представления в Web-приложении используются специальные формы с именами $$ViewTemplate for viewname и $$ViewTemplateDefault. Напомню, что эти формы помогают лишь кастомизировать вид представлений, генерируемый Domino Web-сервером по умолчанию, - на них нельзя рассчитывать, если нужно скрыть содержимое представлений!

Рекомендации по работе с формами

 

Предположим, в Web-приложении созданы четыре $$ViewTemplate-формы для четырех UI-представлений приложения. Все остальные служебные и вспомогательные представления закрыты формой $$ViewTemplateDefault, на которой поле $$ViewBody заменено статическим текстом «Нет доступа».

Приведу простые способы доступа к содержимому закрытых вспомогательных представлений (таблица 1).

Отсюда вывод: получить доступ к содержимому представлений, отображение которых кастомизировано специальными формами, легко, так как $$ViewTemplate-форма - это не средство управления доступом к данным, а лишь способ оформления приложения.

Тем не менее, использовать $$ViewTemplate-формы необходимо. Возможность открыть представление в стандартном исполнении HTTP-задачи (см. рис. 3) внутри законченного Web-приложения, говорит многое об аккуратности разработчика. Пользователь может разочароваться в качестве приложения, когда его озадачат непонятным содержимым страницы, непохожей по стилю на все остальные да еще и с англоязычными ссылками, хотя все приложение выполнено на русском языке. $$ViewTemplate-формы позволяют предотвратить доступ к представлениям в таком виде.

Рис. 3.Пример стандартного исполнения представления Web-сервером Domino.
Пример стандартного исполнения представления Web-сервером Domino. 

Рекомендации по использованию представлений и Template-форм

Рекомендации по использованию представлений и $$ViewTemplate-форм для создания Web-приложения в едином корпоративном стиле на платформе Lotus Notes выглядят так:

  • если представление не должно отображаться в Web, его необходимо скрыть от Web, используя соответствующие свойства представления. Редкое исключение составляют представления, у которых используется свойство Form formula;
  • если представление не скрыто от Web-браузеров на предпоследней закладке свойств, то для него должна быть предусмотрена $$ViewTemplate-форма. При этом не важно, используется это представление в интерфейсе приложения или выполняет служебные функции.

Эти два правила были приняты как стандарт при разработке СЭД Босс-Референт v. 3. Углубляясь в тему, опишу свой подход к использованию $$ViewTemplate-форм:

1. Для всех представлений, открытие которых через ?OpenView нежелательно, я использую $$ViewTemplateDefault, где вместо поля $$ViewBody оставляю сообщение о неправомерности действия. Полезно добавить в эту форму автоматическое перенаправление на стартовую страницу приложения.

2. Для каждого интерфейсного представления я делаю отдельную $$ViewTemplate for viewname форму. Как правило, содержимое $$ViewTemplate-форм интерфейсных представлений одинаково, поэтому его можно вынести в отдельную подформу и вставить в индивидуальные $$ViewTemplate-формы.

3. Чтобы не создавать множество одинаковых $$ViewTemplate for viewname, отличающихся лишь наименованием, можно указать их наименования в пределах одной формы как алиасы

4. Domino Designer ограничивает длину имени формы вместе с алиасами 256-ю байтами. Если случиться, что это ограничение не позволяет перечислить имена всех $$ViewTemplate-форм для каждого UI-представления, можно поступить двумя способами:

  • создать еще одну форму с нужной подформой и дописать необходимые имена форм здесь;
  • используя Lotus Script, прописать все имена $$ViewTemplate for viewname в поле $Title одного документа дизайна формы (см. рис. 4). Все тело формы будет находиться в подформе, так что можно не беспокоиться о потере содержимого $Title формы, имея в виду необходимость ее изменения в дальнейшем.

Рис. 4.Пример единой для 14 представлений $$ViewTemplate for viewname формы.

5. Аналогично нужно поступить и с Template-формами для поисковой формы и результатов поиска соответственно. Я всегда добавляю алиасами к $$ViewTemplateDefault еще два имени:

  • Имя $$Search - для предотвращения доступа к стандартной серой поисковой форме с помощью Get-запроса вида http://hostname/database/viewName/$searchForm?SearchView (см. рис. 5).

Рис. 5.Внешний вид формы поиска, генерируемой Domino Web-сервером.

  • Имя $$SearchTemplateDefault - для предотвращения поиска по непредусмотренным представлениям с помощью Get-запросов вида http://hostname/database/viewName?SearchView&Query="запрос" (см. рис. 6).

Рис. 6.Пример формы, блокирующей открытие и поиск по непредусмотренным представлениям.

Рекомендую делать это вне зависимости от того, будет ваша база иметь полнотекстовый индекс или нет. На выполнение этих действий вы потратите несколько минут, зато если возникнет необходимость проиндексировать базу для FullText-поиска в толстом клиенте, вы сможете сделать это, не беспокоясь об открывающейся возможности неправомерно использовать его на стороне тонкого клиента.

6. Если ваше Web-приложение должно давать возможность полнотекстового поиска по определенному представлению, рекомендую создавать индивидуальные формы $$SearchTemplate for viewname для каждого представления, по которому предполагается выполнять поиск - все аналогично $$ViewTemplate for viewname.

Использование кастомизированных форм отображения ошибок

Важный момент при построении Web-приложений на платформе Lotus Notes - создание кастомизированных форм для обработки ошибок. Обсудим использование специальных форм для обработки ошибок в масштабах базы данных, т. е. хранящихся непосредственно в приложении. В масштабах сервера эти формы настраиваются с помощью специальной базы Domino Web Server Configuration, но она в данной статье не затрагивается. Рассмотрим упомянутые формы поподробнее.

Имеющиеся ограничения

Как известно, существует четыре типа событий, ассоциированных со специальными Web-формами (таблица 2):

Таблица 2. Перечень событий и ассоциированных с ними специальных форм.

Событие Форма Комментарии
Успешное удаление $$ReturnDocumentDeleted Форма для кастомизации сообщения об успешном удалении. Может быть полезна лишь в простейших приложениях, где допустимо удаление документов Get-запросом вида http://hostname/database/viewname/key?deletedocument
Ошибка аутентификации $$ReturnAuthenticationFailure Форма для кастомизации сообщения о неуспешной аутентификации. В версиях Lotus Notes R5x/R6x существует ограничение в ее использовании: не работает при session-based аутентификации.
Ошибка авторизации $$ReturnAuthorizationFailure Форма для кастомизации сообщения о неуспешной авторизации. В версиях Lotus Notes R5x/R6x существует ограничение в ее использовании: не работает при session-based аутентификации.
Общая ошибка $$ReturnGeneralError Форма для кастомизации сообщения о всех других ошибках в Web-приложении. Эта форма доступна при session-based аутентификации и, по моему мнению, из одной только этой формы можно извлечь много пользы.

Рекомендации по работе с формами для отображения ошибок

Для простоты работы с выше описанными формами, я всегда создаю одну форму, выполненную в едином для всего Web-приложения стиле, которая имеет три имени специальных форм-ошибок (см. рис. 7):

Рис. 7.Пример формы, кастомизирующей сообщения об ошибках.

Использование такой формы имеет целый ряд преимуществ:

  • уже озвученный момент: позволяет выдержать единый корпоративный стиль во всем Web-приложении;
  • позволяет преобразовать сообщения об ошибках, отображаемые на языке сервера Lotus Domino, к языку всего Web-приложения;
  • позволяет добавить механизм автоматического перенаправления пользователя на стартовую страницу приложения, делая его более дружественным. К примеру, я знаком с ситуациями, когда после реструктуризации сайта компании, поисковики в течение определенного времени выдавали устаревшие ссылки. Благодаря предлагаемому решению пользователи, как минимум, будут перенаправляться на заглавную страницу обновленного сайта, где смогут увидеть новость о прошедших изменениях и добавить в Favorites новые корректные ссылки;
  • позволяет добавить обработчики ошибок, возникающих в Web-приложении. Поговорим об этом подробнее.

Если в настройках Domino сервера включено протоколирование HTTP-запросов в базу domlog.nsf, то, зачастую пользоваться этим не очень удобно: внутри log-документов нет текстового описания ошибки. И если разница между кодами ошибок 404 и 500 очевидна визуально, то вот понять причину общей, 500-й ошибки, затруднительно (см. рис. 8).

Конечно, для нахождения текстового описания ошибки можно заглянуть в базу Log.nsf, но это также не лучший вариант в плане удобства анализа ошибок в Web-приложении (см. рис. 9).

Поэтому я всегда добавляю в форму $$ReturnGeneralError механизм, который сохранит все доступные CGI-переменные и текстовое описание ошибки в отдельную базу - удобную для анализа ошибок приложения (см. рис.10).

Рис. 10.Пример формы $$ReturnGeneralError с механизмом сохранения информации об ошибке.

Наконец, хочу напомнить, что выше рассмотренные приемы кастомизации вида представлений, элементов поиска и уведомлений об ошибках, основанные на использовании специальных форм, требуют от разработчика внимательного конфигурирования и этих самых специальных форм для предотвращения создания по ним документов в базе.

Если брать за пример реализации на ресурсе www.lotus.com, то можно увидеть, что Get-запросы вида http://hostname/database/$$ViewTemplateDefault?ReadForm не оставлены разработчиками без внимания.

В заключение

Вполне возможно, кому-то мои рекомендации покажутся опциональными. Действительно, часто задача разработчика упрощается тем, что создаваемое Web-приложение планируется использовать внутри корпоративной сети, не открывая его во внешний мир. Здесь на первый план могут выйти требования к срокам, разнообразию и удобству функционала, - законченность деталей или внешний лоск менее важны, - не на продажу ведь.

Кто-то может возразить: «Ну и что плохого в том, что пользователь сможет открыть служебное представление в стандартном исполнении Domino Web-сервера?». Возможно, что ничего плохого. Это скорее вопрос культуры разработчика. Согласитесь, грустно видеть домашний сайт компании-разработчика ПО на платформе Lotus Notes, у которого открыто всё и вся. Сейчас бизнес выходит на такой уровень, когда заказчику не удастся объяснить, что «так и надо». Часто компании-покупатели имеют своих сильных Lotus-специалистов, которые обратят внимание на такое проявление небрежности. Существующий уровень конкуренции обязывает выдерживать высокое качество решений.

Поэтому если перед вами стоит задача создать действительно качественное решение, рекомендую учесть эти моменты и избавить себя от головной боли в будущем, тем более что вышеописанные приемы не требуют ни особых интеллектуальных усилий, ни существенных временных затрат и проверены опытом их применения в практике одной из ведущих компаний-разработчиков ПО на платформе Lotus Notes - ЗАО Аплана Софтвер ( www.aplana.com)


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=7122