usermanager.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package usermanager
  2. import (
  3. "errors"
  4. "time"
  5. "strconv"
  6. "git.mmnx.de/Moe/databaseutils"
  7. "github.com/dgrijalva/jwt-go"
  8. "fmt"
  9. )
  10. var (
  11. Users *[]User
  12. )
  13. const (
  14. ERR_USER_NOT_FOUND = "ERR_USER_NOT_FOUND"
  15. ERR_PASSWORD_MISMATCH = "ERR_PASSWORD_MISMATCH"
  16. ERR_SESSION_TIMED_OUT = "ERR_SESSION_TIMED_OUT"
  17. ERR_INVALID_TOKEN = "ERR_INVALID_TOKEN"
  18. )
  19. type User struct {
  20. ID int
  21. Username string
  22. Password string
  23. Mail string
  24. }
  25. func (user *User) Login(username string, password string) (string, error) {
  26. hmacSampleSecret := []byte("ayyLMAO") // crypto key for JWT encryption, TODO: move this to some config
  27. row, err := databaseutils.DBUtil.GetRow("*", "users", "username", username) // get user
  28. if err != nil {
  29. if err.Error() == databaseutils.ERR_EMPTY_RESULT { // empty result -> user not found
  30. return "", errors.New(ERR_USER_NOT_FOUND)
  31. }
  32. fmt.Println("DB ERR @ user Login: ", err)
  33. }
  34. if password == row[2] {
  35. token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
  36. "username": username,
  37. "userid": row[0],
  38. "nbf": time.Now().Unix(),
  39. "token": "nigger", // TODO db based tokens
  40. })
  41. tokenString, _ := token.SignedString(hmacSampleSecret)
  42. user.ID, _ = strconv.Atoi(row[0])
  43. user.Username = row[1]
  44. user.Mail = row[3]
  45. *Users = append(*Users, *user)
  46. fmt.Printf("%v\n", *Users)
  47. return tokenString, nil
  48. } else {
  49. return "", errors.New(ERR_PASSWORD_MISMATCH)
  50. }
  51. }
  52. func searchUser(userID int) int {
  53. for i := range *Users {
  54. if (*Users)[i].ID == userID {
  55. return i
  56. }
  57. }
  58. return -1
  59. }
  60. func VerifyUserLoggedIn(tokenString string) (bool, error) {
  61. hmacSampleSecret := []byte("ayyLMAO") // crypto key for JWT encryption, TODO: move this to some config
  62. token, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
  63. if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
  64. return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
  65. }
  66. return hmacSampleSecret, nil
  67. })
  68. if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { // if token is valid
  69. if userID, ok := claims["userid"].(string); ok { // extract userID
  70. intUserID, _ := strconv.Atoi(userID) // convert to int ... god i love scripting languages
  71. sliceID := searchUser(intUserID) // verify that user has a session on the server
  72. if sliceID != -1 { // searchUser returns -1 if there's no such user
  73. return true, nil
  74. } else {
  75. return false, errors.New(ERR_SESSION_TIMED_OUT) // Session probably expired - may also be faked? TODO more checks?
  76. }
  77. } else {
  78. return false, errors.New("Unknown error") // This should never happen, prolly can't convert something in claims then..
  79. }
  80. } else {
  81. 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
  82. }
  83. }