package service import ( "encoding/json" "io/ioutil" "net/http" "net/url" "strconv" "time" "XT_Admin_Api/models" "XT_Admin_Api/utils" "github.com/astaxie/beego" ) type AdminUserInfo struct { AdminUser *models.AdminUser `json:"user"` CurrentOrgId int64 `json:"current_org_id"` CurrentAppId int64 `json:"current_app_id"` OrgIds []int64 `json:"org_ids"` Orgs map[int64]*models.Org `json:"orgs"` OrgAppIds map[int64][]int64 `json:"org_app_ids"` OrgApps map[int64](map[int64]*models.OrgApp) `json:"org_apps"` App2OrgIds map[int64]int64 `json:"app_to_org_ids"` AppRoles map[int64]*models.App_Role `json:"app_roles"` AppPurviews map[int64][]*models.Purview `json:"app_purviews"` AppUrlfors map[int64][]string `json:"app_urlfors"` Subscibes map[int64]*models.ServeSubscibe `json:"org_subscibes"` } type verifyTokenError struct { Msg string } func (e *verifyTokenError) Error() string { return e.Msg } // 验证 token 成功后返回的管理员用户的所有信息,包括:基本用户信息,所属的所有机构,机构下的所有应用,应用的用户权限 // map 的数据格式为 /* "admin_user": { AdminUser's json }, current_org_id: 1, current_app_id: 11, "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 VerifyToken(token string, ip string, sessionID string) (*AdminUserInfo, error, int) { // if len(sessionID) == 0 { // return nil, &verifyTokenError{"sessionID 为空"} // } ssoDomain := beego.AppConfig.String("sso_domain") api := ssoDomain + "/verifytoken" values := make(url.Values) values.Set("token", token) values.Set("app_type", "3") values.Set("ip", ip) values.Set("session_id", sessionID) resp, requestErr := http.PostForm(api, values) if requestErr != nil { utils.ErrorLog("请求验证 sso token 接口失败: %v", requestErr) return nil, requestErr, 0 } defer resp.Body.Close() body, ioErr := ioutil.ReadAll(resp.Body) if ioErr != nil { utils.ErrorLog("验证 sso token 接口返回数据读取失败: %v", ioErr) return nil, ioErr, 0 } var respJSON map[string]interface{} utils.InfoLog(string(body)) if err := json.Unmarshal([]byte(string(body)), &respJSON); err != nil { utils.ErrorLog("验证 sso token 接口返回数据解析JSON失败: %v", err) return nil, err, 0 } if respJSON["state"].(float64) != 1 { msg := respJSON["msg"].(string) utils.ErrorLog("验证 sso token 接口请求失败: %v", msg) return nil, &verifyTokenError{"验证 sso token 接口请求失败"}, int(respJSON["code"].(float64)) } else { utils.SuccessLog("验证 sso token 成功") return processAdminUserInfo(respJSON["data"].(map[string]interface{})), nil, 0 } } func processAdminUserInfo(data map[string]interface{}) *AdminUserInfo { adminUser := processAdminUser(data) currentOrgId, currentAppId := processCurrentOrgIDAndAppID(data) orgIds := processOrgIds(data) orgs := processOrgs(data) orgAppIds := processOrgAppIds(data) orgApps := processOrgApps(data) app2OrgIds := processApp2OrgIds(data) appRoles := processAppRoles(data) appPurviews := processPurviews(data) appUrlfors := processPurviewUrlfors(data) orgSubscibes := processOrgSubscibes(data) sessionAdminUserInfo := &AdminUserInfo{ AdminUser: adminUser, CurrentOrgId: currentOrgId, CurrentAppId: currentAppId, OrgIds: orgIds, Orgs: orgs, OrgAppIds: orgAppIds, OrgApps: orgApps, App2OrgIds: app2OrgIds, AppRoles: appRoles, AppPurviews: appPurviews, AppUrlfors: appUrlfors, Subscibes: orgSubscibes, } return sessionAdminUserInfo } // "admin_user": { AdminUser's json }, func processAdminUser(data map[string]interface{}) *models.AdminUser { userJSONStr := data["admin_user"].(string) var adminUser models.AdminUser if err := json.Unmarshal([]byte(userJSONStr), &adminUser); err != nil { utils.ErrorLog("解析用户信息失败:%v", err) return nil } else { return &adminUser } } // current_org_id: 1, // current_app_id: 11, func processCurrentOrgIDAndAppID(data map[string]interface{}) (int64, int64) { orgIDStr := data["current_org_id"].(string) appIDStr := data["current_app_id"].(string) orgID, _ := strconv.Atoi(orgIDStr) appID, _ := strconv.Atoi(appIDStr) return int64(orgID), int64(appID) } // "org_ids": [1, 2, 3], func processOrgIds(data map[string]interface{}) []int64 { orgIdStrs := data["org_ids"].([]interface{}) orgIds := make([]int64, 0, len(orgIdStrs)) for _, idstr := range orgIdStrs { id, _ := strconv.Atoi(idstr.(string)) orgIds = append(orgIds, int64(id)) } return orgIds } // "orgs": { (org_id: Org_Obj) // 1: { Org's json }, // 2: { Org's json }, // }, func processOrgs(data map[string]interface{}) map[int64]*models.Org { orgJSONs := data["orgs"].(map[string]interface{}) orgs := make(map[int64]*models.Org) for orgIdStr, orgJSON := range orgJSONs { orgId, _ := strconv.Atoi(orgIdStr) var org models.Org json.Unmarshal([]byte(orgJSON.(string)), &org) orgs[int64(orgId)] = &org } return orgs } // "org_app_ids": { (org_id: org_app_ids) // 1: [11, 12, 13], // 2: [21, 22, 23], // }, func processOrgAppIds(data map[string]interface{}) map[int64][]int64 { orgAppIdStrs := data["org_app_ids"].(map[string]interface{}) orgAppIds := make(map[int64][]int64) for orgIdStr, appIdStrs := range orgAppIdStrs { orgId, _ := strconv.Atoi(orgIdStr) appIds := make([]int64, 0, len(appIdStrs.([]interface{}))) for _, appIdStr := range appIdStrs.([]interface{}) { appId, _ := strconv.Atoi(appIdStr.(string)) appIds = append(appIds, int64(appId)) } orgAppIds[int64(orgId)] = appIds } return orgAppIds } // "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 }, // }, // }, func processOrgApps(data map[string]interface{}) map[int64]map[int64]*models.OrgApp { orgAppJSONs := data["org_apps"].(map[string]interface{}) orgApps := make(map[int64]map[int64]*models.OrgApp) for orgIdStr, appJSONStrMap := range orgAppJSONs { orgId, _ := strconv.Atoi(orgIdStr) apps := make(map[int64]*models.OrgApp) for appIdStr, appJSONStr := range appJSONStrMap.(map[string]interface{}) { appId, _ := strconv.Atoi(appIdStr) var app models.OrgApp json.Unmarshal([]byte(appJSONStr.(string)), &app) apps[int64(appId)] = &app } orgApps[int64(orgId)] = apps } return orgApps } // "app_to_org_ids": { (app_id: org_id) // 11: 1, // 12: 1, // 21: 2, // 22: 2, // }, func processApp2OrgIds(data map[string]interface{}) map[int64]int64 { app2OrgIdStrs := data["app_to_org_ids"].(map[string]interface{}) app2OrgIds := make(map[int64]int64) for appIdStr, orgIdStr := range app2OrgIdStrs { orgId, _ := strconv.Atoi(orgIdStr.(string)) appId, _ := strconv.Atoi(appIdStr) app2OrgIds[int64(appId)] = int64(orgId) } return app2OrgIds } // "app_roles": { (app_id: App_Role Obj) // 11: {App_Role's json}, // 12: {App_Role's json}, // 21: {App_Role's json}, // }, func processAppRoles(data map[string]interface{}) map[int64]*models.App_Role { appRoleJSONs := data["app_roles"].(map[string]interface{}) appRoles := make(map[int64]*models.App_Role) for appIDStr, appRoleJSON := range appRoleJSONs { appID, _ := strconv.Atoi(appIDStr) var appRole models.App_Role json.Unmarshal([]byte(appRoleJSON.(string)), &appRole) appRoles[int64(appID)] = &appRole } return appRoles } // "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}, // ], // }, func processPurviews(data map[string]interface{}) map[int64][]*models.Purview { appPurviewJSONsStrs := data["purviews"].(map[string]interface{}) appPurviews := make(map[int64][]*models.Purview) for appIdStr, purviewJSONsStr := range appPurviewJSONsStrs { appId, _ := strconv.Atoi(appIdStr) var purviews []*models.Purview json.Unmarshal([]byte(purviewJSONsStr.(string)), &purviews) // setLinkForPurviews(purviews) appPurviews[int64(appId)] = purviews } return appPurviews } // func setLinkForPurviews(purviews []*models.Purview) { // for _, purview := range purviews { // if len(purview.Urlfor) == 0 { // purview.Link = "" // } else { // purview.Link = beego.URLFor(purview.Urlfor) // } // if purview.Childs == nil { // purview.Childs = make([]*models.Purview, 0) // } else { // setLinkForPurviews(purview.Childs) // } // // utils.TraceLog("%+v", purview) // } // } // "purview_urlfors": { (app_id: [url_for]) // 11: [ // "Controller1.Action1", // "Controller1.Action2", // "Controller2.Action1", // "Controller2.Action2", // ], // } func processPurviewUrlfors(data map[string]interface{}) map[int64][]string { appUrlforsStrs := data["purview_urlfors"].(map[string]interface{}) appUrlfors := make(map[int64][]string) for appIdStr, urlforsStr := range appUrlforsStrs { appId, _ := strconv.Atoi(appIdStr) var urlfors []string json.Unmarshal([]byte(urlforsStr.(string)), &urlfors) appUrlfors[int64(appId)] = urlfors } return appUrlfors } // "org_subscibes": { (org_id: ServeSubscibe) // 11: {ServeSubscibe's json} // }, func processOrgSubscibes(data map[string]interface{}) map[int64]*models.ServeSubscibe { subscibeJSONs := data["org_subscibes"].(map[string]interface{}) subscibes := make(map[int64]*models.ServeSubscibe) for orgIDStr, subscibeJSON := range subscibeJSONs { orgID, _ := strconv.Atoi(orgIDStr) var subscibe models.ServeSubscibe json.Unmarshal([]byte(subscibeJSON.(string)), &subscibe) subscibes[int64(orgID)] = &subscibe } return subscibes } func ModifyPassword(adminID int64, password string) error { err := writeUserDb.Model(&models.AdminUser{}).Where("id = ? AND status = 1", adminID).Updates(map[string]interface{}{"password": password, "mtime": time.Now().Unix()}).Error return err }