package v1 import ( "bytes" "crypto/tls" "encoding/json" "fmt" "git.inspur.com/sbg-jszt/cfn/cfn-schedule/config" "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/controller" "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/middleware" "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/user" "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/pkg/auth" "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/pkg/errors" "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/validator" "git.inspur.com/sbg-jszt/cfn/cfn-schedule/pkg/log" "github.com/gin-gonic/gin" "github.com/golang/glog" "gorm.io/gorm" "io" "net/http" "time" ) const AUTH_HEADER = "Authorization" type UserInfo struct { *user.UserObj Token string `json:"token"` } func LoginInfo(c *gin.Context) { u, exists := c.Get(middleware.LoginUserKey) if !exists { controller.FailCode(c, errors.AuthorizationError, nil) return } userObj, ok := u.(*user.UserObj) if !ok { controller.FailCode(c, errors.AuthorizationError, nil) return } if !config.Config.Auth.Enable { controller.FailCode(c, errors.ServerError, nil, "login is disabled!") return } url := config.Config.Auth.Url if url == "" { controller.FailCode(c, errors.ServerError, nil, "login config is not set!") return } token := c.Request.Header.Get(AUTH_HEADER) var client *http.Client var request *http.Request var resp *http.Response client = &http.Client{Transport: &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, }} request, err := http.NewRequest("GET", url+config.Config.Auth.LoginInfo, nil) if err != nil { glog.Errorln("failed to create request", err) controller.FailCode(c, errors.ServerError, err, "failed to create request!") return } request.Header.Add(AUTH_HEADER, token) resp, err = client.Do(request) if err != nil { glog.Errorln("failed to request", err) controller.FailCode(c, errors.ServerError, err, "failed to request!") return } defer resp.Body.Close() defer client.CloseIdleConnections() if resp.StatusCode != 200 { glog.Errorln("response error") controller.FailCode(c, errors.ServerError, nil, "response error!") return } var respBody map[string]interface{} respStr, _ := io.ReadAll(resp.Body) err = json.Unmarshal(respStr, &respBody) if err != nil { glog.Errorln("failed to decode response", err) controller.FailCode(c, errors.ServerError, err, "failed to decode response!") return } data := respBody["data"] if data == nil { meta := respBody["meta"] controller.FailCode(c, errors.ServerError, nil, meta.(map[string]interface{})["message"].(string)) return } userMap := data.(map[string]interface{})["user"] mobile := userMap.(map[string]interface{})["mobile"] if mobile != nil { userObj.Mobile = mobile.(string) } provinceId := userMap.(map[string]interface{})["provinceId"] if provinceId != nil { userObj.ProvinceId = provinceId.(string) } userObj.Status = userMap.(map[string]interface{})["status"].(string) userinfo := UserInfo{ UserObj: userObj, } controller.Success(c, userinfo) } type LoginBody struct { AppCode string `json:"appCode"` Password string `json:"password"` SingleLogin bool `json:"singleLogin"` TextCode string `json:"textCode"` UserName string `json:"username"` Uuid string `json:"uuid"` } func Login(c *gin.Context) { if !config.Config.Auth.Enable { controller.FailCode(c, errors.ServerError, nil, "login is disabled!") return } url := config.Config.Auth.Url if url == "" { controller.FailCode(c, errors.ServerError, nil, "login config is not set!") return } loginBody := LoginBody{} err := validator.CheckPostParams(c, &loginBody) if err != nil || (loginBody.AppCode == "" || loginBody.Password == "" || loginBody.TextCode == "" || loginBody.UserName == "" || loginBody.Uuid == "") { controller.FailCode(c, errors.ServerError, err, "请检查参数!") return } client := &http.Client{Transport: &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, }} authPath := config.Config.Auth.LoginWithCode reqBody, err := json.Marshal(loginBody) resp, err := client.Post(url+authPath, "application/json", bytes.NewReader(reqBody)) if err != nil { controller.FailCode(c, errors.ServerError, err, "服务异常!") return } defer resp.Body.Close() defer client.CloseIdleConnections() var respBody map[string]interface{} respBytes, _ := io.ReadAll(resp.Body) log.Info("auth response:" + string(respBytes)) if resp.StatusCode != 200 { glog.Errorln("response error:" + string(respBytes)) controller.FailCode(c, errors.ServerError, nil, "服务异常!") return } err = json.Unmarshal(respBytes, &respBody) if err != nil { glog.Errorln("failed to decode response", err.Error()) controller.FailCode(c, errors.ServerError, nil, "服务异常!") return } data := respBody["data"] if data == nil { meta := respBody["meta"] controller.FailCode(c, errors.ServerError, nil, meta.(map[string]interface{})["message"].(string)) return } accountMap := data.(map[string]interface{})["account"] userName := accountMap.(map[string]interface{})["loginName"].(string) currentUser := user.NewUserModel() err = currentUser.GetByUserName(userName) if err != nil { if err == gorm.ErrRecordNotFound { glog.Warningln("User does not exist in database registry") currentUser = nil } else { controller.FailCode(c, errors.ServerError, err, "服务异常!") return } } if currentUser == nil { glog.Infoln("Moving user to database, user: ", loginBody.UserName) spec := user.UserSpec{} spec.UserID = accountMap.(map[string]interface{})["accountId"].(string) spec.UserName = userName userMap := data.(map[string]interface{})["user"] displayName := userMap.(map[string]interface{})["cn"] if displayName != nil { spec.DisplayName = displayName.(string) } else { spec.DisplayName = userName } if userName == "admin" { spec.Role = 1 } else { spec.Role = 0 } if config.Config.CfnConfig.Enable { spec.Namespace = fmt.Sprintf("DEFAULT,%s", config.Config.CfnConfig.CfnWorkSpaceId) } else { spec.Namespace = "DEFAULT" } _, err = user.CreateUser(spec) if err != nil { glog.Errorln("failed to create user, err: " + err.Error()) controller.FailCode(c, errors.ServerError, err, "服务异常!") return } } detail, err := user.GetUserByUsername(userName) if err != nil || detail == nil { glog.Errorln("failed to get user, err: " + err.Error()) controller.FailCode(c, errors.ServerError, err, "服务异常!") return } userMap := data.(map[string]interface{})["user"] mobile := userMap.(map[string]interface{})["mobile"] if mobile != nil { detail.Mobile = mobile.(string) } provinceId := userMap.(map[string]interface{})["provinceId"] if provinceId != nil { detail.ProvinceId = provinceId.(string) } detail.Status = userMap.(map[string]interface{})["status"].(string) tokenMap := data.(map[string]interface{})["token"] authToken := tokenMap.(map[string]interface{})["accessToken"].(string) go func() { userModel := user.NewUserModel() userModel.UserID = detail.UserID userModel.LastLoginTime = time.Now() userModel.LoginFrequency = detail.LoginFrequency + 1 _, err = userModel.UpdateLastLoginTime() if err != nil { glog.Errorln("Failed to update last_login_time", err) } }() token, err := auth.Authorize(authToken, detail) if err != nil || token == "" { glog.Errorln("Failed to get token", err) controller.FailCode(c, errors.ServerError, err, "服务异常!") return } userinfo := UserInfo{ UserObj: detail, Token: token, } controller.Success(c, userinfo) }