console.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. package main
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "strings"
  7. )
  8. //Handle console command from the console module
  9. func consoleCommandHandler(input string) string {
  10. //chunk := strings.Split(input, " ");
  11. chunk, err := parseCommandLine(input)
  12. if err != nil {
  13. return err.Error()
  14. }
  15. if len(chunk) > 0 && chunk[0] == "auth" {
  16. if matchSubfix(chunk, []string{"auth", "new"}, 4, "auth new {username} {password}") {
  17. return "Creating a new user " + chunk[2] + " with password " + chunk[3]
  18. }
  19. } else if len(chunk) > 0 && chunk[0] == "permission" {
  20. if matchSubfix(chunk, []string{"permission", "list"}, 2, "") {
  21. fmt.Println("> ", permissionHandler.PermissionGroups)
  22. return "OK"
  23. } else if matchSubfix(chunk, []string{"permission", "user"}, 3, "permission user {username}") {
  24. username := chunk[2]
  25. group, _ := permissionHandler.GetUsersPermissionGroup(username)
  26. for _, thisGroup := range group {
  27. fmt.Println(thisGroup)
  28. }
  29. return "OK"
  30. } else if matchSubfix(chunk, []string{"permission", "group"}, 3, "permission group {groupname}") {
  31. groupname := chunk[2]
  32. groups := permissionHandler.PermissionGroups
  33. for _, thisGroup := range groups {
  34. if thisGroup.Name == groupname {
  35. fmt.Println(thisGroup)
  36. }
  37. }
  38. return "OK"
  39. } else if matchSubfix(chunk, []string{"permission", "getinterface"}, 3, "permission getinterface {username}") {
  40. //Get the list of interface module for this user
  41. userinfo, err := userHandler.GetUserInfoFromUsername(chunk[2])
  42. if err != nil {
  43. return err.Error()
  44. }
  45. return strings.Join(userinfo.GetInterfaceModules(), ",")
  46. }
  47. } else if len(chunk) > 0 && chunk[0] == "quota" {
  48. if matchSubfix(chunk, []string{"quota", "user"}, 3, "quota user {username}") {
  49. userinfo, err := userHandler.GetUserInfoFromUsername(chunk[2])
  50. if err != nil {
  51. return err.Error()
  52. }
  53. fmt.Println("> "+"User Quota: ", userinfo.StorageQuota.UsedStorageQuota, "/", userinfo.StorageQuota.GetUserStorageQuota(), "bytes")
  54. return "OK"
  55. }
  56. } else if len(chunk) > 0 && chunk[0] == "database" {
  57. if matchSubfix(chunk, []string{"database", "dump"}, 3, "database dump {filename}") {
  58. //Dump the database to file
  59. return "WIP"
  60. } else if matchSubfix(chunk, []string{"database", "list", "tables"}, 3, "") {
  61. //List all opened tables
  62. sysdb.Tables.Range(func(k, v interface{}) bool {
  63. fmt.Println(k.(string))
  64. return true
  65. })
  66. return "OK"
  67. } else if matchSubfix(chunk, []string{"database", "view"}, 3, "database list {tablename}") {
  68. //List everything in this table
  69. tableList := []string{}
  70. sysdb.Tables.Range(func(k, v interface{}) bool {
  71. tableList = append(tableList, k.(string))
  72. return true
  73. })
  74. if !inArray(tableList, chunk[2]) {
  75. return "Table not exists"
  76. } else if chunk[2] == "auth" {
  77. return "You cannot view this database table"
  78. }
  79. entries, err := sysdb.ListTable(chunk[2])
  80. if err != nil {
  81. return err.Error()
  82. }
  83. for _, keypairs := range entries {
  84. fmt.Println("> " + string(keypairs[0]) + ":" + string(keypairs[1]))
  85. }
  86. fmt.Println("Total Entry Count: ", len(entries))
  87. return "OK"
  88. }
  89. } else if len(chunk) > 0 && chunk[0] == "user" {
  90. if matchSubfix(chunk, []string{"user", "object", "dump"}, 4, "user object dump {username}") {
  91. //Dump the given user object as json
  92. userinfo, err := userHandler.GetUserInfoFromUsername(chunk[3])
  93. if err != nil {
  94. return err.Error()
  95. }
  96. jsonString, _ := json.Marshal(userinfo)
  97. return string(jsonString)
  98. } else if matchSubfix(chunk, []string{"user", "quota"}, 3, "user quota {username}") {
  99. //List user quota of the given username
  100. userinfo, err := userHandler.GetUserInfoFromUsername(chunk[2])
  101. if err != nil {
  102. return err.Error()
  103. }
  104. fmt.Println(userinfo.StorageQuota.UsedStorageQuota, "/", userinfo.StorageQuota.TotalStorageQuota)
  105. return "OK"
  106. }
  107. } else if len(chunk) > 0 && chunk[0] == "storage" {
  108. if matchSubfix(chunk, []string{"storage", "list", "basepool"}, 3, "") {
  109. //Dump the base storage pool
  110. jsonString, _ := json.Marshal(userHandler.GetStoragePool())
  111. return string(jsonString)
  112. }
  113. } else if len(chunk) > 0 && chunk[0] == "find" {
  114. if matchSubfix(chunk, []string{"find", "module"}, 3, "list module {modulename}") {
  115. //Display all loaded modules
  116. for _, module := range moduleHandler.LoadedModule {
  117. if strings.ToLower(module.Name) == strings.ToLower(chunk[2]) {
  118. jsonString, _ := json.Marshal(module)
  119. return string(jsonString)
  120. }
  121. }
  122. return string("Module not found")
  123. } else if matchSubfix(chunk, []string{"find", "modules"}, 2, "") {
  124. //Display all loaded modules
  125. jsonString, _ := json.Marshal(moduleHandler.LoadedModule)
  126. return string(jsonString)
  127. } else if matchSubfix(chunk, []string{"find", "subservices"}, 2, "") {
  128. //Display all loaded subservices
  129. fmt.Println(ssRouter.RunningSubService)
  130. return "OK"
  131. }
  132. } else if len(chunk) == 1 && chunk[0] == "stop" {
  133. //Stopping the server
  134. fmt.Println("Shutting down aroz online system by terminal request")
  135. executeShutdownSequence()
  136. }
  137. return "Invalid Command. Given: '" + strings.Join(chunk, " ") + "'"
  138. }
  139. //Check if the given line input match the requirement
  140. func matchSubfix(chunk []string, match []string, minlength int, usageExample string) bool {
  141. matching := true
  142. //Check if the chunk contains minmium length of the command request
  143. if len(chunk) >= len(match) {
  144. for i, cchunk := range match {
  145. if chunk[i] != cchunk {
  146. matching = false
  147. }
  148. }
  149. } else {
  150. matching = false
  151. }
  152. if len(chunk)-minlength == -1 && chunk[len(chunk)-1] == match[len(match)-1] {
  153. fmt.Println("Paramter missing. Usage: " + usageExample)
  154. return false
  155. }
  156. return matching
  157. }
  158. func parseCommandLine(command string) ([]string, error) {
  159. var args []string
  160. state := "start"
  161. current := ""
  162. quote := "\""
  163. escapeNext := true
  164. for i := 0; i < len(command); i++ {
  165. c := command[i]
  166. if state == "quotes" {
  167. if string(c) != quote {
  168. current += string(c)
  169. } else {
  170. args = append(args, current)
  171. current = ""
  172. state = "start"
  173. }
  174. continue
  175. }
  176. if escapeNext {
  177. current += string(c)
  178. escapeNext = false
  179. continue
  180. }
  181. if c == '\\' {
  182. escapeNext = true
  183. continue
  184. }
  185. if c == '"' || c == '\'' {
  186. state = "quotes"
  187. quote = string(c)
  188. continue
  189. }
  190. if state == "arg" {
  191. if c == ' ' || c == '\t' {
  192. args = append(args, current)
  193. current = ""
  194. state = "start"
  195. } else {
  196. current += string(c)
  197. }
  198. continue
  199. }
  200. if c != ' ' && c != '\t' {
  201. state = "arg"
  202. current += string(c)
  203. }
  204. }
  205. if state == "quotes" {
  206. return []string{}, errors.New(fmt.Sprintf("Unclosed quote in command line: %s", command))
  207. }
  208. if current != "" {
  209. args = append(args, current)
  210. }
  211. return args, nil
  212. }