Kaynağa Gözat

you can login and be verified that you're logged in

Moritz Schmidt 9 yıl önce
ebeveyn
işleme
a1780a2f11
1 değiştirilmiş dosya ile 56 ekleme ve 8 silme
  1. 56 8
      usermanager.go

+ 56 - 8
usermanager.go

@@ -10,7 +10,14 @@ import (
 )
 
 var (
-  Users *[5]User
+  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 {
@@ -22,13 +29,14 @@ type User struct {
 
 
 func (user *User) Login(username string, password string) (string, error) {
-  hmacSampleSecret := []byte("ayyLMAO")
-  row := databaseutils.DBUtil.GetRow("*", "users", "username", username)
+  hmacSampleSecret := []byte("ayyLMAO") // crypto key for JWT encryption, TODO: move this to some config
+  row, err := databaseutils.DBUtil.GetRow("*", "users", "username", username) // get user
 
-  fmt.Println("%v", row)
-
-  if len(row) < 1 { // TODO this doesnt work
-    return "", errors.New("User not found")
+  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] {
@@ -45,8 +53,48 @@ func (user *User) Login(username string, password string) (string, error) {
     user.Username = row[1]
     user.Mail = row[3]
 
+    *Users = append(*Users, *user)
+
+    fmt.Printf("%v\n", *Users)
+
     return tokenString, nil
   } else {
-    return "", errors.New("Password Mismatch")
+    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
   }
 }