//! \addtogroup HTTPServer //! \~\file pihttpserverprotected.h //! \brief HTTP server with per-route access protection //! \~english HTTP server with per-route access protection //! \~russian HTTP-сервер с защитой маршрутов от неавторизованного доступа /* PIP - Platform Independent Primitives HTTP server with per-route access protection Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PIHTTPSERVERPROTECTED_H #define PIHTTPSERVERPROTECTED_H #include "pihttpserver.h" namespace PIHTTP { //! \~\ingroup HTTPServer //! \~\brief //! \~english Authentication result produced by a protected server for a single request. //! \~russian Результат аутентификации, создаваемый защищенным сервером для одного запроса. struct PIP_HTTP_SERVER_EXPORT AuthInfo { //! \~english Creates a result with the specified authorization state and user id. //! \~russian Создает результат с указанным состоянием авторизации и идентификатором пользователя. AuthInfo(bool a = false, int id = 0): authorized(a), user_id(id) {} //! \~english \c true if the request is allowed to reach the route handler. //! \~russian \c true, если запрос разрешено передать обработчику маршрута. bool authorized; //! \~english Id of the authenticated user as known by the application; \c 0 means //! "user is not identified" (e.g. single-user mode without a user table). //! \~russian Идентификатор аутентифицированного пользователя в нумерации приложения; //! \c 0 означает, что пользователь не идентифицирован (например, однопользовательский //! режим без таблицы пользователей). int user_id; }; }; // namespace PIHTTP //! \~\ingroup HTTPServer //! \~\brief //! \~english HTTP server with per-route access protection: protected routes run authentication //! before the handler and return a denial reply when the request is not authorized. //! \~russian HTTP-сервер с защитой маршрутов: для защищенных маршрутов перед обработчиком //! выполняется аутентификация, а при отказе возвращается ответ об отказе в доступе. class PIP_HTTP_SERVER_EXPORT PIHTTPServerProtected: public PIHTTPServer { PIOBJECT_SUBCLASS(PIHTTPServerProtected, PIHTTPServer) public: //! \~english Request handler for protected routes; receives the authentication result //! produced by \a authenticate(). //! \~russian Обработчик запроса для защищенных маршрутов; получает результат аутентификации, //! созданный \a authenticate(). using UserRequestFunction = std::function; //! \~english Registers a protected route: \a authenticate() is invoked before the handler; //! when \c AuthInfo::authorized is \c false the \a accessDeniedReply() is returned instead. //! \~russian Регистрирует защищенный маршрут: перед обработчиком вызывается \a authenticate(); //! при \c false в \c AuthInfo::authorized вместо ответа обработчика возвращается \a accessDeniedReply(). bool registerProtectedPath(const PIString & path, PIHTTP::Method method, UserRequestFunction functor); //! \~english Registers a protected route handler that does not receive the authentication result. //! \~russian Регистрирует обработчик защищенного маршрута, не получающий результат аутентификации. bool registerProtectedPath(const PIString & path, PIHTTP::Method method, RequestFunction functor); //! \~english Registers an object method as a protected route handler with the authentication result. //! \~russian Регистрирует метод объекта как обработчик защищенного маршрута с результатом аутентификации. template bool registerProtectedPath(const PIString & path, PIHTTP::Method method, T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &, const PIHTTP::AuthInfo &)) { return registerProtectedPath(path, method, [o, function](const PIHTTP::MessageConst & m, const PIHTTP::AuthInfo & info) { return (o->*function)(m, info); }); } //! \~english Registers an object method as a protected route handler. //! \~russian Регистрирует метод объекта как обработчик защищенного маршрута. template bool registerProtectedPath(const PIString & path, PIHTTP::Method method, T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) { return registerProtectedPath(path, method, [o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); }); } protected: //! \~english Authenticates a protected request; the result is passed to the route handler. //! Access is denied when \c AuthInfo::authorized is \c false. //! \~russian Аутентифицирует защищенный запрос; результат передается обработчику маршрута. //! Доступ запрещается, если в \c AuthInfo::authorized \c false. virtual PIHTTP::AuthInfo authenticate(const PIHTTP::MessageConst & request) = 0; //! \~english Reply produced when \a authenticate() denies access. Subclasses must //! override this method to produce a reply matching their authentication scheme //! (typically \c 401 Unauthorized with a \c WWW-Authenticate challenge header). //! \~russian Ответ, создаваемый при отказе \a authenticate(). Подклассы должны //! переопределить этот метод, чтобы вернуть ответ, соответствующий схеме аутентификации //! (как правило, \c 401 Unauthorized с заголовком-challenge \c WWW-Authenticate). virtual PIHTTP::MessageMutable accessDeniedReply(const PIHTTP::MessageConst & request) = 0; }; #endif // PIHTTPSERVERPROTECTED_H