verify_login_token_service.go 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. package service
  2. import (
  3. "encoding/json"
  4. "github.com/jinzhu/gorm"
  5. "io/ioutil"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "time"
  10. "XT_New/models"
  11. "XT_New/utils"
  12. "fmt"
  13. "github.com/astaxie/beego"
  14. )
  15. type AdminUserInfo struct {
  16. AdminUser *models.AdminUser `json:"user"`
  17. CurrentOrgId int64 `json:"current_org_id"`
  18. CurrentAppId int64 `json:"current_app_id"`
  19. OrgIds []int64 `json:"org_ids"`
  20. Orgs map[int64]*models.Org `json:"orgs"`
  21. OrgAppIds map[int64][]int64 `json:"org_app_ids"`
  22. OrgApps map[int64](map[int64]*models.OrgApp) `json:"org_apps"`
  23. App2OrgIds map[int64]int64 `json:"app_to_org_ids"`
  24. AppRoles map[int64]*models.App_Role `json:"app_roles"`
  25. AppPurviews map[int64][]*models.Purview `json:"app_purviews"`
  26. AppUrlfors map[int64][]string `json:"app_urlfors"`
  27. Subscibes map[int64]*models.ServeSubscibe `json:"org_subscibes"`
  28. }
  29. type verifyTokenError struct {
  30. Msg string
  31. }
  32. func (e *verifyTokenError) Error() string {
  33. return e.Msg
  34. }
  35. // 验证 token 成功后返回的管理员用户的所有信息,包括:基本用户信息,所属的所有机构,机构下的所有应用,应用的用户权限
  36. // map 的数据格式为
  37. /*
  38. "admin_user": { AdminUser's json },
  39. current_org_id: 1,
  40. current_app_id: 11,
  41. "org_ids": [1, 2, 3],
  42. "orgs": { (org_id: Org_Obj)
  43. 1: { Org's json },
  44. 2: { Org's json },
  45. },
  46. "org_app_ids": { (org_id: org_app_ids)
  47. 1: [11, 12, 13],
  48. 2: [21, 22, 23],
  49. },
  50. "org_apps": { (org_id: {app_id: OrgApp_Obj})
  51. 1: {
  52. 11: { OrgApp's json },
  53. 12: { OrgApp's json },
  54. },
  55. 2: {
  56. 21: { OrgApp's json },
  57. 22: { OrgApp's json },
  58. },
  59. },
  60. "app_to_org_ids": { (app_id: org_id)
  61. 11: 1,
  62. 12: 1,
  63. 21: 2,
  64. 22: 2,
  65. },
  66. "app_roles": { (app_id: App_Role Obj)
  67. 11: {App_Role's json},
  68. 12: {App_Role's json},
  69. 21: {App_Role's json},
  70. },
  71. "purviews": { (app_id: [processed Purviews' json])
  72. 11: [
  73. {Purview's json .childs[
  74. {Purview's json},
  75. {Purview's json},
  76. ]},
  77. {Purview's json},
  78. ],
  79. 12: [
  80. {Purview's json},
  81. {Purview's json},
  82. ],
  83. },
  84. "purview_urlfors": { (app_id: [url_for])
  85. 11: [
  86. "Controller1.Action1",
  87. "Controller1.Action2",
  88. "Controller2.Action1",
  89. "Controller2.Action2",
  90. ],
  91. }
  92. 应当注意的是,屈服于 Golang 令人恶心的类型机制,这里将所有数值型的 key 或 value 全部转成了 string
  93. */
  94. // 解析用户信息,并返回
  95. func VerifyToken(token string, ip string, sessionID string) (*AdminUserInfo, error, int) {
  96. // if len(sessionID) == 0 {
  97. // return nil, &verifyTokenError{"sessionID 为空"}
  98. // }
  99. ssoDomain := beego.AppConfig.String("sso_domain")
  100. api := ssoDomain + "/verifytoken"
  101. values := make(url.Values)
  102. values.Set("token", token)
  103. values.Set("app_type", "3")
  104. values.Set("ip", ip)
  105. values.Set("session_id", sessionID)
  106. resp, requestErr := http.PostForm(api, values)
  107. fmt.Println("resp", resp)
  108. if requestErr != nil {
  109. utils.ErrorLog("请求验证 sso token 接口失败: %v", requestErr)
  110. return nil, requestErr, 0
  111. }
  112. defer resp.Body.Close()
  113. body, ioErr := ioutil.ReadAll(resp.Body)
  114. if ioErr != nil {
  115. utils.ErrorLog("验证 sso token 接口返回数据读取失败: %v", ioErr)
  116. return nil, ioErr, 0
  117. }
  118. var respJSON map[string]interface{}
  119. utils.InfoLog(string(body))
  120. if err := json.Unmarshal([]byte(string(body)), &respJSON); err != nil {
  121. utils.ErrorLog("验证 sso token 接口返回数据解析JSON失败: %v", err)
  122. return nil, err, 0
  123. }
  124. fmt.Println(respJSON)
  125. if respJSON["state"].(float64) != 1 {
  126. msg := respJSON["msg"].(string)
  127. utils.ErrorLog("验证 sso token 接口请求失败: %v", msg)
  128. return nil, &verifyTokenError{"验证 sso token 接口请求失败"}, int(respJSON["code"].(float64))
  129. } else {
  130. utils.SuccessLog("验证 sso token 成功")
  131. return processAdminUserInfo(respJSON["data"].(map[string]interface{})), nil, 0
  132. }
  133. }
  134. func processAdminUserInfo(data map[string]interface{}) *AdminUserInfo {
  135. adminUser := processAdminUser(data)
  136. currentOrgId, currentAppId := processCurrentOrgIDAndAppID(data)
  137. orgIds := processOrgIds(data)
  138. orgs := processOrgs(data)
  139. orgAppIds := processOrgAppIds(data)
  140. orgApps := processOrgApps(data)
  141. //app2OrgIds := processApp2OrgIds(data)
  142. appRoles := processAppRoles(data)
  143. appPurviews := processPurviews(data)
  144. appUrlfors := processPurviewUrlfors(data)
  145. //orgSubscibes := processOrgSubscibes(data)
  146. sessionAdminUserInfo := &AdminUserInfo{
  147. AdminUser: adminUser,
  148. CurrentOrgId: currentOrgId,
  149. CurrentAppId: currentAppId,
  150. OrgIds: orgIds,
  151. Orgs: orgs,
  152. OrgAppIds: orgAppIds,
  153. OrgApps: orgApps,
  154. //App2OrgIds: app2OrgIds,
  155. AppRoles: appRoles,
  156. AppPurviews: appPurviews,
  157. AppUrlfors: appUrlfors,
  158. //Subscibes: orgSubscibes,
  159. }
  160. return sessionAdminUserInfo
  161. }
  162. // "admin_user": { AdminUser's json },
  163. func processAdminUser(data map[string]interface{}) *models.AdminUser {
  164. userJSONStr := data["admin_user"].(string)
  165. var adminUser models.AdminUser
  166. if err := json.Unmarshal([]byte(userJSONStr), &adminUser); err != nil {
  167. utils.ErrorLog("解析用户信息失败:%v", err)
  168. return nil
  169. } else {
  170. return &adminUser
  171. }
  172. }
  173. // current_org_id: 1,
  174. // current_app_id: 11,
  175. func processCurrentOrgIDAndAppID(data map[string]interface{}) (int64, int64) {
  176. orgIDStr := data["current_org_id"].(string)
  177. appIDStr := data["current_app_id"].(string)
  178. orgID, _ := strconv.Atoi(orgIDStr)
  179. appID, _ := strconv.Atoi(appIDStr)
  180. return int64(orgID), int64(appID)
  181. }
  182. // "org_ids": [1, 2, 3],
  183. func processOrgIds(data map[string]interface{}) []int64 {
  184. orgIdStrs := data["org_ids"].([]interface{})
  185. orgIds := make([]int64, 0, len(orgIdStrs))
  186. for _, idstr := range orgIdStrs {
  187. id, _ := strconv.Atoi(idstr.(string))
  188. orgIds = append(orgIds, int64(id))
  189. }
  190. return orgIds
  191. }
  192. // "orgs": { (org_id: Org_Obj)
  193. // 1: { Org's json },
  194. // 2: { Org's json },
  195. // },
  196. func processOrgs(data map[string]interface{}) map[int64]*models.Org {
  197. orgJSONs := data["orgs"].(map[string]interface{})
  198. orgs := make(map[int64]*models.Org)
  199. for orgIdStr, orgJSON := range orgJSONs {
  200. orgId, _ := strconv.Atoi(orgIdStr)
  201. var org models.Org
  202. json.Unmarshal([]byte(orgJSON.(string)), &org)
  203. orgs[int64(orgId)] = &org
  204. }
  205. return orgs
  206. }
  207. // "org_app_ids": { (org_id: org_app_ids)
  208. // 1: [11, 12, 13],
  209. // 2: [21, 22, 23],
  210. // },
  211. func processOrgAppIds(data map[string]interface{}) map[int64][]int64 {
  212. orgAppIdStrs := data["org_app_ids"].(map[string]interface{})
  213. orgAppIds := make(map[int64][]int64)
  214. for orgIdStr, appIdStrs := range orgAppIdStrs {
  215. orgId, _ := strconv.Atoi(orgIdStr)
  216. appIds := make([]int64, 0, len(appIdStrs.([]interface{})))
  217. for _, appIdStr := range appIdStrs.([]interface{}) {
  218. appId, _ := strconv.Atoi(appIdStr.(string))
  219. appIds = append(appIds, int64(appId))
  220. }
  221. orgAppIds[int64(orgId)] = appIds
  222. }
  223. return orgAppIds
  224. }
  225. // "org_apps": { (org_id: {app_id: OrgApp_Obj})
  226. // 1: {
  227. // 11: { OrgApp's json },
  228. // 12: { OrgApp's json },
  229. // },
  230. // 2: {
  231. // 21: { OrgApp's json },
  232. // 22: { OrgApp's json },
  233. // },
  234. // },
  235. func processOrgApps(data map[string]interface{}) map[int64]map[int64]*models.OrgApp {
  236. orgAppJSONs := data["org_apps"].(map[string]interface{})
  237. orgApps := make(map[int64]map[int64]*models.OrgApp)
  238. for orgIdStr, appJSONStrMap := range orgAppJSONs {
  239. orgId, _ := strconv.Atoi(orgIdStr)
  240. apps := make(map[int64]*models.OrgApp)
  241. for appIdStr, appJSONStr := range appJSONStrMap.(map[string]interface{}) {
  242. appId, _ := strconv.Atoi(appIdStr)
  243. var app models.OrgApp
  244. json.Unmarshal([]byte(appJSONStr.(string)), &app)
  245. apps[int64(appId)] = &app
  246. }
  247. orgApps[int64(orgId)] = apps
  248. }
  249. return orgApps
  250. }
  251. // "app_to_org_ids": { (app_id: org_id)
  252. // 11: 1,
  253. // 12: 1,
  254. // 21: 2,
  255. // 22: 2,
  256. // },
  257. func processApp2OrgIds(data map[string]interface{}) map[int64]int64 {
  258. app2OrgIdStrs := data["app_to_org_ids"].(map[string]interface{})
  259. app2OrgIds := make(map[int64]int64)
  260. for appIdStr, orgIdStr := range app2OrgIdStrs {
  261. orgId, _ := strconv.Atoi(orgIdStr.(string))
  262. appId, _ := strconv.Atoi(appIdStr)
  263. app2OrgIds[int64(appId)] = int64(orgId)
  264. }
  265. return app2OrgIds
  266. }
  267. // "app_roles": { (app_id: App_Role Obj)
  268. // 11: {App_Role's json},
  269. // 12: {App_Role's json},
  270. // 21: {App_Role's json},
  271. // },
  272. func processAppRoles(data map[string]interface{}) map[int64]*models.App_Role {
  273. appRoleJSONs := data["app_roles"].(map[string]interface{})
  274. appRoles := make(map[int64]*models.App_Role)
  275. for appIDStr, appRoleJSON := range appRoleJSONs {
  276. appID, _ := strconv.Atoi(appIDStr)
  277. var appRole models.App_Role
  278. json.Unmarshal([]byte(appRoleJSON.(string)), &appRole)
  279. appRoles[int64(appID)] = &appRole
  280. }
  281. return appRoles
  282. }
  283. // "purviews": { (app_id: [processed Purviews' json])
  284. // 11: [
  285. // {Purview's json .childs[
  286. // {Purview's json},
  287. // {Purview's json},
  288. // ]},
  289. // {Purview's json},
  290. // ],
  291. // 12: [
  292. // {Purview's json},
  293. // {Purview's json},
  294. // ],
  295. // },
  296. func processPurviews(data map[string]interface{}) map[int64][]*models.Purview {
  297. appPurviewJSONsStrs := data["purviews"].(map[string]interface{})
  298. appPurviews := make(map[int64][]*models.Purview)
  299. for appIdStr, purviewJSONsStr := range appPurviewJSONsStrs {
  300. appId, _ := strconv.Atoi(appIdStr)
  301. var purviews []*models.Purview
  302. json.Unmarshal([]byte(purviewJSONsStr.(string)), &purviews)
  303. // setLinkForPurviews(purviews)
  304. appPurviews[int64(appId)] = purviews
  305. }
  306. return appPurviews
  307. }
  308. // func setLinkForPurviews(purviews []*models.Purview) {
  309. // for _, purview := range purviews {
  310. // if len(purview.Urlfor) == 0 {
  311. // purview.Link = ""
  312. // } else {
  313. // purview.Link = beego.URLFor(purview.Urlfor)
  314. // }
  315. // if purview.Childs == nil {
  316. // purview.Childs = make([]*models.Purview, 0)
  317. // } else {
  318. // setLinkForPurviews(purview.Childs)
  319. // }
  320. // // utils.TraceLog("%+v", purview)
  321. // }
  322. // }
  323. // "purview_urlfors": { (app_id: [url_for])
  324. // 11: [
  325. // "Controller1.Action1",
  326. // "Controller1.Action2",
  327. // "Controller2.Action1",
  328. // "Controller2.Action2",
  329. // ],
  330. // }
  331. func processPurviewUrlfors(data map[string]interface{}) map[int64][]string {
  332. appUrlforsStrs := data["purview_urlfors"].(map[string]interface{})
  333. appUrlfors := make(map[int64][]string)
  334. for appIdStr, urlforsStr := range appUrlforsStrs {
  335. appId, _ := strconv.Atoi(appIdStr)
  336. var urlfors []string
  337. json.Unmarshal([]byte(urlforsStr.(string)), &urlfors)
  338. appUrlfors[int64(appId)] = urlfors
  339. }
  340. return appUrlfors
  341. }
  342. // "org_subscibes": { (org_id: ServeSubscibe)
  343. // 11: {ServeSubscibe's json}
  344. // },
  345. func processOrgSubscibes(data map[string]interface{}) map[int64]*models.ServeSubscibe {
  346. subscibeJSONs := data["org_subscibes"].(map[string]interface{})
  347. subscibes := make(map[int64]*models.ServeSubscibe)
  348. for orgIDStr, subscibeJSON := range subscibeJSONs {
  349. orgID, _ := strconv.Atoi(orgIDStr)
  350. var subscibe models.ServeSubscibe
  351. json.Unmarshal([]byte(subscibeJSON.(string)), &subscibe)
  352. subscibes[int64(orgID)] = &subscibe
  353. }
  354. return subscibes
  355. }
  356. func ModifyPassword(adminID int64, password string) error {
  357. err := writeUserDb.Model(&models.AdminUser{}).Where("id = ? AND status = 1", adminID).Updates(map[string]interface{}{"password": password, "mtime": time.Now().Unix()}).Error
  358. return err
  359. }
  360. func GetPurviewById(ids string) ([]*models.Purview, error) {
  361. var originPurviews []*models.Purview
  362. getPurviewErr := readUserDb.Model(&models.Purview{}).Where(fmt.Sprintf("id in (%v) and status = 1", ids)).Order("listorder asc").Order("id asc").Find(&originPurviews).Error
  363. return originPurviews, getPurviewErr
  364. }
  365. func FindAdminUserIDA(id int64) (role models.App_Role, err error) {
  366. err = readUserDb.Model(&models.App_Role{}).Where("id = ?", id).First(&role).Error
  367. return
  368. }
  369. func GetSuperAdminUsersPurviewTreeAndUrlfors(appType int) ([]string, []*models.Purview, error) {
  370. originPurviews, getPurviewErr := getAllOriginPurviews(appType)
  371. if getPurviewErr != nil {
  372. return nil, nil, getPurviewErr
  373. }
  374. urlfors, processedPurviews := getUrlforsAndProcessPurviews2Tree(originPurviews)
  375. return urlfors, processedPurviews, nil
  376. }
  377. // 加工这些规则:树形化;以及从中取出不为空的 urlfor
  378. // 正确结果的前提是 originPurviews 以 parentid asc 排好序了的
  379. func getUrlforsAndProcessPurviews2Tree(originPurviews []*models.Purview) ([]string, []*models.Purview) {
  380. processedPurviews := make([]*models.Purview, 0)
  381. pid_childs := make(map[int][]*models.Purview)
  382. urlfors := make([]string, 0, len(originPurviews))
  383. for _, purview := range originPurviews {
  384. if len(purview.Urlfor) != 0 {
  385. urlfors = append(urlfors, purview.Urlfor)
  386. }
  387. // warning:下面这个算法只适用最多两层树形结构的菜单,对于两层以上的会丢失掉第三层及其以下的节点
  388. // 因为取出 originPurviews 的时候已经排过序了,所以顶级节点肯定最先处理,不需要担心子节点比父节点先处理
  389. if purview.Parentid == 0 {
  390. processedPurviews = append(processedPurviews, purview)
  391. } else {
  392. childs := pid_childs[int(purview.Parentid)]
  393. if pid_childs[int(purview.Parentid)] == nil {
  394. childs = make([]*models.Purview, 0)
  395. }
  396. childs = append(childs, purview)
  397. pid_childs[int(purview.Parentid)] = childs
  398. }
  399. }
  400. for _, proPurview := range processedPurviews {
  401. proPurview.Childs = pid_childs[int(proPurview.Id)]
  402. }
  403. return urlfors, processedPurviews
  404. }
  405. func getAllOriginPurviews(appType int) ([]*models.Purview, error) {
  406. var purviews []*models.Purview
  407. getPurviewErr := readUserDb.Model(models.Purview{}).Where("module = ? AND status = 1", appType).Order("listorder asc").Order("id asc").Find(&purviews).Error
  408. if getPurviewErr != nil {
  409. if getPurviewErr == gorm.ErrRecordNotFound {
  410. return nil, nil
  411. } else {
  412. return nil, getPurviewErr
  413. }
  414. }
  415. return purviews, nil
  416. }