add authentication service
This commit is contained in:
		
							
								
								
									
										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; | ||||
| 
 | ||||
| class AsyncJsonRequestWebHandler: public AsyncWebHandler { | ||||
| class AsyncJsonWebHandler: public AsyncWebHandler { | ||||
| 
 | ||||
|   private: | ||||
| 
 | ||||
|     String _uri; | ||||
|     WebRequestMethodComposite _method; | ||||
|     JsonRequestCallback _onRequest; | ||||
|     size_t _maxContentLength; | ||||
| 
 | ||||
|   protected: | ||||
|     String _uri; | ||||
| 
 | ||||
|   public: | ||||
| 
 | ||||
|     AsyncJsonRequestWebHandler() : | ||||
|       _uri(), | ||||
|     AsyncJsonWebHandler() :       | ||||
|       _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), | ||||
|       _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 setMethod(WebRequestMethodComposite method) { _method = method; } | ||||
| @@ -61,7 +62,9 @@ class AsyncJsonRequestWebHandler: public AsyncWebHandler { | ||||
|     virtual void handleRequest(AsyncWebServerRequest *request) override final { | ||||
|       // no request configured
 | ||||
|       if(!_onRequest) { | ||||
|         request->send(404); | ||||
|         Serial.print("No request callback was configured for endpoint: "); | ||||
|         Serial.println(_uri);            | ||||
|         request->send(500); | ||||
|         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> | ||||
|  | ||||
| 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)); | ||||
|  | ||||
|   // 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() {} | ||||
| @@ -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) { | ||||
|   AsyncJsonResponse * response = new AsyncJsonResponse(MAX_USERS_SIZE); | ||||
|   JsonObject jsonObject = response->getRoot();   | ||||
| @@ -132,36 +68,56 @@ void SecurityManager::begin() { | ||||
|   jwtHandler.setSecret(_jwtSecret); | ||||
| } | ||||
|  | ||||
| /* | ||||
| * TODO - VERIFY JWT IS CORRECT! | ||||
| */ | ||||
| Authentication SecurityManager::verify(String jwt) { | ||||
|   DynamicJsonDocument parsedJwt(MAX_JWT_SIZE); | ||||
|   jwtHandler.parseJWT(jwt, parsedJwt); | ||||
|   if (parsedJwt.is<JsonObject>()) { | ||||
|     String username = parsedJwt["username"]; | ||||
| Authentication SecurityManager::authenticateRequest(AsyncWebServerRequest *request) { | ||||
|   AsyncWebHeader* authorizationHeader = request->getHeader(AUTHORIZATION_HEADER); | ||||
|   if (authorizationHeader) { | ||||
|     String value = authorizationHeader->value(); | ||||
|     value.startsWith(AUTHORIZATION_HEADER_PREFIX); | ||||
|     value = value.substring(AUTHORIZATION_HEADER_PREFIX_LEN); | ||||
|     return authenticateJWT(value); | ||||
|   }   | ||||
|   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) { | ||||
|       if (_user.getUsername() == username){ | ||||
|         return Authentication::forUser(_user); | ||||
|       if (_user.getUsername() == username && validatePayload(parsedPayload, &_user)){ | ||||
|         return Authentication(_user); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return Authentication::notAuthenticated(); | ||||
|   return Authentication(); | ||||
| } | ||||
|  | ||||
| Authentication SecurityManager::authenticate(String username, String password) { | ||||
|   for (User _user : _users) { | ||||
|     if (_user.getUsername() == username && _user.getPassword() == password){ | ||||
|       return Authentication::forUser(_user); | ||||
|       return Authentication(_user); | ||||
|     } | ||||
|   } | ||||
|   return Authentication::notAuthenticated(); | ||||
|   return Authentication(); | ||||
| } | ||||
|  | ||||
| String SecurityManager::generateJWT(User user) { | ||||
|   DynamicJsonDocument _jsonDocument(MAX_JWT_SIZE);       | ||||
|   JsonObject jwt = _jsonDocument.to<JsonObject>(); | ||||
|   jwt["username"] = user.getUsername(); | ||||
|   jwt["role"] = user.getRole(); | ||||
|   return jwtHandler.buildJWT(jwt); | ||||
| inline void populateJWTPayload(JsonObject &payload, User *user) { | ||||
|   payload["username"] = user->getUsername(); | ||||
|   payload["role"] = user->getRole(); | ||||
| } | ||||
|  | ||||
| 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 USERS_PATH "/rest/users" | ||||
| #define AUTHENTICATE_PATH "/rest/authenticate" | ||||
| #define SIGN_IN_PATH "/rest/signIn" | ||||
| #define TEST_VERIFICATION_PATH "/rest/verification" | ||||
|  | ||||
| #define AUTHORIZATION_HEADER "Authorization" | ||||
| #define AUTHORIZATION_HEADER_PREFIX "Bearer " | ||||
| #define AUTHORIZATION_HEADER_PREFIX_LEN 7 | ||||
|  | ||||
| #define MAX_JWT_SIZE 128 | ||||
| #define MAX_SECURITY_MANAGER_SETTINGS_SIZE 512 | ||||
| #define SECURITY_MANAGER_MAX_USERS 5 | ||||
|  | ||||
| #define ANONYMOUS_USERNAME "_anonymous" | ||||
| #define ANONYMOUS_PASSWORD "" | ||||
| #define ANONYMOUS_ROLE "" | ||||
|  | ||||
| #define MAX_USERS_SIZE 1024 | ||||
|  | ||||
| class User { | ||||
| @@ -45,31 +42,27 @@ class User { | ||||
|     } | ||||
| }; | ||||
|  | ||||
| const User NOT_AUTHENTICATED = User(ANONYMOUS_USERNAME, ANONYMOUS_PASSWORD, ANONYMOUS_ROLE); | ||||
|  | ||||
| class Authentication { | ||||
|   private: | ||||
|     User _user; | ||||
|     User *_user; | ||||
|     boolean _authenticated; | ||||
|     Authentication(User user, boolean authenticated) : _user(user), _authenticated(authenticated) {} | ||||
|   public: | ||||
|     // NOOP | ||||
|     ~Authentication(){} | ||||
|     User& getUser() { | ||||
|     Authentication(User& user): _user(new User(user)), _authenticated(true) {} | ||||
|     Authentication() : _user(NULL), _authenticated(false) {}   | ||||
|     ~Authentication() { | ||||
|       if (_user != NULL){ | ||||
|         delete(_user); | ||||
|       }       | ||||
|     } | ||||
|     User* getUser() { | ||||
|       return _user; | ||||
|     } | ||||
|     bool isAuthenticated() { | ||||
|       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: | ||||
|  | ||||
| @@ -79,19 +72,19 @@ class SecurityManager :  public SettingsPersistence { | ||||
|     void begin(); | ||||
|  | ||||
|     /* | ||||
|     * Lookup the user by JWT | ||||
|     */ | ||||
|     Authentication verify(String jwt); | ||||
|  | ||||
|     /* | ||||
|     * Authenticate, returning the user if found. | ||||
|     * Authenticate, returning the user if found | ||||
|     */ | ||||
|     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 | ||||
|     */ | ||||
|     String generateJWT(User user); | ||||
|     String generateJWT(User *user); | ||||
|  | ||||
|   protected: | ||||
|  | ||||
| @@ -102,11 +95,6 @@ class SecurityManager :  public SettingsPersistence { | ||||
|     // jwt handler | ||||
|     ArduinoJsonJWT jwtHandler = ArduinoJsonJWT(DEFAULT_JWT_SECRET); | ||||
|  | ||||
|     // server instance | ||||
|     AsyncWebServer* _server; | ||||
|     AsyncJsonRequestWebHandler _signInRequestHandler; | ||||
|     AsyncJsonRequestWebHandler _testVerifiction; | ||||
|  | ||||
|     // access point settings | ||||
|     String _jwtSecret; | ||||
|     std::list<String> _roles; | ||||
| @@ -114,8 +102,17 @@ class SecurityManager :  public SettingsPersistence { | ||||
|  | ||||
|     // endpoint functions | ||||
|     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 | ||||
| @@ -4,13 +4,13 @@ | ||||
| #include <ESPAsyncWebServer.h> | ||||
| #include <FS.h> | ||||
| #include <ArduinoJson.h> | ||||
| #include <AsyncJsonRequestWebHandler.h> | ||||
| #include <AsyncJsonWebHandler.h> | ||||
| #include <AsyncArduinoJson6.h> | ||||
|  | ||||
| /** | ||||
| * 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 | ||||
| * AsyncJsonRequestWebHandler with a setter. | ||||
| * AsyncJsonWebHandler with a setter. | ||||
| */ | ||||
| #define MAX_SETTINGS_SIZE 1024 | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| #include <SettingsPersistence.h> | ||||
| #include <ESPAsyncWebServer.h> | ||||
| #include <ArduinoJson.h> | ||||
| #include <AsyncJsonRequestWebHandler.h> | ||||
| #include <AsyncJsonWebHandler.h> | ||||
| #include <AsyncArduinoJson6.h> | ||||
|  | ||||
| /* | ||||
| @@ -22,7 +22,7 @@ class SettingsService : public SettingsPersistence { | ||||
|  | ||||
| private: | ||||
|  | ||||
|   AsyncJsonRequestWebHandler _updateHandler; | ||||
|   AsyncJsonWebHandler _updateHandler; | ||||
|  | ||||
|   void fetchConfig(AsyncWebServerRequest *request){ | ||||
|     AsyncJsonResponse * response = new AsyncJsonResponse(MAX_SETTINGS_SIZE); | ||||
|   | ||||
| @@ -12,12 +12,12 @@ | ||||
| #include <ESPAsyncWebServer.h> | ||||
| #include <ArduinoJson.h> | ||||
| #include <AsyncArduinoJson6.h> | ||||
| #include <AsyncJsonRequestWebHandler.h> | ||||
| #include <AsyncJsonWebHandler.h> | ||||
|  | ||||
| /** | ||||
| * 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 | ||||
| * AsyncJsonRequestWebHandler with a setter. | ||||
| * AsyncJsonWebHandler with a setter. | ||||
| */ | ||||
| #define MAX_SETTINGS_SIZE 1024 | ||||
|  | ||||
| @@ -31,7 +31,7 @@ class SimpleService { | ||||
|  | ||||
| private: | ||||
|  | ||||
|   AsyncJsonRequestWebHandler _updateHandler; | ||||
|   AsyncJsonWebHandler _updateHandler; | ||||
|  | ||||
|   void fetchConfig(AsyncWebServerRequest *request){ | ||||
|     AsyncJsonResponse * response = new AsyncJsonResponse(MAX_SETTINGS_SIZE); | ||||
|   | ||||
							
								
								
									
										12
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/main.cpp
									
									
									
									
									
								
							| @@ -10,15 +10,18 @@ | ||||
| #endif | ||||
|  | ||||
| #include <FS.h> | ||||
|  | ||||
| #include <SecurityManager.h> | ||||
| #include <WiFiSettingsService.h> | ||||
| #include <WiFiStatus.h> | ||||
| #include <WiFiScanner.h> | ||||
| #include <APSettingsService.h> | ||||
| #include <NTPSettingsService.h> | ||||
| #include <NTPStatus.h> | ||||
| #include <OTASettingsService.h> | ||||
| #include <AuthenticationService.h> | ||||
| #include <WiFiScanner.h> | ||||
| #include <WiFiStatus.h> | ||||
| #include <NTPStatus.h> | ||||
| #include <APStatus.h> | ||||
| #include <SecurityManager.h> | ||||
|  | ||||
|  | ||||
| #define SERIAL_BAUD_RATE 115200 | ||||
|  | ||||
| @@ -30,6 +33,7 @@ WiFiSettingsService wifiSettingsService = WiFiSettingsService(&server, &SPIFFS); | ||||
| APSettingsService apSettingsService = APSettingsService(&server, &SPIFFS); | ||||
| NTPSettingsService ntpSettingsService = NTPSettingsService(&server, &SPIFFS); | ||||
| OTASettingsService otaSettingsService = OTASettingsService(&server, &SPIFFS); | ||||
| AuthenticationService authenticationService = AuthenticationService(&server, &securityManager); | ||||
|  | ||||
| WiFiScanner wifiScanner = WiFiScanner(&server); | ||||
| WiFiStatus wifiStatus = WiFiStatus(&server); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user