//! \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