|
@@ -7,7 +7,7 @@ import (
|
|
|
"strconv"
|
|
"strconv"
|
|
|
"git.mmnx.de/Moe/databaseutils"
|
|
"git.mmnx.de/Moe/databaseutils"
|
|
|
"git.mmnx.de/Moe/configutils"
|
|
"git.mmnx.de/Moe/configutils"
|
|
|
- "git.mmnx.de/Moe/templatehelpers"
|
|
|
|
|
|
|
+ "git.mmnx.de/Moe/errorhelpers"
|
|
|
"github.com/dgrijalva/jwt-go"
|
|
"github.com/dgrijalva/jwt-go"
|
|
|
"github.com/kataras/iris"
|
|
"github.com/kataras/iris"
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
"golang.org/x/crypto/bcrypt"
|
|
@@ -18,19 +18,6 @@ var (
|
|
|
Users *[]User // stores all currently logged in users
|
|
Users *[]User // stores all currently logged in users
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-const ( // Error constants
|
|
|
|
|
- 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"
|
|
|
|
|
- ERR_USERNAME_TAKEN = "ERR_USERNAME_TAKEN"
|
|
|
|
|
- ERR_INVALID_PARAM = "ERR_INVALID_PARAM"
|
|
|
|
|
- ERR_NO_CHANGES = "ERR_NO_CHANGES"
|
|
|
|
|
- SUCCESS_LOGIN = "SUCCESS_LOGIN"
|
|
|
|
|
- SUCCESS_UPDATE = "SUCCESS_UPDATE"
|
|
|
|
|
- SUCCESS_TOKENS_GENERATED = "SUCCESS_TOKENS_GENERATED"
|
|
|
|
|
-)
|
|
|
|
|
-
|
|
|
|
|
type User struct { // User
|
|
type User struct { // User
|
|
|
ID string
|
|
ID string
|
|
|
Username string
|
|
Username string
|
|
@@ -39,39 +26,13 @@ type User struct { // User
|
|
|
TokenUsed string
|
|
TokenUsed string
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-type PageParams struct{
|
|
|
|
|
- NotificationType string
|
|
|
|
|
- Notification string
|
|
|
|
|
- ReqDir string
|
|
|
|
|
- Admin string
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-type PageUserParams struct{
|
|
|
|
|
- NotificationType string
|
|
|
|
|
- Notification string
|
|
|
|
|
- ReqDir string
|
|
|
|
|
- Username string
|
|
|
|
|
- Admin string
|
|
|
|
|
- Custom []string
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-type PageUserParamsMessage struct{
|
|
|
|
|
- NotificationType string
|
|
|
|
|
- Notification string
|
|
|
|
|
- ReqDir string
|
|
|
|
|
- Username string
|
|
|
|
|
- Email string
|
|
|
|
|
- Admin string
|
|
|
|
|
- Message string
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
func (user *User) Login(username string, password string) (string, error) {
|
|
func (user *User) Login(username string, password string) (string, error) {
|
|
|
hmacSampleSecret := []byte(configutils.Conf.CryptoKey) // crypto key for JWT encryption
|
|
hmacSampleSecret := []byte(configutils.Conf.CryptoKey) // crypto key for JWT encryption
|
|
|
row, err := databaseutils.DBUtil.GetRow("*", "users", "username", username) // get user from db
|
|
row, err := databaseutils.DBUtil.GetRow("*", "users", "username", username) // get user from db
|
|
|
|
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
if err.Error() == databaseutils.ERR_EMPTY_RESULT { // empty result -> user not found
|
|
if err.Error() == databaseutils.ERR_EMPTY_RESULT { // empty result -> user not found
|
|
|
- return "", errors.New(ERR_USER_NOT_FOUND)
|
|
|
|
|
|
|
+ return "", errors.New(errorhelpers.ERR_USER_NOT_FOUND)
|
|
|
} else {
|
|
} else {
|
|
|
return "", errors.New("Unknown error")
|
|
return "", errors.New("Unknown error")
|
|
|
}
|
|
}
|
|
@@ -106,7 +67,7 @@ func (user *User) Login(username string, password string) (string, error) {
|
|
|
|
|
|
|
|
return tokenString, nil // return tokenString (Cookie)
|
|
return tokenString, nil // return tokenString (Cookie)
|
|
|
} else {
|
|
} else {
|
|
|
- return "", errors.New(ERR_PASSWORD_MISMATCH) // wrong password
|
|
|
|
|
|
|
+ return "", errors.New(errorhelpers.ERR_PASSWORD_MISMATCH) // wrong password
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -127,14 +88,13 @@ func LogoutHandler(ctx *iris.Context) {
|
|
|
userID := ctx.GetString("userID")
|
|
userID := ctx.GetString("userID")
|
|
|
|
|
|
|
|
user, err := GetUserFromDB(userID)
|
|
user, err := GetUserFromDB(userID)
|
|
|
- if err != nil {
|
|
|
|
|
- templatehelpers.ShowError([]string{err.Error()}, ctx)
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
|
|
|
|
|
user.Logout(userID);
|
|
user.Logout(userID);
|
|
|
ctx.SetCookieKV("token", "")
|
|
ctx.SetCookieKV("token", "")
|
|
|
- templatehelpers.ShowNotification([]string{"Successfully logged out", "login"}, ctx)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ err = errors.New(errorhelpers.SUCCESS_LOGOUT)
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (user *User) Update() error {
|
|
func (user *User) Update() error {
|
|
@@ -171,7 +131,7 @@ func SearchUserByUsername(username string) int {
|
|
|
|
|
|
|
|
func VerifyUserLoggedIn(tokenString string) (bool, string, error) { // TODO renew JWT from time to time preventing expiry
|
|
func VerifyUserLoggedIn(tokenString string) (bool, string, error) { // TODO renew JWT from time to time preventing expiry
|
|
|
if tokenString == "" { // if no tokenString("Cookie") exists fail
|
|
if tokenString == "" { // if no tokenString("Cookie") exists fail
|
|
|
- return false, "-1", errors.New(ERR_INVALID_TOKEN)
|
|
|
|
|
|
|
+ return false, "-1", errors.New(errorhelpers.ERR_INVALID_TOKEN)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
hmacSampleSecret := []byte(configutils.Conf.CryptoKey) // crypto key for JWT encryption
|
|
hmacSampleSecret := []byte(configutils.Conf.CryptoKey) // crypto key for JWT encryption
|
|
@@ -189,13 +149,13 @@ func VerifyUserLoggedIn(tokenString string) (bool, string, error) { // TODO rene
|
|
|
if sliceID != -1 { // searchUser returns -1 if there's no such user
|
|
if sliceID != -1 { // searchUser returns -1 if there's no such user
|
|
|
return true, userID, nil // logged in, TODO: "0" template comparision dynamic
|
|
return true, userID, nil // logged in, TODO: "0" template comparision dynamic
|
|
|
} else {
|
|
} else {
|
|
|
- return false, "-1", errors.New(ERR_SESSION_TIMED_OUT) // Session probably expired - may also be faked? TODO more checks?
|
|
|
|
|
|
|
+ return false, "-1", errors.New(errorhelpers.ERR_SESSION_TIMED_OUT) // Session probably expired - may also be faked? TODO more checks?
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
return false, "-1", 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 {
|
|
} else {
|
|
|
- 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
|
|
|
|
|
|
|
+ return false, "-1", errors.New(errorhelpers.ERR_INVALID_TOKEN) // Token is invalid, expired or whatever, TODO switch with ERR_SESSION_TIMED_OUT when database based session system
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -203,19 +163,17 @@ func AuthHandler(ctx *iris.Context) {
|
|
|
tokenString := ctx.GetCookie("token")
|
|
tokenString := ctx.GetCookie("token")
|
|
|
isAuthed, userID, err := VerifyUserLoggedIn(tokenString)
|
|
isAuthed, userID, err := VerifyUserLoggedIn(tokenString)
|
|
|
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- // fmt.Println("Auth error: ", err.Error())
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if isAuthed {
|
|
if isAuthed {
|
|
|
ctx.Set("userID", userID) // save userID for in-context use
|
|
ctx.Set("userID", userID) // save userID for in-context use
|
|
|
- ctx.Next() // successfully authed, next handler
|
|
|
|
|
- } else {
|
|
|
|
|
- if err := ctx.Render("login_box.html", PageUserParams{"1", err.Error(), "login", "", "0", []string{}}); err != nil {
|
|
|
|
|
- //println(err.Error()) // TODO log this somewhere
|
|
|
|
|
- } // failed to auth
|
|
|
|
|
|
|
+ userArrayID := SearchUser(userID)
|
|
|
|
|
|
|
|
|
|
+ params := ctx.Get("params").(map[string]string)
|
|
|
|
|
+ params["username"] = (*Users)[userArrayID].Username
|
|
|
|
|
+ params["admin"] = (*Users)[userArrayID].Admin // TODO rename to isAdmin ?
|
|
|
|
|
+ ctx.Set("params", params)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx) // if error, show error, otherwise next middleware
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func CanBeAuthedHandler(ctx *iris.Context) {
|
|
func CanBeAuthedHandler(ctx *iris.Context) {
|
|
@@ -226,7 +184,7 @@ func CanBeAuthedHandler(ctx *iris.Context) {
|
|
|
ctx.Set("userID", userID) // save userID for in-context use
|
|
ctx.Set("userID", userID) // save userID for in-context use
|
|
|
} else if err != nil {
|
|
} else if err != nil {
|
|
|
if !((err.Error() != "ERR_SESSION_TIMED_OUT") || (err.Error() != "ERR_INVALID_TOKEN")) { // ignore ERR_SESSION_TIMED_OUT and ERR_INVALID_TOKEN
|
|
if !((err.Error() != "ERR_SESSION_TIMED_OUT") || (err.Error() != "ERR_INVALID_TOKEN")) { // ignore ERR_SESSION_TIMED_OUT and ERR_INVALID_TOKEN
|
|
|
- templatehelpers.ShowError([]string{err.Error()}, ctx)
|
|
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -288,6 +246,17 @@ func GetTokens(used bool) []string {
|
|
|
return tokens
|
|
return tokens
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func GetTokensAsString(used bool) string {
|
|
|
|
|
+ tokens := GetTokens(used)
|
|
|
|
|
+ ret := ""
|
|
|
|
|
+
|
|
|
|
|
+ for i := range tokens {
|
|
|
|
|
+ ret += fmt.Sprintf("%s\n", tokens[i])
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return ret
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func GetUser(userID string) (User, error) {
|
|
func GetUser(userID string) (User, error) {
|
|
|
usersArrayID := SearchUser(userID)
|
|
usersArrayID := SearchUser(userID)
|
|
|
|
|
|
|
@@ -366,15 +335,15 @@ func VerifyUserUpdate(username string, password string, userID string) error {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if SearchUserByUsernameInDB(username) != -1 && username != tmpUser.Username { // username can't be changed as there already exists a user with that name or it's the old name
|
|
if SearchUserByUsernameInDB(username) != -1 && username != tmpUser.Username { // username can't be changed as there already exists a user with that name or it's the old name
|
|
|
- return errors.New(ERR_USERNAME_TAKEN)
|
|
|
|
|
|
|
+ return errors.New(errorhelpers.ERR_USERNAME_TAKEN)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if username == "" { // if not left empty change
|
|
if username == "" { // if not left empty change
|
|
|
- return errors.New(ERR_INVALID_PARAM)
|
|
|
|
|
|
|
+ return errors.New(errorhelpers.ERR_INVALID_PARAM)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if password == "" { // if not left empty we change it
|
|
if password == "" { // if not left empty we change it
|
|
|
- return errors.New(ERR_INVALID_PARAM)
|
|
|
|
|
|
|
+ return errors.New(errorhelpers.ERR_INVALID_PARAM)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
return nil
|
|
@@ -442,14 +411,15 @@ func RegisterHandler(ctx *iris.Context) {
|
|
|
usedToken := IsTokenUsed(usedTokens, token) // check if token is used
|
|
usedToken := IsTokenUsed(usedTokens, token) // check if token is used
|
|
|
|
|
|
|
|
if !unusedToken && !usedToken { // token doesnt exist
|
|
if !unusedToken && !usedToken { // token doesnt exist
|
|
|
- templatehelpers.ShowError([]string{ERR_INVALID_TOKEN}, ctx)
|
|
|
|
|
|
|
+ err := errors.New(errorhelpers.ERR_INVALID_TOKEN) // TODO rename this to differ from cookie-token?
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
tokenUserID, err := SearchUserByTokenInDB(token)
|
|
tokenUserID, err := SearchUserByTokenInDB(token)
|
|
|
if err != nil { // id of user, we're going to change if exists
|
|
if err != nil { // id of user, we're going to change if exists
|
|
|
if err.Error() != "ERR_EMPTY_RESULT" { // if no user found for that token let them register
|
|
if err.Error() != "ERR_EMPTY_RESULT" { // if no user found for that token let them register
|
|
|
- templatehelpers.ShowError([]string{err.Error()}, ctx)
|
|
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -462,26 +432,29 @@ func RegisterHandler(ctx *iris.Context) {
|
|
|
|
|
|
|
|
err := RegisterUserWithToken(username, string(passwordBin), token) // register user
|
|
err := RegisterUserWithToken(username, string(passwordBin), token) // register user
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- templatehelpers.ShowError([]string{err.Error()}, ctx)
|
|
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
tokenString, err := user.Login(username, password) // try to login
|
|
tokenString, err := user.Login(username, password) // try to login
|
|
|
|
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- templatehelpers.ShowError([]string{err.Error()}, ctx)
|
|
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
} else {
|
|
} else {
|
|
|
ctx.SetCookieKV("token", tokenString) // set tokenString as cookie
|
|
ctx.SetCookieKV("token", tokenString) // set tokenString as cookie
|
|
|
- templatehelpers.ShowNotification([]string{"registration successfull", "home"}, ctx)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ err = errors.New(errorhelpers.SUCCESS_REGISTER)
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} else { // used token -> update
|
|
} else { // used token -> update
|
|
|
if err := UserUpdateProcessor(username, password, tokenUserIDStr); err != nil { // simply try to update
|
|
if err := UserUpdateProcessor(username, password, tokenUserIDStr); err != nil { // simply try to update
|
|
|
- templatehelpers.ShowError([]string{err.Error()}, ctx)
|
|
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
return
|
|
return
|
|
|
} else {
|
|
} else {
|
|
|
user.Logout(tokenUserIDStr) // log user out from system
|
|
user.Logout(tokenUserIDStr) // log user out from system
|
|
|
- templatehelpers.ShowNotification([]string{"reset successfull", "login"}, ctx)
|
|
|
|
|
|
|
+ err = errors.New(errorhelpers.SUCCESS_UPDATE)
|
|
|
|
|
+ errorhelpers.HandleError(err, ctx)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|