|
|
@@ -5,7 +5,9 @@ import (
|
|
|
"time"
|
|
|
"strconv"
|
|
|
"git.mmnx.de/Moe/databaseutils"
|
|
|
+ "git.mmnx.de/Moe/configutils"
|
|
|
"github.com/dgrijalva/jwt-go"
|
|
|
+ "github.com/kataras/iris"
|
|
|
"fmt"
|
|
|
)
|
|
|
|
|
|
@@ -29,7 +31,7 @@ type User struct {
|
|
|
|
|
|
|
|
|
func (user *User) Login(username string, password string) (string, error) {
|
|
|
- hmacSampleSecret := []byte("ayyLMAO") // crypto key for JWT encryption, TODO: move this to some config
|
|
|
+ hmacSampleSecret := []byte(configutils.Conf.CryptoKey) // crypto key for JWT encryption
|
|
|
row, err := databaseutils.DBUtil.GetRow("*", "users", "username", username) // get user
|
|
|
|
|
|
if err != nil {
|
|
|
@@ -40,10 +42,16 @@ func (user *User) Login(username string, password string) (string, error) {
|
|
|
}
|
|
|
|
|
|
if password == row[2] {
|
|
|
+ expire, err := time.ParseDuration("168h") // 7 days
|
|
|
+ if(err != nil) {
|
|
|
+ return "", errors.New("the hell?")
|
|
|
+ }
|
|
|
+
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
|
|
"username": username,
|
|
|
"userid": row[0],
|
|
|
"nbf": time.Now().Unix(),
|
|
|
+ "exp": time.Now().Add(expire).Unix(),
|
|
|
"token": "nigger", // TODO db based tokens
|
|
|
})
|
|
|
|
|
|
@@ -59,6 +67,7 @@ func (user *User) Login(username string, password string) (string, error) {
|
|
|
|
|
|
return tokenString, nil
|
|
|
} else {
|
|
|
+
|
|
|
return "", errors.New(ERR_PASSWORD_MISMATCH)
|
|
|
}
|
|
|
}
|
|
|
@@ -72,8 +81,8 @@ func searchUser(userID int) int {
|
|
|
return -1
|
|
|
}
|
|
|
|
|
|
-func VerifyUserLoggedIn(tokenString string) (bool, error) {
|
|
|
- hmacSampleSecret := []byte("ayyLMAO") // crypto key for JWT encryption, TODO: move this to some config
|
|
|
+func VerifyUserLoggedIn(tokenString string) (bool, int, error) { // TODO renew JWT from time to time preventing expiry
|
|
|
+ hmacSampleSecret := []byte(configutils.Conf.CryptoKey) // crypto key for JWT encryption
|
|
|
|
|
|
token, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
|
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
|
@@ -87,14 +96,31 @@ func VerifyUserLoggedIn(tokenString string) (bool, error) {
|
|
|
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
|
|
|
+ return true, intUserID, nil
|
|
|
} else {
|
|
|
- return false, errors.New(ERR_SESSION_TIMED_OUT) // Session probably expired - may also be faked? TODO more checks?
|
|
|
+ return false, -1, 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..
|
|
|
+ return false, -1, 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
|
|
|
+ return false, -1, errors.New(ERR_INVALID_TOKEN) // Token is invalid, expired or whatever, TODO switch with ERR_SESSION_TIMED_OUT when database based session system
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func AuthHandler(ctx *iris.Context) {
|
|
|
+ tokenString := ctx.GetCookie("token")
|
|
|
+ isAuthed, userID, err := VerifyUserLoggedIn(tokenString)
|
|
|
+
|
|
|
+ ctx.Set("userID", userID)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ ctx.Write(err.Error()) // TODO template compatible error handling
|
|
|
+ }
|
|
|
+
|
|
|
+ if isAuthed {
|
|
|
+ ctx.Next()
|
|
|
+ } else {
|
|
|
+ //ctx.Redirect("/login") // TODO redirect after x second when templates are ready
|
|
|
}
|
|
|
}
|