Bladeren bron

Merge branch 'us20-2-signup-client' into 'develop'

US20.2: Signup command (Client)

See merge request tobias.wach/ccats!28
Sander, Paul 5 jaren geleden
bovenliggende
commit
5dbbcb538a
7 gewijzigde bestanden met toevoegingen van 173 en 77 verwijderingen
  1. 9 3
      cli/include/cmdman.h
  2. 4 2
      cli/include/ioman.h
  3. 2 0
      cli/include/userioman.h
  4. 127 30
      cli/src/cmdman.cpp
  5. 9 37
      cli/src/ioman.cpp
  6. 3 2
      cli/src/machineioman.cpp
  7. 19 3
      cli/src/userioman.cpp

+ 9 - 3
cli/include/cmdman.h

@@ -94,9 +94,10 @@ private:
 
   /**
    * State used to internally format received json to allow easy handling using
-   * handlemap
+   * handlemap and to disallow the use of certain commands when logged in/not
+   * logged in.
    */
-  bool dologin, doversion;
+  bool doversion, loginpossible, dologin, dosignup;
 
   /**
    * Help strings and method prototypes for commands to be used by a user
@@ -115,12 +116,16 @@ private:
   const string descList = "list files available on server";
   CmdRet cmdList(vector<string> args);
 
+  const string descLogin = "login to the server";
+  CmdRet cmdLogin(vector<string> args);
+  const string descSignup = "sign up and login to the server";
+  CmdRet cmdSignup(vector<string> args);
+
   /**
    * Method prototypes for commands used internally
    */
   /* internal execute commands */
   CmdRet cmdVersion(vector<string> args);
-  CmdRet cmdLogin(vector<string> args);
   CmdRet cmdPutdata(vector<string> args);
   CmdRet cmdGetdata(vector<string> args);
   CmdRet cmdListdata(vector<string> args);
@@ -139,6 +144,7 @@ private:
   CmdRet handleListdata(Json::Value);
   CmdRet handleVersion(Json::Value);
   CmdRet handleLogin(Json::Value);
+  CmdRet handleSignup(Json::Value);
 };
 
 #endif

+ 4 - 2
cli/include/ioman.h

@@ -122,8 +122,10 @@ protected:
    */
   virtual void printWelcomeMessage() = 0;
   virtual std::string getCmdPrompt() = 0;
-  virtual std::string getUserPrompt() = 0;
-  virtual std::string getPassPrompt() = 0;
+  // following prompts currently not in use because login happens by entering
+  // command
+  //~  virtual std::string getUserPrompt() = 0;
+  //~  virtual std::string getPassPrompt() = 0;
 
 public:
   /**

+ 2 - 0
cli/include/userioman.h

@@ -33,6 +33,7 @@ private:
    * Method prototypes for printing json output
    */
   /* printing commands go here */
+  void printError(Json::Value root);
   void printConnect(Json::Value root);
   void printHelp(Json::Value root);
   void printStatus(Json::Value root);
@@ -42,6 +43,7 @@ private:
   void printList(Json::Value root);
   void printVersion(Json::Value root);
   void printLogin(Json::Value root);
+  void printSignup(Json::Value root);
   void printPutdata(Json::Value root);
   void printGetdata(Json::Value root);
   void printListdata(Json::Value root);

+ 127 - 30
cli/src/cmdman.cpp

@@ -14,8 +14,10 @@ CmdMan::CmdMan(FileMan &fm, void (*dpf)(string)) : fileman(fm) {
   wbuilder.settings_["indentation"] = "";
   reader = rbuilder.newCharReader();
 
-  dologin = false;
   doversion = false;
+  loginpossible = false;
+  dologin = false;
+  dosignup = false;
 
   /* initialize execute command map */
   execmap["help"] = &CmdMan::cmdHelp;
@@ -26,6 +28,7 @@ CmdMan::CmdMan(FileMan &fm, void (*dpf)(string)) : fileman(fm) {
   execmap["list"] = &CmdMan::cmdList;
   execmap["version"] = &CmdMan::cmdVersion;
   execmap["login"] = &CmdMan::cmdLogin;
+  execmap["signup"] = &CmdMan::cmdSignup;
   execmap["putdata"] = &CmdMan::cmdPutdata;
   execmap["getdata"] = &CmdMan::cmdGetdata;
 
@@ -47,6 +50,7 @@ CmdMan::CmdMan(FileMan &fm, void (*dpf)(string)) : fileman(fm) {
   handlemap["list"] = &CmdMan::handleList;
   handlemap["version"] = &CmdMan::handleVersion;
   handlemap["login"] = &CmdMan::handleLogin;
+  handlemap["signup"] = &CmdMan::handleSignup;
 
   debugprintfunc = dpf;
 }
@@ -83,8 +87,17 @@ CmdMan::CmdRet CmdMan::cmdDisconnect(vector<string> args) {
   CmdRet retval;
   DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
   Json::Value root;
-  root["command"] = "close";
   retval.type = send;
+  if (loginpossible) {
+    // not logged in, send appropriate login message instead of normal close
+    root["login"] = false;
+    root["user"] = "";
+    root["pass"] = "";
+    root["cancel"] = true;
+    retval.type |= close;
+  } else {
+    root["command"] = "close";
+  }
   retval.msg = root;
 
   return retval;
@@ -204,61 +217,113 @@ CmdMan::CmdRet CmdMan::execute(string cmd, vector<string> args) {
              "\" with arguments [ ");
   for (string s : args)
     DEBUGPRINT(s + " ");
-  DEBUGPRINT("]\n");
+  DEBUGPRINT("]");
   map<string, CmdRet (CmdMan::*)(vector<string>)>::iterator it =
       execmap.find(cmd);
-  string retmsg;
+  CmdRet retval;
+  Json::Value root;
+  root["command"] = cmd;
   if (it == execmap.end()) {
-    return {error, string(__PRETTY_FUNCTION__) + " unknown command \"" + cmd +
-                       "\".\ntype help to list available commands."};
+    retval.type = error;
+    root["command"] = "error";
+    root["error"] = string(__PRETTY_FUNCTION__) + " unknown command \"" + cmd +
+                    "\".\ntype help to list available commands.";
+    retval.msg = root;
+    return retval;
+  } else if (loginpossible || dologin || dosignup) {
+    DEBUGPRINT("execute does login");
+    DEBUGPRINT(string("comparison is ") +
+               std::to_string(cmd.compare("login") && cmd.compare("signup") &&
+                              cmd.compare("disconnect") &&
+                              cmd.compare("help")));
+    if (cmd.compare("login") && cmd.compare("signup") &&
+        cmd.compare("disconnect") && cmd.compare("help")) {
+      retval.type = error;
+      root["command"] = "error";
+      root["error"] =
+          string("Not logged in. Available commands are limited to ") +
+          "login" + ", " + "signup" + " and " + "disconnect" + "\n" +
+          "Use help for usage of these commands.";
+      retval.msg = root;
+      return retval;
+    }
   }
   return (this->*(execmap[cmd]))(args);
 }
 
-/* internal commands */
-CmdMan::CmdRet CmdMan::cmdVersion(vector<string> args) {
+/* login and signup commands */
+CmdMan::CmdRet CmdMan::cmdLogin(vector<string> args) {
   CmdRet retval;
   DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
   Json::Value root;
-  root["version"] = protocolVersion;
-  retval.type = send;
+
+  if (loginpossible) {
+    dologin = true;
+    loginpossible = false;
+    root["user"] = args[0];
+    root["pass"] = args[1];
+    root["login"] = true;
+    root["cancel"] = false;
+    retval.type = send;
+  } else {
+    root["command"] = "login";
+    root["error"] = "Login not possible, because you already requested a login "
+                    "or you are logged in";
+    root["accept"] = false;
+    retval.type = error;
+  }
+
   retval.msg = root;
+  return retval;
+}
 
-  doversion = true;
+CmdMan::CmdRet CmdMan::cmdSignup(vector<string> args) {
+  CmdRet retval;
+  DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
+  Json::Value root;
+
+  if (loginpossible) {
+    dosignup = true;
+    loginpossible = false;
+    root["user"] = args[0];
+    root["pass"] = args[1];
+    root["login"] = true;
+    root["cancel"] = false;
+    retval.type = send;
+  } else {
+    root["command"] = "signup";
+    root["error"] = "Signup not possible, because you already requested a "
+                    "login or you are logged in";
+    root["accept"] = false;
+    retval.type = error;
+  }
 
+  retval.msg = root;
   return retval;
 }
 
-CmdMan::CmdRet CmdMan::cmdLogin(vector<string> args) {
+/* internal commands */
+CmdMan::CmdRet CmdMan::cmdVersion(vector<string> args) {
   CmdRet retval;
   DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
   Json::Value root;
-  root["user"] = args[0];
-  root["pass"] = args[1];
-  root["login"] = true;
-  root["cancel"] = false;
+  root["version"] = protocolVersion;
   retval.type = send;
   retval.msg = root;
 
-  dologin = true;
+  doversion = true;
 
   return retval;
 }
 
-/*
-        handlemap["status"] = &CmdMan::handleDefault;
-        handlemap["disconnect"] = &CmdMan::handleDefault;
-        handlemap["put"] = &CmdMan::handleDefault;
-        handlemap["get"] = &CmdMan::handleDefault;
-        handlemap["list"] = NULL;
-        handlemap["version"] = NULL;
-        handlemap["login"] = NULL;
-*/
-
 CmdMan::CmdRet CmdMan::handle(Json::Value root) {
+  CmdRet retval;
+  Json::Value output;
   DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
   if (doversion)
     root["command"] = "version";
+  else if (dosignup)
+    root["command"] = "signup";
   else if (dologin)
     root["command"] = "login";
   DEBUGPRINT(string(__PRETTY_FUNCTION__) + " using json\n" +
@@ -266,10 +331,15 @@ CmdMan::CmdRet CmdMan::handle(Json::Value root) {
   string retmsg;
   map<string, CmdRet (CmdMan::*)(Json::Value)>::iterator it =
       handlemap.find(root["command"].asString());
+
   if (it == handlemap.end()) {
-    return {error, string(__PRETTY_FUNCTION__) + " unknown command \"" +
-                       root["command"].asString() +
-                       "\".\nensure code is implemented."};
+    retval.type = error;
+    output["command"] = "error";
+    output["error"] = string(__PRETTY_FUNCTION__) + " unknown command \"" +
+                      root["command"].asString() +
+                      "\".\nEnsure code is implemented.";
+    retval.msg = output;
+    return retval;
   }
   return (this->*(handlemap[root["command"].asString()]))(root);
 }
@@ -523,6 +593,7 @@ CmdMan::CmdRet CmdMan::handleVersion(Json::Value root) {
     retval.type = print | seton;
     output["accept"] = true;
     doversion = false;
+    loginpossible = true;
   }
   retval.msg = output;
 
@@ -540,6 +611,8 @@ CmdMan::CmdRet CmdMan::handleLogin(Json::Value root) {
     retval.type = error;
     output["error"] = root["error"].asString();
     output["accept"] = false;
+    loginpossible = true;
+    dologin = false;
   } else {
     retval.type = print | seton;
     output["error"] = "";
@@ -550,3 +623,27 @@ CmdMan::CmdRet CmdMan::handleLogin(Json::Value root) {
 
   return retval;
 }
+
+CmdMan::CmdRet CmdMan::handleSignup(Json::Value root) {
+  CmdRet retval;
+  Json::Value output; // LOCALOUTPUT
+  DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
+
+  output["command"] = "signup";
+
+  if (!root["accept"].asBool()) {
+    retval.type = error;
+    output["error"] = root["error"].asString();
+    output["accept"] = false;
+    loginpossible = true;
+    dosignup = false;
+  } else {
+    retval.type = print | seton;
+    output["error"] = "";
+    output["accept"] = true;
+    dosignup = false;
+  }
+  retval.msg = output;
+
+  return retval;
+}

+ 9 - 37
cli/src/ioman.cpp

@@ -376,6 +376,12 @@ void IoMan::inputMain() {
       if (cmdret.type & CmdMan::rettype::error) {
         printMessage(Json::writeString(wbuilder, cmdret.msg), error);
       }
+      if (cmdret.type & CmdMan::rettype::close) {
+        /* TODO i dunno */
+        mainmutex.lock();
+        runmain = false;
+        mainmutex.unlock();
+      }
     }
 
     // clean up local stuff
@@ -519,49 +525,13 @@ void ioman_readlineHandler(char *line) {
 /* main user input loop */
 void IoMan::run() {
   printMessage("IoMan::run() begin", debug);
-  //~ char *line = NULL, *user = NULL, *pass = NULL;
-  char *user = NULL, *pass = NULL;
-  vector<string> tokens;
-  string work, command;
-  CmdMan::CmdRet cmdret;
-  Json::Value root;
-  std::unique_lock<std::mutex> ulock;
   struct pollfd inPipeStatus;
   inPipeStatus.fd = STDIN_FILENO;
   inPipeStatus.events = POLLIN;
 
   runmain = true;
 
-  while (!user) {
-    user = readline(getUserPrompt().c_str());
-    printMessage("Using user: " + string(user), debug);
-  }
-  while (!pass) {
-    pass = readline(getPassPrompt().c_str());
-    printMessage("Using pass: " + string(pass), debug);
-  }
-
-  printMessage("IoMan::run() login", debug);
-
-  localmutex.lock();
-  printMessage(string(__PRETTY_FUNCTION__) + string(" get localmutex"), debug);
-  localinput.push_back("login " + string(user) + " " + string(pass));
-  localmutex.unlock();
-  printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"),
-               debug);
-  free(user);
-  free(pass);
-  localcv.notify_all();
-
-  ulock = std::unique_lock<std::mutex>(initmutex);
-  while (loginstatus == off) {
-    initcv.wait(ulock);
-  }
-  if (loginstatus == err)
-    return;
-  initmutex.unlock();
-  initcv.notify_all();
-
+  // Install readline handler
   rl_callback_handler_install(getCmdPrompt().c_str(),
                               (rl_vcpfunc_t *)&ioman_readlineHandler);
 
@@ -576,6 +546,8 @@ void IoMan::run() {
     }
     if (!connected)
       break;
+    if (loginstatus == err)
+      break;
     mainmutex.lock();
   }
   mainmutex.unlock();

+ 3 - 2
cli/src/machineioman.cpp

@@ -33,5 +33,6 @@ void MachineIoMan::printWelcomeMessage() {
 
 std::string MachineIoMan::getCmdPrompt() { return ""; }
 
-std::string MachineIoMan::getUserPrompt() { return ""; }
-std::string MachineIoMan::getPassPrompt() { return ""; }
+// currently not in use:
+//~ std::string MachineIoMan::getUserPrompt() { return ""; }
+//~ std::string MachineIoMan::getPassPrompt() { return ""; }

+ 19 - 3
cli/src/userioman.cpp

@@ -18,6 +18,7 @@ UserIoMan::UserIoMan(char *ipcstring) : IoMan(ipcstring) {
   reader = rbuilder.newCharReader();
 
   /* initialize print command map */
+  printmap["error"] = &UserIoMan::printError;
   printmap["connect"] = &UserIoMan::printConnect;
   printmap["help"] = &UserIoMan::printHelp;
   printmap["status"] = &UserIoMan::printStatus;
@@ -27,6 +28,7 @@ UserIoMan::UserIoMan(char *ipcstring) : IoMan(ipcstring) {
   printmap["list"] = &UserIoMan::printList;
   printmap["version"] = &UserIoMan::printVersion;
   printmap["login"] = &UserIoMan::printLogin;
+  printmap["signup"] = &UserIoMan::printSignup;
   printmap["putdata"] = &UserIoMan::printPutdata;
   printmap["getdata"] = &UserIoMan::printGetdata;
 }
@@ -64,13 +66,16 @@ void UserIoMan::printMessage(std::string msg, OutMsgType type) {
 }
 
 void UserIoMan::printWelcomeMessage() {
-  std::cout << "please enter user and password" << std::endl;
+  std::cout << "please login by entering \"login <username> <password>\" \nor "
+               "sign up and log in with \"signup <username> <password>\""
+            << std::endl;
 }
 
 std::string UserIoMan::getCmdPrompt() { return "ccats> "; }
 
-std::string UserIoMan::getUserPrompt() { return "User: "; }
-std::string UserIoMan::getPassPrompt() { return "Pass: "; }
+// currently not in use:
+//~ std::string UserIoMan::getUserPrompt() { return "User: "; }
+//~ std::string UserIoMan::getPassPrompt() { return "Pass: "; }
 
 void UserIoMan::printJson(Json::Value root) {
   map<string, void (UserIoMan::*)(Json::Value)>::iterator it =
@@ -86,6 +91,10 @@ void UserIoMan::printJson(Json::Value root) {
   (this->*(printmap[root["command"].asString()]))(root);
 }
 
+void UserIoMan::printError(Json::Value root) {
+  std::cout << "Error: " << root["error"].asString() << std::endl;
+}
+
 void UserIoMan::printConnect(Json::Value root) {
   if (!root["accept"].asBool()) {
     std::cout << "Couldnt connect to " << root["address"].asString() << ":"
@@ -159,6 +168,13 @@ void UserIoMan::printLogin(Json::Value root) {
     std::cout << "Login ok." << std::endl;
 }
 
+void UserIoMan::printSignup(Json::Value root) {
+  if (!root["accept"].asBool()) {
+    std::cout << "Signup failed: " << root["error"].asString() << std::endl;
+  } else
+    std::cout << "Signup ok. You are now logged in." << std::endl;
+}
+
 void UserIoMan::printPutdata(Json::Value root) {}
 
 void UserIoMan::printGetdata(Json::Value root) {}