| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- 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
- }
- }
|