sso

verify_token_controller.go 16KB

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