package usermanager import ( "errors" "time" "strconv" "git.mmnx.de/Moe/databaseutils" "github.com/dgrijalva/jwt-go" "fmt" ) var ( Users *[]User ) const ( ERR_USER_NOT_FOUND = "ERR_USER_NOT_FOUND" ERR_PASSWORD_MISMATCH = "ERR_PASSWORD_MISMATCH" ERR_SESSION_TIMED_OUT = "ERR_SESSION_TIMED_OUT" ERR_INVALID_TOKEN = "ERR_INVALID_TOKEN" ) type User struct { ID int Username string Password string Mail string } func (user *User) Login(username string, password string) (string, error) { hmacSampleSecret := []byte("ayyLMAO") // crypto key for JWT encryption, TODO: move this to some config row, err := databaseutils.DBUtil.GetRow("*", "users", "username", username) // get user if err != nil { if err.Error() == databaseutils.ERR_EMPTY_RESULT { // empty result -> user not found return "", errors.New(ERR_USER_NOT_FOUND) } fmt.Println("DB ERR @ user Login: ", err) } if password == row[2] { token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "username": username, "userid": row[0], "nbf": time.Now().Unix(), "token": "nigger", // TODO db based tokens }) tokenString, _ := token.SignedString(hmacSampleSecret) user.ID, _ = strconv.Atoi(row[0]) user.Username = row[1] user.Mail = row[3] *Users = append(*Users, *user) fmt.Printf("%v\n", *Users) return tokenString, nil } else { return "", errors.New(ERR_PASSWORD_MISMATCH) } } func searchUser(userID int) int { for i := range *Users { if (*Users)[i].ID == userID { return i } } return -1 } func VerifyUserLoggedIn(tokenString string) (bool, error) { hmacSampleSecret := []byte("ayyLMAO") // crypto key for JWT encryption, TODO: move this to some config token, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) } return hmacSampleSecret, nil }) if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { // if token is valid if userID, ok := claims["userid"].(string); ok { // extract userID intUserID, _ := strconv.Atoi(userID) // convert to int ... god i love scripting languages sliceID := searchUser(intUserID) // verify that user has a session on the server if sliceID != -1 { // searchUser returns -1 if there's no such user return true, nil } else { return false, errors.New(ERR_SESSION_TIMED_OUT) // Session probably expired - may also be faked? TODO more checks? } } else { return false, errors.New("Unknown error") // This should never happen, prolly can't convert something in claims then.. } } else { return false, errors.New(ERR_INVALID_TOKEN) // Token is invalid, expired or whatever, TODO switch with ERR_SESSION_TIMED_OUT when database based session system } }