package service import ( "context" "encoding/json" "errors" "fmt" "github.com/sirupsen/logrus" "strconv" "strings" "time" "youngee_m_api/consts" "youngee_m_api/db" "youngee_m_api/model/http_model" "youngee_m_api/model/redis_model" "youngee_m_api/model/system_model" "youngee_m_api/redis" "youngee_m_api/util" ) var LoginAuth *loginAuth func LoginAuthInit(config *system_model.Session) { auth := new(loginAuth) auth.sessionTTL = time.Duration(config.TTL) * time.Minute LoginAuth = auth } type loginAuth struct { sessionTTL time.Duration } func (l *loginAuth) AuthToken(ctx context.Context, token string) (*http_model.UserInfoResponse, error) { user, err := l.parseToken(ctx, token) if err != nil { logrus.Debug("token格式错误:%+v", token) return nil, err } auth, err := l.getSessionAuth(ctx, user) if err != nil { logrus.Debug("获取session redis错误: token:%+v,err:%+v", token, err) return nil, err } if auth.Token != token { logrus.Debug("获取session time过期错误: token:%+v", token) return nil, errors.New("auth failed") } var loginUser http_model.UserInfoResponse if auth.Role == "1" { //主账号 loginUser = http_model.UserInfoResponse{ User: auth.User, Username: auth.Username, Role: auth.Role, JobName: "主账号无岗位", AccountId: auth.ID, SubAccountId: 0, WorkspacePermission: "1", TaskcenterPermission: "1", SectaskPermission: "1", FinancialPermission: "1", OperatePermission: "1", UsercenterPermission: "1", } } else { subaccount, err := db.FindSubAccountById(ctx, auth.ID) if err != nil { return nil, err } jobinfo, err := db.GetJob(ctx, subaccount.JobId) if err != nil { return nil, err } loginUser = http_model.UserInfoResponse{ User: auth.User, Username: auth.Username, Role: auth.Role, JobName: jobinfo.JobName, AccountId: auth.ID, SubAccountId: subaccount.SubAccountId, WorkspacePermission: jobinfo.WorkshopPermission, TaskcenterPermission: jobinfo.TaskcenterPermission, SectaskPermission: jobinfo.SectaskPermisson, FinancialPermission: jobinfo.FinancialPermission, OperatePermission: jobinfo.OperatePermission, UsercenterPermission: jobinfo.UsercenterPermission, } } return &loginUser, nil } func (l *loginAuth) AuthCode(ctx context.Context, User string, password string) (error, *http_model.CodeLoginData) { user, err := db.GetUser(ctx, User) var loginuserdata http_model.CodeLoginData if err != nil { return err, nil } else if user == nil { // 账号不存在 logrus.Debugf("[AuthCode] auth fail,User:%+v", User) loginuserdata.Token = "账号不存在" return errors.New("auth fail"), &loginuserdata } else if string(user.Role) != consts.BRole && string(user.Role) != consts.BRole2 { // 账号权限有误 logrus.Debugf("[AuthCode] auth fail,User:%+v", User) loginuserdata.Token = "权限错误,请登录管理账号" return errors.New("auth fail"), &loginuserdata } else if string(user.UserState) != "1" { // 账号已经被禁用 logrus.Debugf("[AuthCode] auth fail,User:%+v", User) loginuserdata.Token = "账号已经被禁用" return errors.New("auth fail"), &loginuserdata } var token string if user.Password == password { token = l.getToken(ctx, user.User) auth := &redis_model.Auth{ Phone: user.Phone, ID: user.ID, User: user.User, Username: user.Username, RealName: user.RealName, Role: user.Role, Email: user.Email, Token: token, } if err := l.setSession(ctx, user.User, auth); err != nil { fmt.Printf("setSession error\n") return err, nil } } if user.Role == "1" { //主账号 loginuserdata = http_model.CodeLoginData{ Token: token, Username: user.Username, Role: user.Role, JobName: "主账号无岗位", AccountId: user.ID, SubAccountId: 0, WorkspacePermission: "1", TaskcenterPermission: "1", SectaskPermission: "1", FinancialPermission: "1", OperatePermission: "1", UsercenterPermission: "1", } } else { subaccount, err := db.FindSubAccountById(ctx, user.ID) if err != nil { return err, nil } jobinfo, err := db.GetJob(ctx, subaccount.JobId) if err != nil { return err, nil } loginuserdata = http_model.CodeLoginData{ Token: token, Username: user.Username, Role: user.Role, JobName: jobinfo.JobName, AccountId: user.ID, SubAccountId: subaccount.SubAccountId, WorkspacePermission: jobinfo.WorkshopPermission, TaskcenterPermission: jobinfo.TaskcenterPermission, SectaskPermission: jobinfo.SectaskPermisson, FinancialPermission: jobinfo.FinancialPermission, OperatePermission: jobinfo.OperatePermission, UsercenterPermission: jobinfo.UsercenterPermission, } } return nil, &loginuserdata } func (l *loginAuth) setSession(ctx context.Context, user string, auth *redis_model.Auth) error { if authJson, err := json.Marshal(auth); err == nil { err = redis.Set(ctx, l.getRedisKey(user), string(authJson), l.sessionTTL) if err == nil { return err } } return nil } //func (l *loginAuth) getSessionCode(ctx context.Context, phone string) (*string, error) { // value, err := redis.Get(ctx, l.getRedisKey(phone)) // if err != nil { // if err == consts.RedisNil { // return nil, fmt.Errorf("not found in redis,phone:%+v", phone) // } // return nil, err // } // return &value, nil //} func (l *loginAuth) getSessionAuth(ctx context.Context, user string) (*redis_model.Auth, error) { value, err := redis.Get(ctx, l.getRedisKey(user)) if err != nil { if err == consts.RedisNil { return nil, fmt.Errorf("not found in redis,user:%+v", user) } return nil, err } auth := new(redis_model.Auth) if err = json.Unmarshal([]byte(value), auth); err != nil { return nil, err } return auth, nil } func (l *loginAuth) getToken(ctx context.Context, user string) string { timeSeed := strconv.FormatInt(time.Now().Unix(), 10) token := user + "." + timeSeed + "." + util.MD5(user, timeSeed, consts.AuthSalt) return token } func (l *loginAuth) parseToken(ctx context.Context, token string) (string, error) { parts := strings.Split(token, ".") if len(parts) == 3 { user := parts[0] timeSeed := parts[1] if parts[2] == util.MD5(user, timeSeed, consts.AuthSalt) { return user, nil } } return "", errors.New("token invalid") } func (l *loginAuth) encryptPassword(password string) string { return util.MD5(password) } func (l *loginAuth) getRedisKey(key string) string { return fmt.Sprintf("%s%s", consts.SessionRedisPrefix, key) }