122 lines
7.2 KiB
C++
122 lines
7.2 KiB
C++
//! \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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#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<PIHTTP::MessageMutable(const PIHTTP::MessageConst &, const PIHTTP::AuthInfo &)>;
|
||
|
||
//! \~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<typename T>
|
||
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<typename T>
|
||
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
|