package hhc_telws import ( "fmt" "github.com/pascaldekloe/jwt" "golang.org/x/crypto/bcrypt" "time" ) type TelwsAuthSimpleAAA struct { jwtKey []byte userDatabase map[string]string authLogFunc func(isSuccess bool, msg string) jwtttl time.Duration } func NewTelwsAuthSimpleAAA() *TelwsAuthSimpleAAA { ah := &TelwsAuthSimpleAAA{ jwtKey: []byte{}, userDatabase: make(map[string]string), authLogFunc: func(isSuccess bool, msg string) {}, } return ah } func (ah *TelwsAuthSimpleAAA) SetAuthLogFunc(authLogFunc func(isSuccess bool, msg string)) { ah.authLogFunc = authLogFunc } func (ah *TelwsAuthSimpleAAA) SimpleAAAAddSimple(username, password string, cost int) error { hash, err := bcrypt.GenerateFromPassword([]byte(password), cost) if err != nil { return err } ah.userDatabase[username] = string(hash) return nil } func (ah *TelwsAuthSimpleAAA) SimpleAAAAddBcrypt(username, hash string) { ah.userDatabase[username] = hash } func (ah *TelwsAuthSimpleAAA) Register(jwtkey []byte, jwtttl time.Duration) (ahname string) { ah.jwtKey = jwtkey ah.jwtttl = jwtttl return "simple-aaa" } func (ah *TelwsAuthSimpleAAA) Login(authData map[string]string) (isSuccess bool, jwtdata string, emsg string) { amet, ok := authData["method"] if !ok { ah.authLogFunc(false, "no auth method specified") return false, "", "no auth method specified" } if amet != "simple-aaa" { ah.authLogFunc(false, "auth method not support") return false, "", "auth method not support" } username, ok := authData["username"] if !ok { ah.authLogFunc(false, "no username specified") return false, "", "no username specified" } password, ok := authData["password"] if !ok { ah.authLogFunc(false, "no password specified") return false, "", "no password specified" } if username == "" { ah.authLogFunc(false, "username can not be null") return false, "", "username can not be null" } ubc, ok := ah.userDatabase[username] if !ok { ah.authLogFunc(false, fmt.Sprintf("user '%s' not exist", username)) return false, "", "username or password not match" } err := bcrypt.CompareHashAndPassword([]byte(ubc), []byte(password)) if err != nil { ah.authLogFunc(false, fmt.Sprintf("user '%s' auth failed with error: %s", username, err.Error())) return false, "", "username or password not match" } clm := jwt.Claims{} clm.Issuer = "simple-aaa" clm.Subject = "telws-auth" ntm := jwt.NewNumericTime(time.Now()) clm.Issued = ntm clm.NotBefore = ntm clm.Expires = jwt.NewNumericTime(time.Now().Add(ah.jwtttl)) clm.Set = map[string]interface{}{ "username": username, } tok, err := clm.HMACSign(jwt.HS256, ah.jwtKey) if err != nil { ah.authLogFunc(false, fmt.Sprintf("user '%s' auth success but generate jwt error: %s", username, err.Error())) return false, "", "internal error" } ah.authLogFunc(false, fmt.Sprintf("user '%s' auth success", username)) return true, string(tok), "" }