/code/rest/user_service.go

https://github.com/eyebluecn/tank · Go · 280 lines · 201 code · 54 blank · 25 comment · 70 complexity · ab3281aac0eaf6e5a50daa4c229b1443 MD5 · raw file

  1. package rest
  2. import (
  3. "github.com/eyebluecn/tank/code/core"
  4. "github.com/eyebluecn/tank/code/tool/cache"
  5. "github.com/eyebluecn/tank/code/tool/result"
  6. "github.com/eyebluecn/tank/code/tool/util"
  7. "github.com/eyebluecn/tank/code/tool/uuid"
  8. "net/http"
  9. "os"
  10. "time"
  11. )
  12. //@Service
  13. type UserService struct {
  14. BaseBean
  15. userDao *UserDao
  16. sessionDao *SessionDao
  17. //file lock
  18. locker *cache.Table
  19. matterDao *MatterDao
  20. matterService *MatterService
  21. imageCacheDao *ImageCacheDao
  22. shareDao *ShareDao
  23. shareService *ShareService
  24. downloadTokenDao *DownloadTokenDao
  25. uploadTokenDao *UploadTokenDao
  26. footprintDao *FootprintDao
  27. }
  28. func (this *UserService) Init() {
  29. this.BaseBean.Init()
  30. b := core.CONTEXT.GetBean(this.userDao)
  31. if b, ok := b.(*UserDao); ok {
  32. this.userDao = b
  33. }
  34. b = core.CONTEXT.GetBean(this.sessionDao)
  35. if b, ok := b.(*SessionDao); ok {
  36. this.sessionDao = b
  37. }
  38. b = core.CONTEXT.GetBean(this.matterDao)
  39. if b, ok := b.(*MatterDao); ok {
  40. this.matterDao = b
  41. }
  42. b = core.CONTEXT.GetBean(this.matterService)
  43. if b, ok := b.(*MatterService); ok {
  44. this.matterService = b
  45. }
  46. b = core.CONTEXT.GetBean(this.imageCacheDao)
  47. if b, ok := b.(*ImageCacheDao); ok {
  48. this.imageCacheDao = b
  49. }
  50. b = core.CONTEXT.GetBean(this.shareService)
  51. if b, ok := b.(*ShareService); ok {
  52. this.shareService = b
  53. }
  54. b = core.CONTEXT.GetBean(this.downloadTokenDao)
  55. if b, ok := b.(*DownloadTokenDao); ok {
  56. this.downloadTokenDao = b
  57. }
  58. b = core.CONTEXT.GetBean(this.uploadTokenDao)
  59. if b, ok := b.(*UploadTokenDao); ok {
  60. this.uploadTokenDao = b
  61. }
  62. b = core.CONTEXT.GetBean(this.footprintDao)
  63. if b, ok := b.(*FootprintDao); ok {
  64. this.footprintDao = b
  65. }
  66. //create a lock cache.
  67. this.locker = cache.NewTable()
  68. }
  69. //lock a user's operation. If lock, user cannot operate file.
  70. func (this *UserService) MatterLock(userUuid string) {
  71. cacheItem, err := this.locker.Value(userUuid)
  72. if err != nil {
  73. this.logger.Error("error while get cache" + err.Error())
  74. }
  75. if cacheItem != nil && cacheItem.Data() != nil {
  76. panic(result.BadRequest("file is being operating, retry later"))
  77. }
  78. duration := 12 * time.Hour
  79. this.locker.Add(userUuid, duration, true)
  80. }
  81. //unlock
  82. func (this *UserService) MatterUnlock(userUuid string) {
  83. exist := this.locker.Exists(userUuid)
  84. if exist {
  85. _, err := this.locker.Delete(userUuid)
  86. this.PanicError(err)
  87. } else {
  88. this.logger.Error("unlock error. %s has no matter lock ", userUuid)
  89. }
  90. }
  91. //load session to SessionCache. This method will be invoked in every request.
  92. //authorize by 1. cookie 2. username and password in request form. 3. Basic Auth
  93. func (this *UserService) PreHandle(writer http.ResponseWriter, request *http.Request) {
  94. sessionId := util.GetSessionUuidFromRequest(request, core.COOKIE_AUTH_KEY)
  95. if sessionId != "" {
  96. cacheItem, err := core.CONTEXT.GetSessionCache().Value(sessionId)
  97. if err != nil {
  98. this.logger.Error("occur error will get session cache %s", err.Error())
  99. }
  100. //if no cache. try to find in db.
  101. if cacheItem == nil || cacheItem.Data() == nil {
  102. session := this.sessionDao.FindByUuid(sessionId)
  103. if session != nil {
  104. duration := session.ExpireTime.Sub(time.Now())
  105. if duration <= 0 {
  106. this.logger.Error("login info has expired.")
  107. } else {
  108. user := this.userDao.FindByUuid(session.UserUuid)
  109. if user != nil {
  110. core.CONTEXT.GetSessionCache().Add(sessionId, duration, user)
  111. } else {
  112. this.logger.Error("no user with sessionId %s", session.UserUuid)
  113. }
  114. }
  115. }
  116. }
  117. }
  118. //try to auth by USERNAME_KEY PASSWORD_KEY
  119. cacheItem, err := core.CONTEXT.GetSessionCache().Value(sessionId)
  120. if err != nil {
  121. this.logger.Error("occur error will get session cache %s", err.Error())
  122. }
  123. if cacheItem == nil || cacheItem.Data() == nil {
  124. username := request.FormValue(core.USERNAME_KEY)
  125. password := request.FormValue(core.PASSWORD_KEY)
  126. //try to read from BasicAuth
  127. if username == "" || password == "" {
  128. username, password, _ = request.BasicAuth()
  129. }
  130. if username != "" && password != "" {
  131. user := this.userDao.FindByUsername(username)
  132. if user == nil {
  133. this.logger.Error("%s no such user in db.", username)
  134. } else {
  135. if !util.MatchBcrypt(password, user.Password) {
  136. this.logger.Error("%s password error", username)
  137. } else {
  138. this.logger.Info("load a temp session by username and password.")
  139. timeUUID, _ := uuid.NewV4()
  140. uuidStr := string(timeUUID.String())
  141. request.Form[core.COOKIE_AUTH_KEY] = []string{uuidStr}
  142. core.CONTEXT.GetSessionCache().Add(uuidStr, 10*time.Second, user)
  143. }
  144. }
  145. }
  146. }
  147. }
  148. //find a cache user by its userUuid
  149. func (this *UserService) FindCacheUsersByUuid(userUuid string) []*User {
  150. var users []*User
  151. //let session user work.
  152. core.CONTEXT.GetSessionCache().Foreach(func(key interface{}, cacheItem *cache.Item) {
  153. if cacheItem == nil || cacheItem.Data() == nil {
  154. return
  155. }
  156. if value, ok := cacheItem.Data().(*User); ok {
  157. var user = value
  158. if user.Uuid == userUuid {
  159. users = append(users, user)
  160. }
  161. } else {
  162. this.logger.Error("cache item not store the *User")
  163. }
  164. })
  165. return users
  166. }
  167. //remove cache user by its userUuid
  168. func (this *UserService) RemoveCacheUserByUuid(userUuid string) {
  169. var sessionId interface{}
  170. //let session user work.
  171. core.CONTEXT.GetSessionCache().Foreach(func(key interface{}, cacheItem *cache.Item) {
  172. if cacheItem == nil || cacheItem.Data() == nil {
  173. return
  174. }
  175. if value, ok := cacheItem.Data().(*User); ok {
  176. var user = value
  177. if user.Uuid == userUuid {
  178. sessionId = key
  179. this.logger.Info("sessionId %v", key)
  180. }
  181. } else {
  182. this.logger.Error("cache item not store the *User")
  183. }
  184. })
  185. exists := core.CONTEXT.GetSessionCache().Exists(sessionId)
  186. if exists {
  187. _, err := core.CONTEXT.GetSessionCache().Delete(sessionId)
  188. if err != nil {
  189. this.logger.Error("occur error when deleting cache user.")
  190. }
  191. }
  192. }
  193. //delete user
  194. func (this *UserService) DeleteUser(request *http.Request, currentUser *User) {
  195. //delete from cache
  196. this.logger.Info("delete from cache userUuid = %s", currentUser.Uuid)
  197. this.RemoveCacheUserByUuid(currentUser.Uuid)
  198. //delete download tokens
  199. this.logger.Info("delete download tokens")
  200. this.downloadTokenDao.DeleteByUserUuid(currentUser.Uuid)
  201. //delete upload tokens
  202. this.logger.Info("delete upload tokens")
  203. this.uploadTokenDao.DeleteByUserUuid(currentUser.Uuid)
  204. //delete footprints
  205. this.logger.Info("delete footprints")
  206. this.footprintDao.DeleteByUserUuid(currentUser.Uuid)
  207. //delete session
  208. this.logger.Info("delete session")
  209. this.sessionDao.DeleteByUserUuid(currentUser.Uuid)
  210. //delete shares and bridges
  211. this.logger.Info("elete shares and bridges")
  212. this.shareService.DeleteSharesByUser(request, currentUser)
  213. //delete caches
  214. this.logger.Info("delete caches")
  215. this.imageCacheDao.DeleteByUserUuid(currentUser.Uuid)
  216. //delete matters
  217. this.logger.Info("delete matters")
  218. this.matterDao.DeleteByUserUuid(currentUser.Uuid)
  219. //delete this user
  220. this.logger.Info("delete this user.")
  221. this.userDao.Delete(currentUser)
  222. //delete files from disk.
  223. this.logger.Info("delete files from disk. %s", GetUserSpaceRootDir(currentUser.Username))
  224. err := os.RemoveAll(GetUserSpaceRootDir(currentUser.Username))
  225. this.PanicError(err)
  226. }