handlers.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. package scheduler
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strconv"
  6. "time"
  7. "imuslab.com/arozos/mod/common"
  8. )
  9. //List all the jobs related to the given user
  10. func (a *Scheduler) HandleListJobs(w http.ResponseWriter, r *http.Request) {
  11. userinfo, err := a.options.UserHandler.GetUserInfoFromRequest(w, r)
  12. if err != nil {
  13. common.SendErrorResponse(w, "User not logged in")
  14. return
  15. }
  16. //Get username from user info
  17. username := userinfo.Username
  18. //Check if the user request list all
  19. listAll := false
  20. la, _ := common.Mv(r, "listall", false)
  21. if la == "true" && userinfo.IsAdmin() {
  22. listAll = true
  23. }
  24. //Find the scheduled task that belongs to this user
  25. userCreatedJobs := []*Job{}
  26. for _, thisJob := range a.jobs {
  27. if listAll {
  28. //List all the user jobs.
  29. userCreatedJobs = append(userCreatedJobs, thisJob)
  30. } else {
  31. //Only list user's job
  32. if thisJob.Creator == username {
  33. userCreatedJobs = append(userCreatedJobs, thisJob)
  34. }
  35. }
  36. }
  37. //Return the values as json
  38. js, _ := json.Marshal(userCreatedJobs)
  39. common.SendJSONResponse(w, string(js))
  40. }
  41. func (a *Scheduler) HandleAddJob(w http.ResponseWriter, r *http.Request) {
  42. userinfo, err := a.options.UserHandler.GetUserInfoFromRequest(w, r)
  43. if err != nil {
  44. common.SendErrorResponse(w, "User not logged in")
  45. return
  46. }
  47. //Get required paramaters
  48. taskName, err := common.Mv(r, "name", true)
  49. if err != nil {
  50. common.SendErrorResponse(w, "Invalid task name")
  51. return
  52. }
  53. //Check taskname length valid
  54. if len(taskName) > 32 {
  55. common.SendErrorResponse(w, "Task name must be shorter than 32 characters")
  56. return
  57. }
  58. //Check if the name already existsed
  59. for _, runningJob := range a.jobs {
  60. if runningJob.Name == taskName {
  61. common.SendErrorResponse(w, "Task Name already occupied")
  62. return
  63. }
  64. }
  65. scriptpath, err := common.Mv(r, "path", true)
  66. if err != nil {
  67. common.SendErrorResponse(w, "Invalid script path")
  68. return
  69. }
  70. //Can be empty
  71. jobDescription, _ := common.Mv(r, "desc", true)
  72. fsh, err := userinfo.GetFileSystemHandlerFromVirtualPath(scriptpath)
  73. if err != nil {
  74. common.SendErrorResponse(w, err.Error())
  75. return
  76. }
  77. fshAbs := fsh.FileSystemAbstraction
  78. realScriptPath, err := fshAbs.VirtualPathToRealPath(scriptpath, userinfo.Username)
  79. if err != nil {
  80. common.SendErrorResponse(w, err.Error())
  81. return
  82. }
  83. //Check if the file exists
  84. if !fshAbs.FileExists(realScriptPath) {
  85. common.SendErrorResponse(w, "script file not exists")
  86. return
  87. }
  88. interval := int64(86400) //default 1 day in seconds
  89. intervalString, err := common.Mv(r, "interval", true)
  90. if err != nil {
  91. //Default 1 day
  92. } else {
  93. //Parse the intervalString into int
  94. intervalInt, err := strconv.ParseInt(intervalString, 10, 64)
  95. if err != nil {
  96. //Failed to parse interval to int
  97. common.SendErrorResponse(w, "invalid interval")
  98. return
  99. }
  100. interval = intervalInt
  101. }
  102. baseUnixTime := time.Now().Unix()
  103. baseTimeString, err := common.Mv(r, "base", true)
  104. if err != nil {
  105. //Use curent timestamp as base
  106. } else {
  107. baseTimeInt, err := strconv.Atoi(baseTimeString)
  108. if err != nil {
  109. //Failed to parse interval to int
  110. common.SendErrorResponse(w, "Invalid Base Time")
  111. return
  112. }
  113. baseUnixTime = int64(baseTimeInt)
  114. }
  115. //Create a new job
  116. newJob := Job{
  117. Name: taskName,
  118. Creator: userinfo.Username,
  119. Description: jobDescription,
  120. ExecutionInterval: int64(interval),
  121. BaseTime: baseUnixTime,
  122. ScriptVpath: scriptpath,
  123. FshID: fsh.UUID,
  124. }
  125. //Write current job lists to file
  126. a.jobs = append(a.jobs, &newJob)
  127. a.saveJobsToCronFile()
  128. //OK
  129. common.SendOK(w)
  130. }
  131. func (a *Scheduler) HandleJobRemoval(w http.ResponseWriter, r *http.Request) {
  132. userinfo, err := a.options.UserHandler.GetUserInfoFromRequest(w, r)
  133. if err != nil {
  134. common.SendErrorResponse(w, "User not logged in")
  135. return
  136. }
  137. //Get required paramaters
  138. taskName, err := common.Mv(r, "name", true)
  139. if err != nil {
  140. common.SendErrorResponse(w, "Invalid task name")
  141. return
  142. }
  143. //Check if Job exists
  144. if !a.JobExists(taskName) {
  145. //Job with that name not exists
  146. common.SendErrorResponse(w, "Job not exists")
  147. return
  148. }
  149. targetJob := a.GetScheduledJobByName(taskName)
  150. //Job exists. Check if the job is created by the user.
  151. //User can only remove job created by himself or all job is he is admin
  152. allowRemove := false
  153. if !userinfo.IsAdmin() && targetJob.Creator == userinfo.Username {
  154. allowRemove = true
  155. } else if userinfo.IsAdmin() {
  156. allowRemove = true
  157. }
  158. if !allowRemove {
  159. common.SendErrorResponse(w, "Permission Denied")
  160. return
  161. }
  162. //Ok. Remove Job from the list
  163. a.RemoveJobFromScheduleList(taskName)
  164. //Write current job lists to file
  165. a.saveJobsToCronFile()
  166. common.SendOK(w)
  167. }
  168. //Deprecated. Replace with system wide logger
  169. /*
  170. func (a *Scheduler) HandleShowLog(w http.ResponseWriter, r *http.Request) {
  171. filename, _ := mv(r, "filename", false)
  172. if filename == "" {
  173. //Show index
  174. logFiles, _ := filepath.Glob(logFolder + "*.log")
  175. //Convert all to linux syntax
  176. linuxLogFiles := []string{}
  177. for _, lf := range logFiles {
  178. linuxLogFiles = append(linuxLogFiles, filepath.Base(lf))
  179. }
  180. js, _ := json.Marshal(linuxLogFiles)
  181. sendJSONResponse(w, string(js))
  182. } else {
  183. //Show log content
  184. filename = strings.ReplaceAll(filepath.ToSlash(filename), "/", "")
  185. if fileExists(filepath.Join(logFolder, filename)) {
  186. logContent, err := ioutil.ReadFile(filepath.Join(logFolder, filename))
  187. if err != nil {
  188. sendTextResponse(w, "Unable to load log file: "+filename)
  189. } else {
  190. sendTextResponse(w, string(logContent))
  191. }
  192. } else {
  193. sendTextResponse(w, "Unable to load log file: "+filename)
  194. }
  195. }
  196. }
  197. */