user.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. package main
  2. /*
  3. User Management System
  4. Entry points for handler user functions
  5. */
  6. import (
  7. "encoding/json"
  8. "net/http"
  9. "strconv"
  10. "strings"
  11. uuid "github.com/satori/go.uuid"
  12. auth "imuslab.com/arozos/mod/auth"
  13. module "imuslab.com/arozos/mod/modules"
  14. prout "imuslab.com/arozos/mod/prouter"
  15. user "imuslab.com/arozos/mod/user"
  16. "imuslab.com/arozos/mod/utils"
  17. )
  18. func UserSystemInit() {
  19. //Create a new User Handler
  20. uh, err := user.NewUserHandler(sysdb, authAgent, permissionHandler, baseStoragePool, &shareEntryTable)
  21. if err != nil {
  22. panic(err)
  23. }
  24. userHandler = uh
  25. /*
  26. router := prout.NewModuleRouter(prout.RouterOption{
  27. ModuleName: "System Settings",
  28. AdminOnly: false,
  29. UserHandler: userHandler,
  30. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  31. utils.SendErrorResponse(w, "Permission Denied")
  32. },
  33. })
  34. */
  35. //Create Endpoint Listeners
  36. http.HandleFunc("/system/users/list", user_handleList)
  37. //Everyone logged in should have permission to view their profile and change their password
  38. http.HandleFunc("/system/users/userinfo", func(w http.ResponseWriter, r *http.Request) {
  39. authAgent.HandleCheckAuth(w, r, user_handleUserInfo)
  40. })
  41. //Interface info should be able to view by everyone logged in
  42. http.HandleFunc("/system/users/interfaceinfo", func(w http.ResponseWriter, r *http.Request) {
  43. authAgent.HandleCheckAuth(w, r, user_getInterfaceInfo)
  44. })
  45. //Register setting interface for module configuration
  46. registerSetting(settingModule{
  47. Name: "My Account",
  48. Desc: "Manage your account and password",
  49. IconPath: "SystemAO/users/img/small_icon.png",
  50. Group: "Users",
  51. StartDir: "SystemAO/users/account.html",
  52. RequireAdmin: false,
  53. })
  54. registerSetting(settingModule{
  55. Name: "User List",
  56. Desc: "A list of users registered on this system",
  57. IconPath: "SystemAO/users/img/small_icon.png",
  58. Group: "Users",
  59. StartDir: "SystemAO/users/userList.html",
  60. RequireAdmin: true,
  61. })
  62. //Register auth management events that requires user handler
  63. adminRouter := prout.NewModuleRouter(prout.RouterOption{
  64. ModuleName: "System Settings",
  65. AdminOnly: true,
  66. UserHandler: userHandler,
  67. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  68. utils.SendErrorResponse(w, "Permission Denied")
  69. },
  70. })
  71. //Handle Authentication Unregister Handler
  72. adminRouter.HandleFunc("/system/auth/unregister", authAgent.HandleUnregister)
  73. adminRouter.HandleFunc("/system/users/editUser", user_handleUserEdit)
  74. adminRouter.HandleFunc("/system/users/removeUser", user_handleUserRemove)
  75. }
  76. // Remove a user from the system
  77. func user_handleUserRemove(w http.ResponseWriter, r *http.Request) {
  78. username, err := utils.PostPara(r, "username")
  79. if err != nil {
  80. utils.SendErrorResponse(w, "Username not defined")
  81. return
  82. }
  83. if !authAgent.UserExists(username) {
  84. utils.SendErrorResponse(w, "User not exists")
  85. return
  86. }
  87. userinfo, err := userHandler.GetUserInfoFromUsername(username)
  88. if err != nil {
  89. utils.SendErrorResponse(w, err.Error())
  90. return
  91. }
  92. currentUserinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  93. if err != nil {
  94. //This user has not logged in
  95. utils.SendErrorResponse(w, "User not logged in")
  96. return
  97. }
  98. if currentUserinfo.Username == userinfo.Username {
  99. //This user has not logged in
  100. utils.SendErrorResponse(w, "You can't remove yourself")
  101. return
  102. }
  103. //Clear Core User Data
  104. userinfo.RemoveUser()
  105. //Clearn Up FileSystem preferences
  106. system_fs_removeUserPreferences(username)
  107. utils.SendOK(w)
  108. }
  109. func user_handleUserEdit(w http.ResponseWriter, r *http.Request) {
  110. userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  111. if err != nil {
  112. //This user has not logged in
  113. utils.SendErrorResponse(w, "User not logged in")
  114. return
  115. }
  116. if userinfo.IsAdmin() == false {
  117. //Require admin access
  118. utils.SendErrorResponse(w, "Permission Denied")
  119. return
  120. }
  121. opr, _ := utils.PostPara(r, "opr")
  122. username, _ := utils.PostPara(r, "username")
  123. if !authAgent.UserExists(username) {
  124. utils.SendErrorResponse(w, "User not exists")
  125. return
  126. }
  127. if opr == "" {
  128. //List this user information
  129. type returnValue struct {
  130. Username string
  131. Icondata string
  132. Usergroup []string
  133. Quota int64
  134. }
  135. iconData := getUserIcon(username)
  136. userGroup, err := permissionHandler.GetUsersPermissionGroup(username)
  137. if err != nil {
  138. utils.SendErrorResponse(w, "Unable to get user group")
  139. return
  140. }
  141. //Parse the user permission groupts
  142. userGroupNames := []string{}
  143. for _, gp := range userGroup {
  144. userGroupNames = append(userGroupNames, gp.Name)
  145. }
  146. //Get the user's storaeg quota
  147. userinfo, _ := userHandler.GetUserInfoFromUsername(username)
  148. jsonString, _ := json.Marshal(returnValue{
  149. Username: username,
  150. Icondata: iconData,
  151. Usergroup: userGroupNames,
  152. Quota: userinfo.StorageQuota.GetUserStorageQuota(),
  153. })
  154. utils.SendJSONResponse(w, string(jsonString))
  155. } else if opr == "updateUserGroup" {
  156. //Update the target user's group
  157. newgroup, err := utils.PostPara(r, "newgroup")
  158. if err != nil {
  159. systemWideLogger.PrintAndLog("User", err.Error(), err)
  160. utils.SendErrorResponse(w, "New Group not defined")
  161. return
  162. }
  163. newQuota, err := utils.PostPara(r, "quota")
  164. if err != nil {
  165. systemWideLogger.PrintAndLog("User", err.Error(), err)
  166. utils.SendErrorResponse(w, "Quota not defined")
  167. return
  168. }
  169. quotaInt, err := strconv.Atoi(newQuota)
  170. if err != nil {
  171. systemWideLogger.PrintAndLog("User", err.Error(), err)
  172. utils.SendErrorResponse(w, "Invalid Quota Value")
  173. return
  174. }
  175. newGroupKeys := []string{}
  176. err = json.Unmarshal([]byte(newgroup), &newGroupKeys)
  177. if err != nil {
  178. systemWideLogger.PrintAndLog("User", err.Error(), err)
  179. utils.SendErrorResponse(w, "Unable to parse new groups")
  180. return
  181. }
  182. if len(newGroupKeys) == 0 {
  183. utils.SendErrorResponse(w, "User must be in at least one user permission group")
  184. return
  185. }
  186. //Check if each group exists
  187. for _, thisgp := range newGroupKeys {
  188. if !permissionHandler.GroupExists(thisgp) {
  189. utils.SendErrorResponse(w, "Group not exists, given: "+thisgp)
  190. return
  191. }
  192. }
  193. //OK to proceed
  194. userinfo, err := userHandler.GetUserInfoFromUsername(username)
  195. if err != nil {
  196. utils.SendErrorResponse(w, err.Error())
  197. return
  198. }
  199. //Check if the current user is the only one admin in the administrator group and he is leaving the group
  200. allAdministratorGroupUsers, err := userHandler.GetUsersInPermissionGroup("administrator")
  201. if err == nil {
  202. //Skip checking if error
  203. if len(allAdministratorGroupUsers) == 1 && userinfo.UserIsInOneOfTheGroupOf([]string{"administrator"}) && !utils.StringInArray(newGroupKeys, "administrator") {
  204. //Current administrator group only contain 1 user
  205. //This user is in the administrator group
  206. //The user want to unset himself from administrator group
  207. //Reject the operation as this will cause system lockdown
  208. utils.SendErrorResponse(w, "You are the only administrator. You cannot remove yourself from the administrator group.")
  209. return
  210. }
  211. }
  212. //Get the permission groups by their ids
  213. newPermissioGroups := userHandler.GetPermissionHandler().GetPermissionGroupByNameList(newGroupKeys)
  214. //Set the user's permission to these groups
  215. userinfo.SetUserPermissionGroup(newPermissioGroups)
  216. if err != nil {
  217. utils.SendErrorResponse(w, err.Error())
  218. return
  219. }
  220. //Write to quota handler
  221. userinfo.StorageQuota.SetUserStorageQuota(int64(quotaInt))
  222. utils.SendOK(w)
  223. } else if opr == "resetPassword" {
  224. //Reset password for this user
  225. //Generate a random password for this user
  226. tmppassword := uuid.NewV4().String()
  227. hashedPassword := auth.Hash(tmppassword)
  228. err := sysdb.Write("auth", "passhash/"+username, hashedPassword)
  229. if err != nil {
  230. utils.SendErrorResponse(w, err.Error())
  231. return
  232. }
  233. //Finish. Send back the reseted password
  234. utils.SendJSONResponse(w, "\""+tmppassword+"\"")
  235. } else {
  236. utils.SendErrorResponse(w, "Not supported opr")
  237. return
  238. }
  239. }
  240. // Get the user interface info for the user to launch into
  241. func user_getInterfaceInfo(w http.ResponseWriter, r *http.Request) {
  242. userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  243. if err != nil {
  244. //User not logged in
  245. utils.SendErrorResponse(w, "User not logged in")
  246. return
  247. }
  248. interfacingModules := userinfo.GetInterfaceModules()
  249. interfaceModuleInfos := []module.ModuleInfo{}
  250. for _, im := range interfacingModules {
  251. interfaceModuleInfos = append(interfaceModuleInfos, *moduleHandler.GetModuleInfoByID(im))
  252. }
  253. jsonString, _ := json.Marshal(interfaceModuleInfos)
  254. utils.SendJSONResponse(w, string(jsonString))
  255. }
  256. func user_handleUserInfo(w http.ResponseWriter, r *http.Request) {
  257. username, err := authAgent.GetUserName(w, r)
  258. if err != nil {
  259. utils.SendErrorResponse(w, "User not logged in")
  260. return
  261. }
  262. opr, _ := utils.PostPara(r, "opr")
  263. if opr == "" {
  264. //Listing mode
  265. iconData := getUserIcon(username)
  266. userGroup, err := permissionHandler.GetUsersPermissionGroup(username)
  267. if err != nil {
  268. utils.SendErrorResponse(w, "Unable to get user group")
  269. return
  270. }
  271. userGroupNames := []string{}
  272. for _, group := range userGroup {
  273. userGroupNames = append(userGroupNames, group.Name)
  274. }
  275. type returnValue struct {
  276. Username string
  277. Icondata string
  278. Usergroup []string
  279. }
  280. jsonString, _ := json.Marshal(returnValue{
  281. Username: username,
  282. Icondata: iconData,
  283. Usergroup: userGroupNames,
  284. })
  285. utils.SendJSONResponse(w, string(jsonString))
  286. return
  287. } else if opr == "changepw" {
  288. oldpw, _ := utils.PostPara(r, "oldpw")
  289. newpw, _ := utils.PostPara(r, "newpw")
  290. if oldpw == "" || newpw == "" {
  291. utils.SendErrorResponse(w, "Password cannot be empty")
  292. return
  293. }
  294. //valid the old password
  295. hashedPassword := auth.Hash(oldpw)
  296. var passwordInDB string
  297. err = sysdb.Read("auth", "passhash/"+username, &passwordInDB)
  298. if hashedPassword != passwordInDB {
  299. //Old password entry invalid.
  300. utils.SendErrorResponse(w, "Invalid old password.")
  301. return
  302. }
  303. //Logout users from all switchable accounts
  304. authAgent.SwitchableAccountManager.ExpireUserFromAllSwitchableAccountPool(username)
  305. //OK! Change user password
  306. newHashedPassword := auth.Hash(newpw)
  307. sysdb.Write("auth", "passhash/"+username, newHashedPassword)
  308. utils.SendOK(w)
  309. } else if opr == "changeprofilepic" {
  310. picdata, _ := utils.PostPara(r, "picdata")
  311. if picdata != "" {
  312. setUserIcon(username, picdata)
  313. utils.SendOK(w)
  314. } else {
  315. utils.SendErrorResponse(w, "Empty image data received.")
  316. return
  317. }
  318. } else {
  319. utils.SendErrorResponse(w, "Not supported opr")
  320. return
  321. }
  322. }
  323. func user_handleList(w http.ResponseWriter, r *http.Request) {
  324. userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  325. if err != nil {
  326. //This user has not logged in
  327. utils.SendErrorResponse(w, "User not logged in")
  328. return
  329. }
  330. if authAgent.CheckAuth(r) {
  331. entries, _ := sysdb.ListTable("auth")
  332. var results [][]interface{}
  333. for _, keypairs := range entries {
  334. if strings.Contains(string(keypairs[0]), "group/") {
  335. username := strings.Split(string(keypairs[0]), "/")[1]
  336. group := []string{}
  337. //Get user icon if it exists in the database
  338. userIcon := getUserIcon(username)
  339. json.Unmarshal(keypairs[1], &group)
  340. var thisUserInfo []interface{}
  341. thisUserInfo = append(thisUserInfo, username)
  342. thisUserInfo = append(thisUserInfo, group)
  343. thisUserInfo = append(thisUserInfo, userIcon)
  344. thisUserInfo = append(thisUserInfo, username == userinfo.Username)
  345. results = append(results, thisUserInfo)
  346. }
  347. }
  348. jsonString, _ := json.Marshal(results)
  349. utils.SendJSONResponse(w, string(jsonString))
  350. } else {
  351. utils.SendErrorResponse(w, "Permission Denied")
  352. }
  353. }
  354. func getUserIcon(username string) string {
  355. var userIconpath []byte
  356. sysdb.Read("auth", "profilepic/"+username, &userIconpath)
  357. return string(userIconpath)
  358. }
  359. func setUserIcon(username string, base64data string) {
  360. sysdb.Write("auth", "profilepic/"+username, []byte(base64data))
  361. return
  362. }