sso

verify_token_controller.go 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strconv"
  6. "time"
  7. "SSO/enums"
  8. "SSO/models"
  9. "SSO/service"
  10. "SSO/utils"
  11. )
  12. type VerifyTokenController struct {
  13. BaseController
  14. }
  15. func (this *VerifyTokenController) Prepare() {
  16. this.EnableXSRF = false
  17. }
  18. // /verifytoken [post]
  19. // @param token:string
  20. // @param app_type:int
  21. // @param ip:string
  22. // @param session_id:string 客户端(浏览器)sessionID
  23. // return 说明:所有数值型的 key 和 value 都转换为了 string 类型
  24. func (this *VerifyTokenController) VerifyToken() {
  25. token := this.GetString("token")
  26. clientSessionId := this.GetString("session_id")
  27. app_type, _ := this.GetInt("app_type", 0)
  28. // if app_type != 1 && app_type != 3 && app_type != 5 {
  29. // this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
  30. // this.ServeJSON()
  31. // return
  32. // }
  33. if url := service.GetAppURLWithAppType(app_type); len(url) == 0 {
  34. this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
  35. this.ServeJSON()
  36. return
  37. }
  38. utils.TraceLog("clientSessionId: %v", clientSessionId)
  39. if len(clientSessionId) == 0 {
  40. this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
  41. this.ServeJSON()
  42. return
  43. }
  44. if len(token) <= 24 {
  45. this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeInvalidToken)
  46. this.ServeJSON()
  47. return
  48. }
  49. redisClient := service.RedisClient()
  50. defer redisClient.Close()
  51. mobile := token[24:]
  52. // locToken, _ := redisClient.Get(fmt.Sprintf("sso_token_%v", mobile)).Result()
  53. locToken, _ := redisClient.Get(fmt.Sprintf("sso_token_%v", clientSessionId)).Result()
  54. utils.TraceLog("request token: %v \t server cached token: %v", token, locToken)
  55. var isUserInfoFromRedis bool = false
  56. if token == locToken {
  57. infoStr, getCachedInfoErr := redisClient.Get("sso_admin_user_info_" + mobile).Result()
  58. if getCachedInfoErr != nil {
  59. utils.WarningLog("redis 获取管理员用户信息失败:%v", getCachedInfoErr)
  60. infoStr = ""
  61. }
  62. infoStr = ""
  63. var userInfo map[string]interface{}
  64. if len(infoStr) == 0 {
  65. utils.TraceLog("%v data is from operation", "sso_admin_user_info_"+mobile)
  66. isUserInfoFromRedis = false
  67. info, getInfoErr := this.GetAdminUserAllInfo(mobile)
  68. if getInfoErr != nil {
  69. this.Data["json"] = enums.MakeFailResponseJSONWithSGJError(getInfoErr)
  70. this.ServeJSON()
  71. return
  72. }
  73. userInfo = info
  74. infoStr_b, _ := json.Marshal(userInfo)
  75. redisClient.Set("sso_admin_user_info_"+mobile, string(infoStr_b), time.Duration(2)*time.Minute)
  76. } else {
  77. utils.TraceLog("%v data is from redis cache", "sso_admin_user_info_"+mobile)
  78. isUserInfoFromRedis = true
  79. userInfo = make(map[string]interface{})
  80. json.Unmarshal([]byte(infoStr), &userInfo)
  81. }
  82. var adminUser models.AdminUser
  83. json.Unmarshal([]byte(userInfo["admin_user"].(string)), &adminUser)
  84. // 如果有登录记录,取出最近登录记录中的机构和应用
  85. lastLoginLog, getLastLoginLogErr := service.GetAdminUserLastLoginLog(adminUser.Id, app_type)
  86. if getLastLoginLogErr != nil {
  87. utils.ErrorLog("数据错误:查找mobile = %v的用户最近一次登录记录时错误:%v", mobile, getLastLoginLogErr)
  88. }
  89. currentOrgId := 0
  90. currentAppId := 0
  91. if lastLoginLog != nil {
  92. currentOrgId = lastLoginLog.OrgId
  93. currentAppId = lastLoginLog.AppId
  94. } else {
  95. if isUserInfoFromRedis {
  96. orgIds := userInfo["org_ids"].([]interface{})
  97. for _, oid := range orgIds {
  98. orgApps := userInfo["org_apps"].(map[string]interface{})[oid.(string)]
  99. for _, appMapJSON := range orgApps.(map[string]interface{}) {
  100. var appMap map[string]interface{}
  101. json.Unmarshal([]byte(appMapJSON.(string)), &appMap)
  102. a_t := int(appMap["app_type"].(float64))
  103. if a_t == app_type {
  104. currentOrgId = int(appMap["org_id"].(float64))
  105. currentAppId = int(appMap["id"].(float64))
  106. break
  107. }
  108. }
  109. if currentOrgId != 0 && currentAppId != 0 {
  110. break
  111. }
  112. }
  113. } else {
  114. orgIds := userInfo["org_ids"].([]string)
  115. for _, oid := range orgIds {
  116. orgApps := userInfo["org_apps"].(map[string]interface{})[oid]
  117. for _, appMapJSON := range orgApps.(map[string]string) {
  118. var appMap map[string]interface{}
  119. json.Unmarshal([]byte(appMapJSON), &appMap)
  120. a_t := int(appMap["app_type"].(float64))
  121. if a_t == app_type {
  122. currentOrgId = int(appMap["org_id"].(float64))
  123. currentAppId = int(appMap["id"].(float64))
  124. break
  125. }
  126. }
  127. if currentOrgId != 0 && currentAppId != 0 {
  128. break
  129. }
  130. }
  131. }
  132. }
  133. // for key, value := range userInfo {
  134. // if key == "purviews" || key == "purview_urlfors" {
  135. // continue
  136. // }
  137. // utils.TraceLog("%v: %v", key, value)
  138. // }
  139. utils.TraceLog("lastLoginLog : %v", lastLoginLog)
  140. utils.TraceLog("currentOrgId : %v", currentOrgId)
  141. utils.TraceLog("currentAppId : %v", currentAppId)
  142. if currentOrgId == 0 || currentAppId == 0 {
  143. if adminUser.IsSuperAdmin == true {
  144. this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeNeverCreateTypeApp)
  145. this.ServeJSON()
  146. } else {
  147. this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeContactSuperAdminCreateTypeApp)
  148. this.ServeJSON()
  149. }
  150. return
  151. }
  152. returnJSON := make(map[string]interface{})
  153. returnJSON["admin_user"] = userInfo["admin_user"]
  154. returnJSON["org_ids"] = userInfo["org_ids"]
  155. returnJSON["orgs"] = userInfo["orgs"]
  156. returnJSON["org_app_ids"] = userInfo["org_app_ids"]
  157. returnJSON["org_apps"] = userInfo["org_apps"]
  158. returnJSON["app_to_org_ids"] = userInfo["app_to_org_ids"]
  159. returnJSON["current_org_id"] = strconv.Itoa(currentOrgId)
  160. returnJSON["current_app_id"] = strconv.Itoa(currentAppId)
  161. returnJSON["purviews"] = userInfo["purviews"]
  162. returnJSON["purview_urlfors"] = userInfo["purview_urlfors"]
  163. returnJSON["app_roles"] = userInfo["app_roles"]
  164. returnJSON["org_subscibes"] = userInfo["org_subscibes"]
  165. this.Data["json"] = enums.MakeSuccessResponseJSON(returnJSON)
  166. this.ServeJSON()
  167. // 插入一条登录记录
  168. ip := this.GetString("ip")
  169. loginLog := &models.AdminUserLoginLog{
  170. AdminUserId: adminUser.Id,
  171. OrgId: currentOrgId,
  172. AppId: currentAppId,
  173. IP: ip,
  174. OperateType: 1,
  175. AppType: int8(app_type),
  176. CreateTime: time.Now().Unix(),
  177. }
  178. if insertErr := service.InsertLoginLog(loginLog); insertErr != nil {
  179. utils.ErrorLog("为手机号为%v的用户插入一条登录记录失败:%v", mobile, insertErr)
  180. }
  181. } else {
  182. this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeInvalidToken)
  183. this.ServeJSON()
  184. }
  185. }
  186. // 验证 token 之后需要返回的管理员用户的所有信息,包括:基本用户信息,所属的所有机构,机构下的所有应用
  187. // map 的数据格式为
  188. /*
  189. "admin_user": { AdminUser's json },
  190. "org_ids": [1, 2, 3],
  191. "orgs": { (org_id: Org_Obj)
  192. 1: { Org's json },
  193. 2: { Org's json },
  194. },
  195. "org_app_ids": { (org_id: org_app_ids)
  196. 1: [11, 12, 13],
  197. 2: [21, 22, 23],
  198. },
  199. "org_apps": { (org_id: {app_id: OrgApp_Obj})
  200. 1: {
  201. 11: { OrgApp's json },
  202. 12: { OrgApp's json },
  203. },
  204. 2: {
  205. 21: { OrgApp's json },
  206. 22: { OrgApp's json },
  207. },
  208. },
  209. "app_to_org_ids": { (app_id: org_id)
  210. 11: 1,
  211. 12: 1,
  212. 21: 2,
  213. 22: 2,
  214. },
  215. "app_roles": { (app_id: App_Role Obj)
  216. 11: {App_Role's json},
  217. 12: {App_Role's json},
  218. 21: {App_Role's json},
  219. },
  220. "purviews": { (app_id: [processed Purviews' json])
  221. 11: [
  222. {Purview's json .childs[
  223. {Purview's json},
  224. {Purview's json},
  225. ]},
  226. {Purview's json},
  227. ],
  228. 12: [
  229. {Purview's json},
  230. {Purview's json},
  231. ],
  232. }
  233. "purview_urlfors": { (app_id: [url_for])
  234. 11: [
  235. "Controller1.Action1",
  236. "Controller1.Action2",
  237. "Controller2.Action1",
  238. "Controller2.Action2",
  239. ],
  240. }
  241. 应当注意的是,屈服于 Golang 令人恶心的类型机制,这里将所有数值型的 key 或 value 全部转成了 string
  242. */
  243. func (this *VerifyTokenController) GetAdminUserAllInfo(mobile string) (map[string]interface{}, *enums.SGJError) {
  244. adminUser := service.GetAdminUserWithMobile(mobile)
  245. if adminUser == nil {
  246. utils.ErrorLog("数据错误:查找不到mobile = %v的用户", mobile)
  247. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  248. }
  249. orgs, getOrgErr := service.GetAdminUserAllOrgWithUID(adminUser.Id, adminUser.IsSuperAdmin)
  250. if getOrgErr != nil {
  251. utils.ErrorLog("数据错误:查找不到mobile = %v的用户所属的机构:%v", mobile, getOrgErr)
  252. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  253. }
  254. if len(orgs) == 0 {
  255. utils.ErrorLog("数据错误:查找不到mobile = %v的用户所属的机构", mobile)
  256. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  257. }
  258. orgIds := make([]string, 0, len(orgs))
  259. orgJSONs := make(map[string]string)
  260. orgAppIds := make(map[string]interface{})
  261. orgApps := make(map[string]interface{})
  262. app_to_org_ids := make(map[string]string)
  263. app_purviewJSONs := make(map[string]string)
  264. app_purview_urls := make(map[string]string)
  265. app_roles := make(map[string]string)
  266. org_subscibes := make(map[string]string)
  267. for _, org := range orgs {
  268. apps, getAppsErr := service.GetAdminUserAllOrgApp(adminUser.Id, org.Id)
  269. if getAppsErr != nil {
  270. utils.ErrorLog("数据错误:查找mobile = %v的用户所属机构ID为%v下的应用时错误:%v", mobile, org.Id, getAppsErr)
  271. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  272. }
  273. if adminUser.IsSuperAdmin {
  274. didCreateNewApp, createAppErr := this._createAppIfNeeded(adminUser.Id, org.Id, apps)
  275. if createAppErr != nil {
  276. return nil, createAppErr
  277. }
  278. if didCreateNewApp {
  279. apps, getAppsErr = service.GetAdminUserAllOrgApp(adminUser.Id, org.Id)
  280. if getAppsErr != nil {
  281. utils.ErrorLog("数据错误:查找mobile = %v的用户所属机构ID为%v下的应用时错误:%v", mobile, org.Id, getAppsErr)
  282. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  283. }
  284. }
  285. } else {
  286. if len(apps) == 0 {
  287. continue
  288. }
  289. }
  290. subscibe, getSubscibeErr := service.GetOrgServeSubscibe(org.Id)
  291. if getSubscibeErr != nil {
  292. utils.ErrorLog("获取机构订阅信息失败:%v", getSubscibeErr)
  293. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  294. } else if subscibe == nil {
  295. now := time.Now()
  296. nextMonthDate := now.AddDate(0, 0, 30)
  297. subscibe = &models.ServeSubscibe{
  298. OrgId: int64(org.Id),
  299. PeriodStart: now.Unix(),
  300. PeriodEnd: nextMonthDate.Unix(),
  301. Status: 1,
  302. CreatedTime: now.Unix(),
  303. UpdatedTime: now.Unix(),
  304. State: 2,
  305. }
  306. createErr := service.CreateOrgServeSubscibe(subscibe)
  307. if createErr != nil {
  308. utils.ErrorLog(" 创建机构订阅信息失败:%v", createErr)
  309. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  310. }
  311. }
  312. subscibeJSON_b, _ := json.Marshal(subscibe)
  313. subscibeJSON := string(subscibeJSON_b)
  314. org_subscibes[strconv.Itoa(org.Id)] = subscibeJSON
  315. orgJSON_b, _ := json.Marshal(org)
  316. orgJSONStr := string(orgJSON_b)
  317. orgJSONs[strconv.Itoa(org.Id)] = orgJSONStr
  318. orgIds = append(orgIds, strconv.Itoa(org.Id))
  319. appIds := make([]string, 0, len(apps))
  320. appJSONs := make(map[string]string)
  321. for _, app := range apps {
  322. appJSON_b, _ := json.Marshal(app)
  323. appJSONStr := string(appJSON_b)
  324. appJSONs[strconv.Itoa(app.Id)] = appJSONStr
  325. appIds = append(appIds, strconv.Itoa(app.Id))
  326. app_to_org_ids[strconv.Itoa(app.Id)] = strconv.Itoa(org.Id)
  327. if adminUser.IsSuperAdmin {
  328. urlfors, purviews, getPurviewErr := service.GetSuperAdminUsersPurviewTreeAndUrlfors(app.AppType)
  329. if getPurviewErr != nil {
  330. utils.ErrorLog("数据错误:查找超级管理员的类型为%v的应用的权限时错误:%v", app.AppType, getPurviewErr)
  331. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  332. } else {
  333. purviewJSONs_b, _ := json.Marshal(purviews)
  334. app_purviewJSONs[strconv.Itoa(app.Id)] = string(purviewJSONs_b)
  335. urlforJSON_b, _ := json.Marshal(urlfors)
  336. app_purview_urls[strconv.Itoa(app.Id)] = string(urlforJSON_b)
  337. }
  338. } else {
  339. urlfors, purviews, getPurviewErr := service.GetGeneralAdminUsersPurviewTreeAndUrlfors(adminUser.Id, app.Id)
  340. if getPurviewErr != nil {
  341. utils.ErrorLog("数据错误:查找id为%v普通管理员的id为%v的应用的权限时错误:%v", adminUser.Id, app.Id, getPurviewErr)
  342. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  343. } else {
  344. purviewJSONs_b, _ := json.Marshal(purviews)
  345. app_purviewJSONs[strconv.Itoa(app.Id)] = string(purviewJSONs_b)
  346. urlforJSON_b, _ := json.Marshal(urlfors)
  347. app_purview_urls[strconv.Itoa(app.Id)] = string(urlforJSON_b)
  348. }
  349. }
  350. appRole, getAppRoleErr := service.GetAppRole(adminUser.Id, org.Id, app.Id)
  351. if getAppRoleErr != nil {
  352. utils.ErrorLog("数据错误:查找id=%v,orgid=%v,appid=%v的用户信息时失败:%v", adminUser.Id, org.Id, app.Id, getAppRoleErr)
  353. return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
  354. }
  355. appRoleJSON_b, _ := json.Marshal(appRole)
  356. app_roles[strconv.Itoa(app.Id)] = string(appRoleJSON_b)
  357. }
  358. orgAppIds[strconv.Itoa(org.Id)] = appIds
  359. orgApps[strconv.Itoa(org.Id)] = appJSONs
  360. }
  361. adminUserJSON_b, _ := json.Marshal(adminUser)
  362. info := make(map[string]interface{})
  363. info["admin_user"] = string(adminUserJSON_b)
  364. info["org_ids"] = orgIds
  365. info["orgs"] = orgJSONs
  366. info["org_app_ids"] = orgAppIds
  367. info["org_apps"] = orgApps
  368. info["app_to_org_ids"] = app_to_org_ids
  369. info["app_roles"] = app_roles
  370. info["purviews"] = app_purviewJSONs
  371. info["purview_urlfors"] = app_purview_urls
  372. info["org_subscibes"] = org_subscibes
  373. return info, nil
  374. }
  375. func (this *VerifyTokenController) _createAppIfNeeded(adminUserID int, orgID int, didCreatedApps []*models.OrgApp) (bool, *enums.SGJError) {
  376. // 已创建的应用的信息
  377. did_patient_manage_create := false
  378. did_dialysis_manage_create := false
  379. did_cdm_manage_create := false
  380. did_mall_manage_create := false
  381. for _, app := range didCreatedApps {
  382. if app.AppType == 1 {
  383. did_patient_manage_create = true
  384. } else if app.AppType == 3 {
  385. did_dialysis_manage_create = true
  386. } else if app.AppType == 4 {
  387. did_cdm_manage_create = true
  388. } else if app.AppType == 5 {
  389. did_mall_manage_create = true
  390. }
  391. }
  392. // 自动创建所有应用
  393. didCreateNew := false
  394. if did_patient_manage_create == false {
  395. err := service.CreateOrgApp(adminUserID, orgID, 1, false)
  396. if err != nil {
  397. utils.ErrorLog("自动创建酷医聚客应用失败:%v", err)
  398. return false, &enums.SGJError{Code: enums.ErrorCodeDataException}
  399. }
  400. didCreateNew = true
  401. }
  402. if did_dialysis_manage_create == false {
  403. err := service.CreateOrgApp(adminUserID, orgID, 3, false)
  404. if err != nil {
  405. utils.ErrorLog("自动创建透析管理应用失败:%v", err)
  406. return false, &enums.SGJError{Code: enums.ErrorCodeDataException}
  407. }
  408. didCreateNew = true
  409. }
  410. if did_cdm_manage_create == false {
  411. err := service.CreateOrgApp(adminUserID, orgID, 4, false)
  412. if err != nil {
  413. utils.ErrorLog("自动创建慢病管理应用失败:%v", err)
  414. return false, &enums.SGJError{Code: enums.ErrorCodeDataException}
  415. }
  416. didCreateNew = true
  417. }
  418. if did_mall_manage_create == false {
  419. err := service.CreateOrgApp(adminUserID, orgID, 5, false)
  420. if err != nil {
  421. utils.ErrorLog("自动创建微商城应用失败:%v", err)
  422. return false, &enums.SGJError{Code: enums.ErrorCodeDataException}
  423. }
  424. didCreateNew = true
  425. }
  426. return didCreateNew, nil
  427. }