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.

109 lines
2.6 KiB

  1. #ifndef SecurityManager_h
  2. #define SecurityManager_h
  3. #include <list>
  4. #include <ArduinoJsonJWT.h>
  5. #include <ESPAsyncWebServer.h>
  6. #define DEFAULT_JWT_SECRET "esp8266-react"
  7. #define AUTHORIZATION_HEADER "Authorization"
  8. #define AUTHORIZATION_HEADER_PREFIX "Bearer "
  9. #define AUTHORIZATION_HEADER_PREFIX_LEN 7
  10. #define MAX_JWT_SIZE 128
  11. class User {
  12. private:
  13. String _username;
  14. String _password;
  15. bool _admin;
  16. public:
  17. User(String username, String password, bool admin): _username(username), _password(password), _admin(admin) {}
  18. String getUsername() {
  19. return _username;
  20. }
  21. String getPassword() {
  22. return _password;
  23. }
  24. bool isAdmin() {
  25. return _admin;
  26. }
  27. };
  28. class Authentication {
  29. private:
  30. User *_user;
  31. boolean _authenticated;
  32. public:
  33. Authentication(User& user): _user(new User(user)), _authenticated(true) {}
  34. Authentication() : _user(nullptr), _authenticated(false) {}
  35. ~Authentication() {
  36. delete(_user);
  37. }
  38. User* getUser() {
  39. return _user;
  40. }
  41. bool isAuthenticated() {
  42. return _authenticated;
  43. }
  44. };
  45. typedef std::function<boolean(Authentication &authentication)> AuthenticationPredicate;
  46. class AuthenticationPredicates {
  47. public:
  48. static bool NONE_REQUIRED(Authentication &authentication) {
  49. return true;
  50. };
  51. static bool IS_AUTHENTICATED(Authentication &authentication) {
  52. return authentication.isAuthenticated();
  53. };
  54. static bool IS_ADMIN(Authentication &authentication) {
  55. return authentication.isAuthenticated() && authentication.getUser()->isAdmin();
  56. };
  57. };
  58. class SecurityManager {
  59. public:
  60. /*
  61. * Authenticate, returning the user if found
  62. */
  63. Authentication authenticate(String username, String password);
  64. /*
  65. * Check the request header for the Authorization token
  66. */
  67. Authentication authenticateRequest(AsyncWebServerRequest *request);
  68. /*
  69. * Generate a JWT for the user provided
  70. */
  71. String generateJWT(User *user);
  72. /**
  73. * Wrap the provided request to provide validation against an AuthenticationPredicate.
  74. */
  75. ArRequestHandlerFunction wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate);
  76. protected:
  77. ArduinoJsonJWT _jwtHandler = ArduinoJsonJWT(DEFAULT_JWT_SECRET);
  78. std::list<User> _users;
  79. private:
  80. /*
  81. * Lookup the user by JWT
  82. */
  83. Authentication authenticateJWT(String jwt);
  84. /*
  85. * Verify the payload is correct
  86. */
  87. boolean validatePayload(JsonObject &parsedPayload, User *user);
  88. };
  89. #endif // end SecurityManager_h