/**
 * Обработчик системы безопасности, встраивается в стек обработки запросов и
 * контролирует процесс создания контекста безопасности регистрирует в запросе
 * сервис с именем session.
 * 
 * Для получения и создания контекста безопасности используется
 * SecurityAuthority которое отвечает за механизмы проверки подлинности и
 * доверенность полученной сессии, по сути SecurityAuthority реализует протокол
 * безопасности.
 * 
 * При первом доступе к сервисам возможна прозрачная аутентификация, при этом
 * создается новая сессия, для ее создания используется IdentityProvider.
 * IdentityProvider - внешний модуль аутентификации, который по требованию
 * предоставляет идентификатор пользователя, используя собственные механизмы.
 * 
 * После получения данных аутентификации от IdentityProvider они используются в
 * SecurityAuthority для создания сессии.
 * 
 * Многоэтапная аутентификация сессии - случай пока чисто теоретический, оданко,
 * в случае необходимости SecurityAuthtority вызывает исключение при получении
 * сесии, если требуется следующий этап аутентификации сессии, данное исключение
 * прерывает текущую обработку запроса и попадает в обработчик
 * SecurityAuthority.handleError который в свою очередь формирует ответ сервера
 * для продолжения аутентификации.
 */
define([ "dojo/_base/declare", "dojo/when"],
    function(declare, when) {
        
        return declare(null, {
            constructor : function(/*options*/) {
            },
            
            /**
             * Точка входа в обработчик, вызывается инфраструктурой при
             * обработке запроса.
             * 
             * @req Текущий запрос.
             * @next Следующий обработчик в цепочке, вызывается когда сессия уже
             *       зарегистрирована в локаторе.
             * @async
             */
            invoke : function(req, next) {
                let authority = req.getService("securityAuthority");
                return when(next(), function(resp) {
                    if (authority)
                        return authority.completeRequest(resp);
                    return resp;
                }, function(err) {
                    if (authority)
                        return authority.handleError(err);
                    else
                        throw err;
                });
            }
        });
    });
