123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- package controllers
-
- import (
- "encoding/json"
- "fmt"
- "strconv"
- "time"
-
- "SSO/enums"
- "SSO/models"
- "SSO/service"
- "SSO/utils"
- )
-
- type VerifyTokenController struct {
- BaseController
- }
-
- func (this *VerifyTokenController) Prepare() {
- this.EnableXSRF = false
- }
-
- // /verifytoken [post]
- // @param token:string
- // @param app_type:int
- // @param ip:string
- // @param session_id:string 客户端(浏览器)sessionID
- // return 说明:所有数值型的 key 和 value 都转换为了 string 类型
- func (this *VerifyTokenController) VerifyToken() {
- token := this.GetString("token")
- clientSessionId := this.GetString("session_id")
- app_type, _ := this.GetInt("app_type", 0)
- // if app_type != 1 && app_type != 3 && app_type != 5 {
- // this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
- // this.ServeJSON()
- // return
- // }
- if url := service.GetAppURLWithAppType(app_type); len(url) == 0 {
- this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
- this.ServeJSON()
- return
- }
- utils.TraceLog("clientSessionId: %v", clientSessionId)
- if len(clientSessionId) == 0 {
- this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
- this.ServeJSON()
- return
- }
-
- if len(token) <= 24 {
- this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeInvalidToken)
- this.ServeJSON()
- return
- }
- redisClient := service.RedisClient()
- defer redisClient.Close()
- mobile := token[24:]
- // locToken, _ := redisClient.Get(fmt.Sprintf("sso_token_%v", mobile)).Result()
- locToken, _ := redisClient.Get(fmt.Sprintf("sso_token_%v", clientSessionId)).Result()
- utils.TraceLog("request token: %v \t server cached token: %v", token, locToken)
- var isUserInfoFromRedis bool = false
- if token == locToken {
- infoStr, getCachedInfoErr := redisClient.Get("sso_admin_user_info_" + mobile).Result()
- if getCachedInfoErr != nil {
- utils.WarningLog("redis 获取管理员用户信息失败:%v", getCachedInfoErr)
- infoStr = ""
- }
- infoStr = ""
- var userInfo map[string]interface{}
- if len(infoStr) == 0 {
- utils.TraceLog("%v data is from operation", "sso_admin_user_info_"+mobile)
- isUserInfoFromRedis = false
- info, getInfoErr := this.GetAdminUserAllInfo(mobile)
- if getInfoErr != nil {
- this.Data["json"] = enums.MakeFailResponseJSONWithSGJError(getInfoErr)
- this.ServeJSON()
- return
- }
- userInfo = info
- infoStr_b, _ := json.Marshal(userInfo)
- redisClient.Set("sso_admin_user_info_"+mobile, string(infoStr_b), time.Duration(2)*time.Minute)
-
- } else {
- utils.TraceLog("%v data is from redis cache", "sso_admin_user_info_"+mobile)
- isUserInfoFromRedis = true
- userInfo = make(map[string]interface{})
- json.Unmarshal([]byte(infoStr), &userInfo)
- }
-
- var adminUser models.AdminUser
- json.Unmarshal([]byte(userInfo["admin_user"].(string)), &adminUser)
- // 如果有登录记录,取出最近登录记录中的机构和应用
- lastLoginLog, getLastLoginLogErr := service.GetAdminUserLastLoginLog(adminUser.Id, app_type)
- if getLastLoginLogErr != nil {
- utils.ErrorLog("数据错误:查找mobile = %v的用户最近一次登录记录时错误:%v", mobile, getLastLoginLogErr)
- }
- currentOrgId := 0
- currentAppId := 0
- if lastLoginLog != nil {
- currentOrgId = lastLoginLog.OrgId
- currentAppId = lastLoginLog.AppId
- } else {
- if isUserInfoFromRedis {
- orgIds := userInfo["org_ids"].([]interface{})
- for _, oid := range orgIds {
- orgApps := userInfo["org_apps"].(map[string]interface{})[oid.(string)]
- for _, appMapJSON := range orgApps.(map[string]interface{}) {
- var appMap map[string]interface{}
- json.Unmarshal([]byte(appMapJSON.(string)), &appMap)
-
- a_t := int(appMap["app_type"].(float64))
- if a_t == app_type {
- currentOrgId = int(appMap["org_id"].(float64))
- currentAppId = int(appMap["id"].(float64))
- break
- }
- }
- if currentOrgId != 0 && currentAppId != 0 {
- break
- }
- }
-
- } else {
- orgIds := userInfo["org_ids"].([]string)
- for _, oid := range orgIds {
- orgApps := userInfo["org_apps"].(map[string]interface{})[oid]
- for _, appMapJSON := range orgApps.(map[string]string) {
- var appMap map[string]interface{}
- json.Unmarshal([]byte(appMapJSON), &appMap)
-
- a_t := int(appMap["app_type"].(float64))
- if a_t == app_type {
- currentOrgId = int(appMap["org_id"].(float64))
- currentAppId = int(appMap["id"].(float64))
- break
- }
- }
- if currentOrgId != 0 && currentAppId != 0 {
- break
- }
- }
- }
- }
- // for key, value := range userInfo {
- // if key == "purviews" || key == "purview_urlfors" {
- // continue
- // }
- // utils.TraceLog("%v: %v", key, value)
- // }
- utils.TraceLog("lastLoginLog : %v", lastLoginLog)
- utils.TraceLog("currentOrgId : %v", currentOrgId)
- utils.TraceLog("currentAppId : %v", currentAppId)
-
- if currentOrgId == 0 || currentAppId == 0 {
- if adminUser.IsSuperAdmin == true {
- this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeNeverCreateTypeApp)
- this.ServeJSON()
- } else {
- this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeContactSuperAdminCreateTypeApp)
- this.ServeJSON()
- }
- return
- }
-
- returnJSON := make(map[string]interface{})
- returnJSON["admin_user"] = userInfo["admin_user"]
- returnJSON["org_ids"] = userInfo["org_ids"]
- returnJSON["orgs"] = userInfo["orgs"]
- returnJSON["org_app_ids"] = userInfo["org_app_ids"]
- returnJSON["org_apps"] = userInfo["org_apps"]
- returnJSON["app_to_org_ids"] = userInfo["app_to_org_ids"]
- returnJSON["current_org_id"] = strconv.Itoa(currentOrgId)
- returnJSON["current_app_id"] = strconv.Itoa(currentAppId)
- returnJSON["purviews"] = userInfo["purviews"]
- returnJSON["purview_urlfors"] = userInfo["purview_urlfors"]
- returnJSON["app_roles"] = userInfo["app_roles"]
- returnJSON["org_subscibes"] = userInfo["org_subscibes"]
- this.Data["json"] = enums.MakeSuccessResponseJSON(returnJSON)
- this.ServeJSON()
-
- // 插入一条登录记录
- ip := this.GetString("ip")
- loginLog := &models.AdminUserLoginLog{
- AdminUserId: adminUser.Id,
- OrgId: currentOrgId,
- AppId: currentAppId,
- IP: ip,
- OperateType: 1,
- AppType: int8(app_type),
- CreateTime: time.Now().Unix(),
- }
- if insertErr := service.InsertLoginLog(loginLog); insertErr != nil {
- utils.ErrorLog("为手机号为%v的用户插入一条登录记录失败:%v", mobile, insertErr)
- }
-
- } else {
- this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeInvalidToken)
- this.ServeJSON()
- }
- }
-
- // 验证 token 之后需要返回的管理员用户的所有信息,包括:基本用户信息,所属的所有机构,机构下的所有应用
- // map 的数据格式为
- /*
- "admin_user": { AdminUser's json },
- "org_ids": [1, 2, 3],
- "orgs": { (org_id: Org_Obj)
- 1: { Org's json },
- 2: { Org's json },
- },
- "org_app_ids": { (org_id: org_app_ids)
- 1: [11, 12, 13],
- 2: [21, 22, 23],
- },
- "org_apps": { (org_id: {app_id: OrgApp_Obj})
- 1: {
- 11: { OrgApp's json },
- 12: { OrgApp's json },
- },
- 2: {
- 21: { OrgApp's json },
- 22: { OrgApp's json },
- },
- },
- "app_to_org_ids": { (app_id: org_id)
- 11: 1,
- 12: 1,
- 21: 2,
- 22: 2,
- },
- "app_roles": { (app_id: App_Role Obj)
- 11: {App_Role's json},
- 12: {App_Role's json},
- 21: {App_Role's json},
- },
- "purviews": { (app_id: [processed Purviews' json])
- 11: [
- {Purview's json .childs[
- {Purview's json},
- {Purview's json},
- ]},
- {Purview's json},
- ],
- 12: [
- {Purview's json},
- {Purview's json},
- ],
- }
- "purview_urlfors": { (app_id: [url_for])
- 11: [
- "Controller1.Action1",
- "Controller1.Action2",
- "Controller2.Action1",
- "Controller2.Action2",
- ],
- }
- 应当注意的是,屈服于 Golang 令人恶心的类型机制,这里将所有数值型的 key 或 value 全部转成了 string
- */
- func (this *VerifyTokenController) GetAdminUserAllInfo(mobile string) (map[string]interface{}, *enums.SGJError) {
- adminUser := service.GetAdminUserWithMobile(mobile)
- if adminUser == nil {
- utils.ErrorLog("数据错误:查找不到mobile = %v的用户", mobile)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- orgs, getOrgErr := service.GetAdminUserAllOrgWithUID(adminUser.Id, adminUser.IsSuperAdmin)
- if getOrgErr != nil {
- utils.ErrorLog("数据错误:查找不到mobile = %v的用户所属的机构:%v", mobile, getOrgErr)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- if len(orgs) == 0 {
- utils.ErrorLog("数据错误:查找不到mobile = %v的用户所属的机构", mobile)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- orgIds := make([]string, 0, len(orgs))
- orgJSONs := make(map[string]string)
- orgAppIds := make(map[string]interface{})
- orgApps := make(map[string]interface{})
- app_to_org_ids := make(map[string]string)
- app_purviewJSONs := make(map[string]string)
- app_purview_urls := make(map[string]string)
- app_roles := make(map[string]string)
- org_subscibes := make(map[string]string)
- for _, org := range orgs {
- apps, getAppsErr := service.GetAdminUserAllOrgApp(adminUser.Id, org.Id)
- if getAppsErr != nil {
- utils.ErrorLog("数据错误:查找mobile = %v的用户所属机构ID为%v下的应用时错误:%v", mobile, org.Id, getAppsErr)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- if adminUser.IsSuperAdmin {
- didCreateNewApp, createAppErr := this._createAppIfNeeded(adminUser.Id, org.Id, apps)
- if createAppErr != nil {
- return nil, createAppErr
- }
- if didCreateNewApp {
- apps, getAppsErr = service.GetAdminUserAllOrgApp(adminUser.Id, org.Id)
- if getAppsErr != nil {
- utils.ErrorLog("数据错误:查找mobile = %v的用户所属机构ID为%v下的应用时错误:%v", mobile, org.Id, getAppsErr)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- }
-
- } else {
- if len(apps) == 0 {
- continue
- }
- }
-
- subscibe, getSubscibeErr := service.GetOrgServeSubscibe(org.Id)
- if getSubscibeErr != nil {
- utils.ErrorLog("获取机构订阅信息失败:%v", getSubscibeErr)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- } else if subscibe == nil {
- now := time.Now()
- nextMonthDate := now.AddDate(0, 0, 30)
- subscibe = &models.ServeSubscibe{
- OrgId: int64(org.Id),
- PeriodStart: now.Unix(),
- PeriodEnd: nextMonthDate.Unix(),
- Status: 1,
- CreatedTime: now.Unix(),
- UpdatedTime: now.Unix(),
- State: 2,
- }
- createErr := service.CreateOrgServeSubscibe(subscibe)
- if createErr != nil {
- utils.ErrorLog(" 创建机构订阅信息失败:%v", createErr)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- }
- subscibeJSON_b, _ := json.Marshal(subscibe)
- subscibeJSON := string(subscibeJSON_b)
- org_subscibes[strconv.Itoa(org.Id)] = subscibeJSON
-
- orgJSON_b, _ := json.Marshal(org)
- orgJSONStr := string(orgJSON_b)
- orgJSONs[strconv.Itoa(org.Id)] = orgJSONStr
- orgIds = append(orgIds, strconv.Itoa(org.Id))
-
- appIds := make([]string, 0, len(apps))
- appJSONs := make(map[string]string)
- for _, app := range apps {
- appJSON_b, _ := json.Marshal(app)
- appJSONStr := string(appJSON_b)
- appJSONs[strconv.Itoa(app.Id)] = appJSONStr
- appIds = append(appIds, strconv.Itoa(app.Id))
- app_to_org_ids[strconv.Itoa(app.Id)] = strconv.Itoa(org.Id)
-
- if adminUser.IsSuperAdmin {
- urlfors, purviews, getPurviewErr := service.GetSuperAdminUsersPurviewTreeAndUrlfors(app.AppType)
- if getPurviewErr != nil {
- utils.ErrorLog("数据错误:查找超级管理员的类型为%v的应用的权限时错误:%v", app.AppType, getPurviewErr)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- } else {
- purviewJSONs_b, _ := json.Marshal(purviews)
- app_purviewJSONs[strconv.Itoa(app.Id)] = string(purviewJSONs_b)
- urlforJSON_b, _ := json.Marshal(urlfors)
- app_purview_urls[strconv.Itoa(app.Id)] = string(urlforJSON_b)
- }
- } else {
- urlfors, purviews, getPurviewErr := service.GetGeneralAdminUsersPurviewTreeAndUrlfors(adminUser.Id, app.Id)
- if getPurviewErr != nil {
- utils.ErrorLog("数据错误:查找id为%v普通管理员的id为%v的应用的权限时错误:%v", adminUser.Id, app.Id, getPurviewErr)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- } else {
- purviewJSONs_b, _ := json.Marshal(purviews)
- app_purviewJSONs[strconv.Itoa(app.Id)] = string(purviewJSONs_b)
- urlforJSON_b, _ := json.Marshal(urlfors)
- app_purview_urls[strconv.Itoa(app.Id)] = string(urlforJSON_b)
- }
- }
-
- appRole, getAppRoleErr := service.GetAppRole(adminUser.Id, org.Id, app.Id)
- if getAppRoleErr != nil {
- utils.ErrorLog("数据错误:查找id=%v,orgid=%v,appid=%v的用户信息时失败:%v", adminUser.Id, org.Id, app.Id, getAppRoleErr)
- return nil, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- appRoleJSON_b, _ := json.Marshal(appRole)
- app_roles[strconv.Itoa(app.Id)] = string(appRoleJSON_b)
- }
- orgAppIds[strconv.Itoa(org.Id)] = appIds
- orgApps[strconv.Itoa(org.Id)] = appJSONs
- }
-
- adminUserJSON_b, _ := json.Marshal(adminUser)
- info := make(map[string]interface{})
- info["admin_user"] = string(adminUserJSON_b)
- info["org_ids"] = orgIds
- info["orgs"] = orgJSONs
- info["org_app_ids"] = orgAppIds
- info["org_apps"] = orgApps
- info["app_to_org_ids"] = app_to_org_ids
- info["app_roles"] = app_roles
- info["purviews"] = app_purviewJSONs
- info["purview_urlfors"] = app_purview_urls
- info["org_subscibes"] = org_subscibes
- return info, nil
- }
-
- func (this *VerifyTokenController) _createAppIfNeeded(adminUserID int, orgID int, didCreatedApps []*models.OrgApp) (bool, *enums.SGJError) {
- // 已创建的应用的信息
- did_patient_manage_create := false
- did_dialysis_manage_create := false
- did_cdm_manage_create := false
- did_mall_manage_create := false
- for _, app := range didCreatedApps {
- if app.AppType == 1 {
- did_patient_manage_create = true
- } else if app.AppType == 3 {
- did_dialysis_manage_create = true
- } else if app.AppType == 4 {
- did_cdm_manage_create = true
- } else if app.AppType == 5 {
- did_mall_manage_create = true
- }
- }
-
- // 自动创建所有应用
- didCreateNew := false
- if did_dialysis_manage_create == false {
- err := service.CreateOrgApp(adminUserID, orgID, 3, false)
- if err != nil {
- utils.ErrorLog("自动创建透析管理应用失败:%v", err)
- return false, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- didCreateNew = true
- }
- if did_cdm_manage_create == false {
- err := service.CreateOrgApp(adminUserID, orgID, 4, false)
- if err != nil {
- utils.ErrorLog("自动创建慢病管理应用失败:%v", err)
- return false, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- didCreateNew = true
- }
- if did_patient_manage_create == false {
- err := service.CreateOrgApp(adminUserID, orgID, 1, false)
- if err != nil {
- utils.ErrorLog("自动创建酷医聚客应用失败:%v", err)
- return false, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- didCreateNew = true
- }
- if did_mall_manage_create == false {
- err := service.CreateOrgApp(adminUserID, orgID, 5, false)
- if err != nil {
- utils.ErrorLog("自动创建微商城应用失败:%v", err)
- return false, &enums.SGJError{Code: enums.ErrorCodeDataException}
- }
- didCreateNew = true
- }
- return didCreateNew, nil
- }
|