123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- /*
- User.ino
- This is a new module handling user systems on ESP8266
- */
- //Check if a user login is valid by username and password
- bool UserCheckAuth(String username, String password) {
- username.trim();
- password.trim();
- //Load user info from db
- if (!DBKeyExists("user", username)) {
- return false;
- }
- String userHashedPassword = DBRead("user", username); //User hashed password from kvdb
- String enteredHashedPassword = sha1(password); //Entered hashed password
- return userHashedPassword.equals(enteredHashedPassword);
- }
- //Get the username from the request, return empty string if unable to resolve
- String GetUsernameFromRequest(AsyncWebServerRequest *r) {
- if (r->hasHeader("Cookie")) {
- //User cookie from browser
- String authCookie = GetCookieValueByKey(r, "web-auth");
- if (authCookie == "") {
- return "";
- }
- //Check if this is admin login
- if (authCookie.equals(authSession)) {
- return adminUsername;
- }
- //Check if user login
- if (DBKeyExists("sess", authCookie)) {
- //Return the username of this session
- return DBRead("sess", authCookie);
- }
- //Not found
- return "";
- }
- //This user have no cookie in header
- return "";
- }
- //Create new user, creator must be admin
- void HandleNewUser(AsyncWebServerRequest *r) {
- if (!IsAdmin(r)) {
- SendErrorResp(r, "this function require admin permission");
- return;
- }
- String username = GetPara(r, "username");
- String password = GetPara(r, "password");
- username.trim();
- password.trim();
- //Check if the inputs are valid
- if (username == "" || password == "") {
- SendErrorResp(r, "username or password is an empty string");
- return;
- } else if (password.length() < 8) {
- SendErrorResp(r, "password must contain at least 8 characters");
- return;
- }
- //Check if the user already exists
- if (DBKeyExists("user", username)) {
- SendErrorResp(r, "user with name: " + username + " already exists");
- return;
- }
- //OK create the user
- bool succ = DBWrite("user", username, sha1(password));
- if (!succ) {
- SendErrorResp(r, "write new user to database failed");
- return;
- }
- r->send(200, "application/json", "\"OK\"");
- }
- //Remove the given username from the system
- void HandleRemoveUser(AsyncWebServerRequest *r) {
- if (!IsAdmin(r)) {
- SendErrorResp(r, "this function require admin permission");
- return;
- }
- String username = GetPara(r, "username");
- username.trim();
- //Check if the user exists
- if (!DBKeyExists("user", username)) {
- SendErrorResp(r, "user with name: " + username + " not exists");
- return;
- }
- //Okey, remove the user
- bool succ = DBRemove("user", username);
- if (!succ) {
- SendErrorResp(r, "remove user from system failed");
- return;
- }
- r->send(200, "application/json", "\"OK\"");
- }
- //Admin or the user themselve change password for the account
- void HandleUserChangePassword(AsyncWebServerRequest *r) {
- //Get requesting username
- if (!IsUserAuthed(r)) {
- SendErrorResp(r, "user not logged in");
- return;
- }
- String currentUser = GetUsernameFromRequest(r);
- if (currentUser == "") {
- SendErrorResp(r, "unable to load user from system");
- return;
- }
- //Check if the user can change password
- //note that admin password cannot be changed on-the-fly
- //admin password can only be changed in SD card config file
- String modifyingUsername = GetPara(r, "username");
- String newPassword = GetPara(r, "newpw");
- modifyingUsername.trim();
- newPassword.trim();
- if (modifyingUsername == adminUsername) {
- SendErrorResp(r, "admin username can only be changed in the config file");
- return;
- }
- if (currentUser == adminUsername || modifyingUsername == currentUser) {
- //Allow modify
- if (newPassword.length() < 8) {
- SendErrorResp(r, "password must contain at least 8 characters");
- return;
- }
- //Write to database
- bool succ = DBWrite("user", modifyingUsername, sha1(newPassword));
- if (!succ) {
- SendErrorResp(r, "write new user to database failed");
- return;
- }
- SendOK(r);
- } else {
- SendErrorResp(r, "permission denied");
- return;
- }
- SendOK(r);
- }
- //Get the current username
- void HandleGetUserinfo(AsyncWebServerRequest *r){
- if (!HandleAuth(r)) {
- return;
- }
- String isAdmin = "false";
- if (IsAdmin(r)){
- isAdmin = "true";
- }
- String username = GetUsernameFromRequest(r);
- r->send(200, "application/json", "{\"username\":\"" + username + "\", \"admin\":" + isAdmin + "}");
- }
- //List all users registered in this WebStick
- void HandleUserList(AsyncWebServerRequest *r) {
- if (!HandleAuth(r)) {
- return;
- }
- //Build the json with brute force
- String jsonString = "[";
- //As the DB do not support list, it directly access the root of the folder where the kvdb stores the entries
- File root = SD.open(DB_root + "user/");
- bool firstObject = true;
- if (root) {
- while (true) {
- File entry = root.openNextFile();
- if (!entry) {
- // No more files
- break;
- } else {
- //There are more lines. Add a , to the end of the previous json object
- if (!firstObject) {
- jsonString = jsonString + ",";
- } else {
- firstObject = false;
- }
- //Filter out all the directory if any
- if (entry.isDirectory()) {
- continue;
- }
- //Append to the JSON line
- jsonString = jsonString + "{\"Username\":\"" + entry.name() + "\"}";
- }
- }
- }
- jsonString += "]";
- r->send(200, "application/json", jsonString);
-
- }
|