add authentication service
This commit is contained in:
parent
7817010533
commit
04e852f7d9
52
src/AsyncAuthJsonWebHandler.h
Normal file
52
src/AsyncAuthJsonWebHandler.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef AsyncAuthJsonWebHandler_H_
|
||||||
|
#define AsyncAuthJsonWebHandler_H_
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <AsyncJsonWebHandler.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <SecurityManager.h>
|
||||||
|
|
||||||
|
typedef std::function<void(AsyncWebServerRequest *request, JsonDocument &jsonDocument, Authentication &authentication)> AuthenticationJsonRequestCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extends AsyncJsonWebHandler with a wrapper which verifies the user is authenticated.
|
||||||
|
*
|
||||||
|
* TODO - Extend with role checking support, possibly with a callback to verify the user.
|
||||||
|
*/
|
||||||
|
class AsyncAuthJsonWebHandler: public AsyncJsonWebHandler {
|
||||||
|
|
||||||
|
private:
|
||||||
|
SecurityManager *_securityManager;
|
||||||
|
using AsyncJsonWebHandler::onRequest;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
AsyncAuthJsonWebHandler() :
|
||||||
|
AsyncJsonWebHandler(), _securityManager(NULL) {}
|
||||||
|
|
||||||
|
~AsyncAuthJsonWebHandler() {}
|
||||||
|
|
||||||
|
void setSecurityManager(SecurityManager *securityManager) {
|
||||||
|
_securityManager = securityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onRequest(AuthenticationJsonRequestCallback callback) {
|
||||||
|
AsyncJsonWebHandler::onRequest([this, callback](AsyncWebServerRequest *request, JsonDocument &jsonDocument) {
|
||||||
|
if(!_securityManager) {
|
||||||
|
Serial.print("Security manager not configured for endpoint: ");
|
||||||
|
Serial.println(_uri);
|
||||||
|
request->send(500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Authentication authentication = _securityManager->authenticateRequest(request);
|
||||||
|
if (!authentication.isAuthenticated()) {
|
||||||
|
request->send(401);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback(request, jsonDocument, authentication);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // end AsyncAuthJsonWebHandler_H_
|
@ -17,24 +17,25 @@
|
|||||||
|
|
||||||
typedef std::function<void(AsyncWebServerRequest *request, JsonDocument &jsonDocument)> JsonRequestCallback;
|
typedef std::function<void(AsyncWebServerRequest *request, JsonDocument &jsonDocument)> JsonRequestCallback;
|
||||||
|
|
||||||
class AsyncJsonRequestWebHandler: public AsyncWebHandler {
|
class AsyncJsonWebHandler: public AsyncWebHandler {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
String _uri;
|
|
||||||
WebRequestMethodComposite _method;
|
WebRequestMethodComposite _method;
|
||||||
JsonRequestCallback _onRequest;
|
JsonRequestCallback _onRequest;
|
||||||
size_t _maxContentLength;
|
size_t _maxContentLength;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
String _uri;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AsyncJsonRequestWebHandler() :
|
AsyncJsonWebHandler() :
|
||||||
_uri(),
|
|
||||||
_method(HTTP_POST|HTTP_PUT|HTTP_PATCH),
|
_method(HTTP_POST|HTTP_PUT|HTTP_PATCH),
|
||||||
_onRequest(NULL),
|
_onRequest(NULL),
|
||||||
_maxContentLength(ASYNC_JSON_REQUEST_DEFAULT_MAX_SIZE) {}
|
_maxContentLength(ASYNC_JSON_REQUEST_DEFAULT_MAX_SIZE),
|
||||||
|
_uri() {}
|
||||||
|
|
||||||
~AsyncJsonRequestWebHandler() {}
|
~AsyncJsonWebHandler() {}
|
||||||
|
|
||||||
void setUri(const String& uri) { _uri = uri; }
|
void setUri(const String& uri) { _uri = uri; }
|
||||||
void setMethod(WebRequestMethodComposite method) { _method = method; }
|
void setMethod(WebRequestMethodComposite method) { _method = method; }
|
||||||
@ -61,7 +62,9 @@ class AsyncJsonRequestWebHandler: public AsyncWebHandler {
|
|||||||
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
||||||
// no request configured
|
// no request configured
|
||||||
if(!_onRequest) {
|
if(!_onRequest) {
|
||||||
request->send(404);
|
Serial.print("No request callback was configured for endpoint: ");
|
||||||
|
Serial.println(_uri);
|
||||||
|
request->send(500);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
45
src/AuthenticationService.cpp
Normal file
45
src/AuthenticationService.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include <AuthenticationService.h>
|
||||||
|
|
||||||
|
AuthenticationService::AuthenticationService(AsyncWebServer* server, SecurityManager* securityManager):
|
||||||
|
_server(server), _securityManager(securityManager) {
|
||||||
|
server->on(VERIFY_AUTHORIZATION_PATH, HTTP_GET, std::bind(&AuthenticationService::verifyAuthorization, this, std::placeholders::_1));
|
||||||
|
|
||||||
|
_signInHandler.setUri(SIGN_IN_PATH);
|
||||||
|
_signInHandler.setMethod(HTTP_POST);
|
||||||
|
_signInHandler.setMaxContentLength(MAX_SECURITY_MANAGER_SETTINGS_SIZE);
|
||||||
|
_signInHandler.onRequest(std::bind(&AuthenticationService::signIn, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
server->addHandler(&_signInHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticationService::~AuthenticationService() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifys that the request supplied a valid JWT.
|
||||||
|
*/
|
||||||
|
void AuthenticationService::verifyAuthorization(AsyncWebServerRequest *request) {
|
||||||
|
Authentication authentication = _securityManager->authenticateRequest(request);
|
||||||
|
request->send(authentication.isAuthenticated() ? 200: 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signs in a user if the username and password match. Provides a JWT to be used in the Authorization header in subsequent requests.
|
||||||
|
*/
|
||||||
|
void AuthenticationService::signIn(AsyncWebServerRequest *request, JsonDocument &jsonDocument){
|
||||||
|
if (jsonDocument.is<JsonObject>()) {
|
||||||
|
String username = jsonDocument["username"];
|
||||||
|
String password = jsonDocument["password"];
|
||||||
|
Authentication authentication = _securityManager->authenticate(username, password);
|
||||||
|
if (authentication.isAuthenticated()) {
|
||||||
|
User* user = authentication.getUser();
|
||||||
|
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_USERS_SIZE);
|
||||||
|
JsonObject jsonObject = response->getRoot();
|
||||||
|
jsonObject["access_token"] = _securityManager->generateJWT(user);
|
||||||
|
response->setLength();
|
||||||
|
request->send(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AsyncWebServerResponse *response = request->beginResponse(401);
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
|
|
30
src/AuthenticationService.h
Normal file
30
src/AuthenticationService.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef AuthenticationService_H_
|
||||||
|
#define AuthenticationService_H_
|
||||||
|
|
||||||
|
#include <SecurityManager.h>
|
||||||
|
|
||||||
|
#define VERIFY_AUTHORIZATION_PATH "/rest/verifyAuthorization"
|
||||||
|
#define SIGN_IN_PATH "/rest/signIn"
|
||||||
|
|
||||||
|
#define MAX_AUTHENTICATION_SIZE 256
|
||||||
|
|
||||||
|
class AuthenticationService {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
AuthenticationService(AsyncWebServer* server, SecurityManager* securityManager) ;
|
||||||
|
~AuthenticationService();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// server instance
|
||||||
|
AsyncWebServer* _server;
|
||||||
|
SecurityManager* _securityManager;
|
||||||
|
AsyncJsonWebHandler _signInHandler;
|
||||||
|
|
||||||
|
// endpoint functions
|
||||||
|
void signIn(AsyncWebServerRequest *request, JsonDocument &jsonDocument);
|
||||||
|
void verifyAuthorization(AsyncWebServerRequest *request);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // end SecurityManager_h
|
@ -1,23 +1,7 @@
|
|||||||
#include <SecurityManager.h>
|
#include <SecurityManager.h>
|
||||||
|
|
||||||
SecurityManager::SecurityManager(AsyncWebServer* server, FS* fs) : SettingsPersistence(fs, SECURITY_SETTINGS_FILE) {
|
SecurityManager::SecurityManager(AsyncWebServer* server, FS* fs) : SettingsPersistence(fs, SECURITY_SETTINGS_FILE) {
|
||||||
// fetch users
|
|
||||||
server->on(USERS_PATH, HTTP_GET, std::bind(&SecurityManager::fetchUsers, this, std::placeholders::_1));
|
server->on(USERS_PATH, HTTP_GET, std::bind(&SecurityManager::fetchUsers, this, std::placeholders::_1));
|
||||||
|
|
||||||
// sign in request
|
|
||||||
_signInRequestHandler.setUri(SIGN_IN_PATH);
|
|
||||||
_signInRequestHandler.setMethod(HTTP_POST);
|
|
||||||
_signInRequestHandler.setMaxContentLength(MAX_SECURITY_MANAGER_SETTINGS_SIZE);
|
|
||||||
_signInRequestHandler.onRequest(std::bind(&SecurityManager::signIn, this, std::placeholders::_1, std::placeholders::_2));
|
|
||||||
server->addHandler(&_signInRequestHandler);
|
|
||||||
|
|
||||||
|
|
||||||
// sign in request
|
|
||||||
_testVerifiction.setUri(TEST_VERIFICATION_PATH);
|
|
||||||
_testVerifiction.setMethod(HTTP_POST);
|
|
||||||
_testVerifiction.setMaxContentLength(MAX_SECURITY_MANAGER_SETTINGS_SIZE);
|
|
||||||
_testVerifiction.onRequest(std::bind(&SecurityManager::testVerification, this, std::placeholders::_1, std::placeholders::_2));
|
|
||||||
server->addHandler(&_testVerifiction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityManager::~SecurityManager() {}
|
SecurityManager::~SecurityManager() {}
|
||||||
@ -68,54 +52,6 @@ void SecurityManager::writeToJsonObject(JsonObject& root) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - Decide about default role behaviour, don't over-engineer (multiple roles, boolean admin flag???).
|
|
||||||
void SecurityManager::signIn(AsyncWebServerRequest *request, JsonDocument &jsonDocument){
|
|
||||||
if (jsonDocument.is<JsonObject>()) {
|
|
||||||
// authenticate user
|
|
||||||
String username = jsonDocument["username"];
|
|
||||||
String password = jsonDocument["password"];
|
|
||||||
Authentication authentication = authenticate(username, password);
|
|
||||||
|
|
||||||
if (authentication.isAuthenticated()) {
|
|
||||||
User& user = authentication.getUser();
|
|
||||||
|
|
||||||
// create JWT
|
|
||||||
DynamicJsonDocument _jsonDocument(MAX_JWT_SIZE);
|
|
||||||
JsonObject jwt = _jsonDocument.to<JsonObject>();
|
|
||||||
jwt["username"] = user.getUsername();
|
|
||||||
jwt["role"] = user.getRole();
|
|
||||||
|
|
||||||
// send JWT response
|
|
||||||
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_USERS_SIZE);
|
|
||||||
JsonObject jsonObject = response->getRoot();
|
|
||||||
jsonObject["access_token"] = jwtHandler.buildJWT(jwt);
|
|
||||||
response->setLength();
|
|
||||||
request->send(response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// authentication failed
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(401);
|
|
||||||
request->send(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SecurityManager::testVerification(AsyncWebServerRequest *request, JsonDocument &jsonDocument){
|
|
||||||
if (jsonDocument.is<JsonObject>()) {
|
|
||||||
String accessToken = jsonDocument["access_token"];
|
|
||||||
DynamicJsonDocument parsedJwt(MAX_JWT_SIZE);
|
|
||||||
jwtHandler.parseJWT(accessToken, parsedJwt);
|
|
||||||
if (parsedJwt.is<JsonObject>()){
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(200);
|
|
||||||
request->send(response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// authentication failed
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(401);
|
|
||||||
request->send(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SecurityManager::fetchUsers(AsyncWebServerRequest *request) {
|
void SecurityManager::fetchUsers(AsyncWebServerRequest *request) {
|
||||||
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_USERS_SIZE);
|
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_USERS_SIZE);
|
||||||
JsonObject jsonObject = response->getRoot();
|
JsonObject jsonObject = response->getRoot();
|
||||||
@ -132,36 +68,56 @@ void SecurityManager::begin() {
|
|||||||
jwtHandler.setSecret(_jwtSecret);
|
jwtHandler.setSecret(_jwtSecret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
Authentication SecurityManager::authenticateRequest(AsyncWebServerRequest *request) {
|
||||||
* TODO - VERIFY JWT IS CORRECT!
|
AsyncWebHeader* authorizationHeader = request->getHeader(AUTHORIZATION_HEADER);
|
||||||
*/
|
if (authorizationHeader) {
|
||||||
Authentication SecurityManager::verify(String jwt) {
|
String value = authorizationHeader->value();
|
||||||
DynamicJsonDocument parsedJwt(MAX_JWT_SIZE);
|
value.startsWith(AUTHORIZATION_HEADER_PREFIX);
|
||||||
jwtHandler.parseJWT(jwt, parsedJwt);
|
value = value.substring(AUTHORIZATION_HEADER_PREFIX_LEN);
|
||||||
if (parsedJwt.is<JsonObject>()) {
|
return authenticateJWT(value);
|
||||||
String username = parsedJwt["username"];
|
}
|
||||||
|
return Authentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
Authentication SecurityManager::authenticateJWT(String jwt) {
|
||||||
|
DynamicJsonDocument payloadDocument(MAX_JWT_SIZE);
|
||||||
|
jwtHandler.parseJWT(jwt, payloadDocument);
|
||||||
|
if (payloadDocument.is<JsonObject>()) {
|
||||||
|
JsonObject parsedPayload = payloadDocument.as<JsonObject>();
|
||||||
|
String username = parsedPayload["username"];
|
||||||
for (User _user : _users) {
|
for (User _user : _users) {
|
||||||
if (_user.getUsername() == username){
|
if (_user.getUsername() == username && validatePayload(parsedPayload, &_user)){
|
||||||
return Authentication::forUser(_user);
|
return Authentication(_user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Authentication::notAuthenticated();
|
return Authentication();
|
||||||
}
|
}
|
||||||
|
|
||||||
Authentication SecurityManager::authenticate(String username, String password) {
|
Authentication SecurityManager::authenticate(String username, String password) {
|
||||||
for (User _user : _users) {
|
for (User _user : _users) {
|
||||||
if (_user.getUsername() == username && _user.getPassword() == password){
|
if (_user.getUsername() == username && _user.getPassword() == password){
|
||||||
return Authentication::forUser(_user);
|
return Authentication(_user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Authentication::notAuthenticated();
|
return Authentication();
|
||||||
}
|
}
|
||||||
|
|
||||||
String SecurityManager::generateJWT(User user) {
|
inline void populateJWTPayload(JsonObject &payload, User *user) {
|
||||||
DynamicJsonDocument _jsonDocument(MAX_JWT_SIZE);
|
payload["username"] = user->getUsername();
|
||||||
JsonObject jwt = _jsonDocument.to<JsonObject>();
|
payload["role"] = user->getRole();
|
||||||
jwt["username"] = user.getUsername();
|
}
|
||||||
jwt["role"] = user.getRole();
|
|
||||||
return jwtHandler.buildJWT(jwt);
|
boolean SecurityManager::validatePayload(JsonObject &parsedPayload, User *user) {
|
||||||
|
DynamicJsonDocument _jsonDocument(MAX_JWT_SIZE);
|
||||||
|
JsonObject payload = _jsonDocument.to<JsonObject>();
|
||||||
|
populateJWTPayload(payload, user);
|
||||||
|
return payload == parsedPayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
String SecurityManager::generateJWT(User *user) {
|
||||||
|
DynamicJsonDocument _jsonDocument(MAX_JWT_SIZE);
|
||||||
|
JsonObject payload = _jsonDocument.to<JsonObject>();
|
||||||
|
populateJWTPayload(payload, user);
|
||||||
|
return jwtHandler.buildJWT(payload);
|
||||||
}
|
}
|
||||||
|
@ -13,18 +13,15 @@
|
|||||||
#define SECURITY_SETTINGS_FILE "/config/securitySettings.json"
|
#define SECURITY_SETTINGS_FILE "/config/securitySettings.json"
|
||||||
|
|
||||||
#define USERS_PATH "/rest/users"
|
#define USERS_PATH "/rest/users"
|
||||||
#define AUTHENTICATE_PATH "/rest/authenticate"
|
|
||||||
#define SIGN_IN_PATH "/rest/signIn"
|
#define AUTHORIZATION_HEADER "Authorization"
|
||||||
#define TEST_VERIFICATION_PATH "/rest/verification"
|
#define AUTHORIZATION_HEADER_PREFIX "Bearer "
|
||||||
|
#define AUTHORIZATION_HEADER_PREFIX_LEN 7
|
||||||
|
|
||||||
#define MAX_JWT_SIZE 128
|
#define MAX_JWT_SIZE 128
|
||||||
#define MAX_SECURITY_MANAGER_SETTINGS_SIZE 512
|
#define MAX_SECURITY_MANAGER_SETTINGS_SIZE 512
|
||||||
#define SECURITY_MANAGER_MAX_USERS 5
|
#define SECURITY_MANAGER_MAX_USERS 5
|
||||||
|
|
||||||
#define ANONYMOUS_USERNAME "_anonymous"
|
|
||||||
#define ANONYMOUS_PASSWORD ""
|
|
||||||
#define ANONYMOUS_ROLE ""
|
|
||||||
|
|
||||||
#define MAX_USERS_SIZE 1024
|
#define MAX_USERS_SIZE 1024
|
||||||
|
|
||||||
class User {
|
class User {
|
||||||
@ -45,31 +42,27 @@ class User {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const User NOT_AUTHENTICATED = User(ANONYMOUS_USERNAME, ANONYMOUS_PASSWORD, ANONYMOUS_ROLE);
|
|
||||||
|
|
||||||
class Authentication {
|
class Authentication {
|
||||||
private:
|
private:
|
||||||
User _user;
|
User *_user;
|
||||||
boolean _authenticated;
|
boolean _authenticated;
|
||||||
Authentication(User user, boolean authenticated) : _user(user), _authenticated(authenticated) {}
|
|
||||||
public:
|
public:
|
||||||
// NOOP
|
Authentication(User& user): _user(new User(user)), _authenticated(true) {}
|
||||||
~Authentication(){}
|
Authentication() : _user(NULL), _authenticated(false) {}
|
||||||
User& getUser() {
|
~Authentication() {
|
||||||
|
if (_user != NULL){
|
||||||
|
delete(_user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
User* getUser() {
|
||||||
return _user;
|
return _user;
|
||||||
}
|
}
|
||||||
bool isAuthenticated() {
|
bool isAuthenticated() {
|
||||||
return _authenticated;
|
return _authenticated;
|
||||||
}
|
}
|
||||||
static Authentication forUser(User user){
|
|
||||||
return Authentication(user, true);
|
|
||||||
}
|
|
||||||
static Authentication notAuthenticated(){
|
|
||||||
return Authentication(NOT_AUTHENTICATED, false);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SecurityManager : public SettingsPersistence {
|
class SecurityManager : public SettingsPersistence {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -79,19 +72,19 @@ class SecurityManager : public SettingsPersistence {
|
|||||||
void begin();
|
void begin();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup the user by JWT
|
* Authenticate, returning the user if found
|
||||||
*/
|
|
||||||
Authentication verify(String jwt);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Authenticate, returning the user if found.
|
|
||||||
*/
|
*/
|
||||||
Authentication authenticate(String username, String password);
|
Authentication authenticate(String username, String password);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the request header for the Authorization token
|
||||||
|
*/
|
||||||
|
Authentication authenticateRequest(AsyncWebServerRequest *request);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate a JWT for the user provided
|
* Generate a JWT for the user provided
|
||||||
*/
|
*/
|
||||||
String generateJWT(User user);
|
String generateJWT(User *user);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -102,11 +95,6 @@ class SecurityManager : public SettingsPersistence {
|
|||||||
// jwt handler
|
// jwt handler
|
||||||
ArduinoJsonJWT jwtHandler = ArduinoJsonJWT(DEFAULT_JWT_SECRET);
|
ArduinoJsonJWT jwtHandler = ArduinoJsonJWT(DEFAULT_JWT_SECRET);
|
||||||
|
|
||||||
// server instance
|
|
||||||
AsyncWebServer* _server;
|
|
||||||
AsyncJsonRequestWebHandler _signInRequestHandler;
|
|
||||||
AsyncJsonRequestWebHandler _testVerifiction;
|
|
||||||
|
|
||||||
// access point settings
|
// access point settings
|
||||||
String _jwtSecret;
|
String _jwtSecret;
|
||||||
std::list<String> _roles;
|
std::list<String> _roles;
|
||||||
@ -114,8 +102,17 @@ class SecurityManager : public SettingsPersistence {
|
|||||||
|
|
||||||
// endpoint functions
|
// endpoint functions
|
||||||
void fetchUsers(AsyncWebServerRequest *request);
|
void fetchUsers(AsyncWebServerRequest *request);
|
||||||
void signIn(AsyncWebServerRequest *request, JsonDocument &jsonDocument);
|
|
||||||
void testVerification(AsyncWebServerRequest *request, JsonDocument &jsonDocument);
|
/*
|
||||||
|
* Lookup the user by JWT
|
||||||
|
*/
|
||||||
|
Authentication authenticateJWT(String jwt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify the payload is correct
|
||||||
|
*/
|
||||||
|
boolean validatePayload(JsonObject &parsedPayload, User *user);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // end SecurityManager_h
|
#endif // end SecurityManager_h
|
@ -4,13 +4,13 @@
|
|||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <AsyncJsonRequestWebHandler.h>
|
#include <AsyncJsonWebHandler.h>
|
||||||
#include <AsyncArduinoJson6.h>
|
#include <AsyncArduinoJson6.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* At the moment, not expecting settings service to have to deal with large JSON
|
* At the moment, not expecting settings service to have to deal with large JSON
|
||||||
* files this could be made configurable fairly simply, it's exposed on
|
* files this could be made configurable fairly simply, it's exposed on
|
||||||
* AsyncJsonRequestWebHandler with a setter.
|
* AsyncJsonWebHandler with a setter.
|
||||||
*/
|
*/
|
||||||
#define MAX_SETTINGS_SIZE 1024
|
#define MAX_SETTINGS_SIZE 1024
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <SettingsPersistence.h>
|
#include <SettingsPersistence.h>
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <AsyncJsonRequestWebHandler.h>
|
#include <AsyncJsonWebHandler.h>
|
||||||
#include <AsyncArduinoJson6.h>
|
#include <AsyncArduinoJson6.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -22,7 +22,7 @@ class SettingsService : public SettingsPersistence {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AsyncJsonRequestWebHandler _updateHandler;
|
AsyncJsonWebHandler _updateHandler;
|
||||||
|
|
||||||
void fetchConfig(AsyncWebServerRequest *request){
|
void fetchConfig(AsyncWebServerRequest *request){
|
||||||
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_SETTINGS_SIZE);
|
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_SETTINGS_SIZE);
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <AsyncArduinoJson6.h>
|
#include <AsyncArduinoJson6.h>
|
||||||
#include <AsyncJsonRequestWebHandler.h>
|
#include <AsyncJsonWebHandler.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* At the moment, not expecting services to have to deal with large JSON
|
* At the moment, not expecting services to have to deal with large JSON
|
||||||
* files this could be made configurable fairly simply, it's exposed on
|
* files this could be made configurable fairly simply, it's exposed on
|
||||||
* AsyncJsonRequestWebHandler with a setter.
|
* AsyncJsonWebHandler with a setter.
|
||||||
*/
|
*/
|
||||||
#define MAX_SETTINGS_SIZE 1024
|
#define MAX_SETTINGS_SIZE 1024
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class SimpleService {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AsyncJsonRequestWebHandler _updateHandler;
|
AsyncJsonWebHandler _updateHandler;
|
||||||
|
|
||||||
void fetchConfig(AsyncWebServerRequest *request){
|
void fetchConfig(AsyncWebServerRequest *request){
|
||||||
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_SETTINGS_SIZE);
|
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_SETTINGS_SIZE);
|
||||||
|
12
src/main.cpp
12
src/main.cpp
@ -10,15 +10,18 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
|
|
||||||
|
#include <SecurityManager.h>
|
||||||
#include <WiFiSettingsService.h>
|
#include <WiFiSettingsService.h>
|
||||||
#include <WiFiStatus.h>
|
|
||||||
#include <WiFiScanner.h>
|
|
||||||
#include <APSettingsService.h>
|
#include <APSettingsService.h>
|
||||||
#include <NTPSettingsService.h>
|
#include <NTPSettingsService.h>
|
||||||
#include <NTPStatus.h>
|
|
||||||
#include <OTASettingsService.h>
|
#include <OTASettingsService.h>
|
||||||
|
#include <AuthenticationService.h>
|
||||||
|
#include <WiFiScanner.h>
|
||||||
|
#include <WiFiStatus.h>
|
||||||
|
#include <NTPStatus.h>
|
||||||
#include <APStatus.h>
|
#include <APStatus.h>
|
||||||
#include <SecurityManager.h>
|
|
||||||
|
|
||||||
#define SERIAL_BAUD_RATE 115200
|
#define SERIAL_BAUD_RATE 115200
|
||||||
|
|
||||||
@ -30,6 +33,7 @@ WiFiSettingsService wifiSettingsService = WiFiSettingsService(&server, &SPIFFS);
|
|||||||
APSettingsService apSettingsService = APSettingsService(&server, &SPIFFS);
|
APSettingsService apSettingsService = APSettingsService(&server, &SPIFFS);
|
||||||
NTPSettingsService ntpSettingsService = NTPSettingsService(&server, &SPIFFS);
|
NTPSettingsService ntpSettingsService = NTPSettingsService(&server, &SPIFFS);
|
||||||
OTASettingsService otaSettingsService = OTASettingsService(&server, &SPIFFS);
|
OTASettingsService otaSettingsService = OTASettingsService(&server, &SPIFFS);
|
||||||
|
AuthenticationService authenticationService = AuthenticationService(&server, &securityManager);
|
||||||
|
|
||||||
WiFiScanner wifiScanner = WiFiScanner(&server);
|
WiFiScanner wifiScanner = WiFiScanner(&server);
|
||||||
WiFiStatus wifiStatus = WiFiStatus(&server);
|
WiFiStatus wifiStatus = WiFiStatus(&server);
|
||||||
|
Loading…
Reference in New Issue
Block a user