package srun import ( "encoding/json" "errors" "fmt" "net/http" log "github.com/sirupsen/logrus" ) type Conf struct { //调用 API 时直接访问 https URL Https bool //登录参数,不可缺省 LoginInfo LoginInfo Client *http.Client CustomHeader map[string]interface{} Logger log.FieldLogger } func New(conf *Conf) *Srun { if conf.Logger == nil { conf.Logger = log.New() } srun := &Srun{ LoginInfo: conf.LoginInfo, Logger: conf.Logger, } srun.Api.Init(&ApiConfig{ Https: conf.Https, Domain: conf.LoginInfo.Form.Domain, Client: conf.Client, CustomHeader: conf.CustomHeader, Logger: conf.Logger, }) return srun } type Srun struct { //登录参数,不可缺省 LoginInfo LoginInfo Api Api Logger log.FieldLogger } func (c Srun) LoginStatus() (online bool, ip string, err error) { res, err := c.Api.GetUserInfo() if err != nil { return false, "", err } errRes, ok := res["error"] if !ok { return false, "", ErrResultCannotFound } ipInterface, ok := res["client_ip"] if !ok { ipInterface, ok = res["online_ip"] if !ok { return false, "", ErrResultCannotFound } } ip = ipInterface.(string) online = errRes.(string) == "ok" return } func (c Srun) DoLogin(clientIP string) error { c.Logger.Debugln("正在获取 Token") if c.LoginInfo.Form.UserType != "" { c.LoginInfo.Form.Username += "@" + c.LoginInfo.Form.UserType } res, err := c.Api.GetChallenge(c.LoginInfo.Form.Username, clientIP) if err != nil { return err } token, ok := res["challenge"] if !ok { return ErrResultCannotFound } tokenStr := token.(string) c.Logger.Debugln("token: ", tokenStr) c.Logger.Debugln("发送登录请求") info, err := json.Marshal(map[string]string{ "username": c.LoginInfo.Form.Username, "password": c.LoginInfo.Form.Password, "ip": clientIP, "acid": c.LoginInfo.Meta.Acid, "enc_ver": c.LoginInfo.Meta.Enc, }) if err != nil { return err } var infoPrefix string if c.LoginInfo.Meta.InfoPrefix != "" { infoPrefix = fmt.Sprintf("{%s}", c.LoginInfo.Meta.InfoPrefix) } EncryptedInfo := infoPrefix + Base64(XEncode(string(info), tokenStr)) Md5Str, err := Md5(tokenStr, c.LoginInfo.Form.Password) if err != nil { return err } EncryptedMd5 := "{MD5}" + Md5Str EncryptedChkstr := Sha1( tokenStr + c.LoginInfo.Form.Username + tokenStr + Md5Str + tokenStr + c.LoginInfo.Meta.Acid + tokenStr + clientIP + tokenStr + c.LoginInfo.Meta.N + tokenStr + c.LoginInfo.Meta.Type + tokenStr + EncryptedInfo, ) var doubleStack string if c.LoginInfo.Meta.DoubleStack { doubleStack = "1" } else { doubleStack = "0" } res, err = c.Api.Login(&LoginRequest{ Username: c.LoginInfo.Form.Username, Password: EncryptedMd5, AcID: c.LoginInfo.Meta.Acid, IP: clientIP, Info: EncryptedInfo, ChkSum: EncryptedChkstr, N: c.LoginInfo.Meta.N, Type: c.LoginInfo.Meta.Type, OS: c.LoginInfo.Meta.OS, Name: c.LoginInfo.Meta.Name, DoubleStack: doubleStack, }) if err != nil { return err } var result interface{} result, ok = res["error"] if !ok { return ErrResultCannotFound } LoginResult := result.(string) if LoginResult != "ok" { return errors.New(LoginResult) } return nil }