Fork of the excellent esp8266-react - https://github.com/rjwats/esp8266-react
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.8 KiB

  1. #ifndef SecuritySettingsService_h
  2. #define SecuritySettingsService_h
  3. #include <SecurityManager.h>
  4. #include <HttpEndpoint.h>
  5. #include <FSPersistence.h>
  6. #ifndef FACTORY_ADMIN_USERNAME
  7. #define FACTORY_ADMIN_USERNAME "admin"
  8. #endif
  9. #ifndef FACTORY_ADMIN_PASSWORD
  10. #define FACTORY_ADMIN_PASSWORD "admin"
  11. #endif
  12. #ifndef FACTORY_GUEST_USERNAME
  13. #define FACTORY_GUEST_USERNAME "guest"
  14. #endif
  15. #ifndef FACTORY_GUEST_PASSWORD
  16. #define FACTORY_GUEST_PASSWORD "guest"
  17. #endif
  18. #define SECURITY_SETTINGS_FILE "/config/securitySettings.json"
  19. #define SECURITY_SETTINGS_PATH "/rest/securitySettings"
  20. class SecuritySettings {
  21. public:
  22. String jwtSecret;
  23. std::list<User> users;
  24. static void read(SecuritySettings& settings, JsonObject& root) {
  25. // secret
  26. root["jwt_secret"] = settings.jwtSecret;
  27. // users
  28. JsonArray users = root.createNestedArray("users");
  29. for (User user : settings.users) {
  30. JsonObject userRoot = users.createNestedObject();
  31. userRoot["username"] = user.username;
  32. userRoot["password"] = user.password;
  33. userRoot["admin"] = user.admin;
  34. }
  35. }
  36. static StateUpdateResult update(JsonObject& root, SecuritySettings& settings) {
  37. // secret
  38. settings.jwtSecret = root["jwt_secret"] | FACTORY_JWT_SECRET;
  39. // users
  40. settings.users.clear();
  41. if (root["users"].is<JsonArray>()) {
  42. for (JsonVariant user : root["users"].as<JsonArray>()) {
  43. settings.users.push_back(User(user["username"], user["password"], user["admin"]));
  44. }
  45. } else {
  46. settings.users.push_back(User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true));
  47. settings.users.push_back(User(FACTORY_GUEST_USERNAME, FACTORY_GUEST_PASSWORD, false));
  48. }
  49. return StateUpdateResult::CHANGED;
  50. }
  51. };
  52. class SecuritySettingsService : public StatefulService<SecuritySettings>, public SecurityManager {
  53. public:
  54. SecuritySettingsService(AsyncWebServer* server, FS* fs);
  55. void begin();
  56. // Functions to implement SecurityManager
  57. Authentication authenticate(const String& username, const String& password);
  58. Authentication authenticateRequest(AsyncWebServerRequest* request);
  59. String generateJWT(User* user);
  60. ArRequestFilterFunction filterRequest(AuthenticationPredicate predicate);
  61. ArRequestHandlerFunction wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate);
  62. ArJsonRequestHandlerFunction wrapCallback(ArJsonRequestHandlerFunction callback, AuthenticationPredicate predicate);
  63. private:
  64. HttpEndpoint<SecuritySettings> _httpEndpoint;
  65. FSPersistence<SecuritySettings> _fsPersistence;
  66. ArduinoJsonJWT _jwtHandler;
  67. void configureJWTHandler();
  68. /*
  69. * Lookup the user by JWT
  70. */
  71. Authentication authenticateJWT(String& jwt);
  72. /*
  73. * Verify the payload is correct
  74. */
  75. boolean validatePayload(JsonObject& parsedPayload, User* user);
  76. };
  77. #endif // end SecuritySettingsService_h