console.go 7.0 KB

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