package main import ( "github.com/kataras/iris" "github.com/kataras/go-template/html" "fmt" "git.mmnx.de/Moe/usermanager" "git.mmnx.de/Moe/databaseutils" "git.mmnx.de/Moe/configutils" "git.mmnx.de/Moe/templatehelpers" "golang.org/x/crypto/bcrypt" // "errors" "strconv" ) type pageUserParams struct { // TODO outsource HasError string Error string ReqDir string Username string Email string Admin string } func main() { conf := configutils.ReadConfig("config.json") // read config configutils.Conf = &conf // store conf globally accessible databaseutils.DBUtil = &databaseutils.DBUtils{configutils.Conf.DBUser, configutils.Conf.DBPass, configutils.Conf.DBHost, configutils.Conf.DBName, nil} // init dbutils databaseutils.DBUtil.Connect() // connect to db users := make([]usermanager.User, 0) // users list usermanager.Users = &users // store globally accessible fmt.Print("") // for not needing to remove fmt ... iris.Config.IsDevelopment = true //iris.Config.Render.Template.Gzip = true /** HELPER FUNCTION EXAMPLE **/ /*config := html.DefaultConfig() config.Layout = "layouts/main.html" config.Helpers["boldme"] = func(input string) raymond.SafeString { return raymond.SafeString(" " + input + "") }*/ /** ROUTING **/ iris.UseTemplate(html.New(html.Config{ // main layout for all pages (like a wrapper for boxes we register downwards) Layout: "layouts/main.html", })) iris.Static("/js", "./static/js", 1) // make js files in static/js available via /js iris.Static("/css", "./static/css", 1) iris.Static("/img", "./static/img", 1) iris.Static("/static", "./static/static", 1) iris.Post("/login", loginHandler) // login form handler iris.Post("/register", registerHandler, usermanager.LogoutHandler) // handles registration, logs user out iris.Post("/account", usermanager.AuthHandler, accountUpdateHandler, usermanager.LogoutHandler) // account management iris.Post("/admin", usermanager.AuthHandler, usermanager.AdminHandler, adminPostHandler) // admin panel iris.Get("/login", templateHandler) // TODO not when logged in iris.Get("/logout", usermanager.AuthHandler, usermanager.LogoutHandler) iris.Get("/register", templateHandler) // TODO not when logged in iris.Get("/", usermanager.AuthHandler, templateHandler) iris.Get("/account", usermanager.AuthHandler, templateHandler) iris.Get("/help", usermanager.AuthHandler, templateHandler) iris.Get("/admin", usermanager.AuthHandler, usermanager.AdminHandler, templateHandler) /** OTHER **/ iris.Listen(":8080") } func loginHandler(ctx *iris.Context) { username := ctx.FormValueString("username") // POST values from login form password := ctx.FormValueString("password") user := usermanager.User{} // new user tokenString, err := user.Login(username, password) // try to login if err != nil { templatehelpers.ShowError(err.Error(), ctx, "login") } else { ctx.SetCookieKV("token", tokenString) templatehelpers.ShowNotification("Login successfull", ctx, "home") } } func registerHandler(ctx *iris.Context) { // TODO outsource token := ctx.FormValueString("token") // POST values from login form username := ctx.FormValueString("username") password := ctx.FormValueString("password") user := usermanager.User{} // new user tokenUserID, err := usermanager.SearchUserByTokenInDB(token) // user, we're going to change if err != nil { templatehelpers.ShowError(err.Error(), ctx, "register") return } tokenUserIDStr := strconv.FormatInt(int64(tokenUserID), 10) if err != nil { templatehelpers.ShowError(err.Error(), ctx, "register") return } tokenUser, err := usermanager.GetUserFromDB(tokenUserIDStr) if err != nil { templatehelpers.ShowError(err.Error(), ctx, "register") return } unusedTokens := usermanager.GetTokens(false) // get all unused tokens usedTokens := usermanager.GetTokens(true) // get all used tokens unusedToken := usermanager.IsTokenUsed(unusedTokens, token) usedToken := usermanager.IsTokenUsed(usedTokens, token) if !unusedToken && !usedToken { // token doesnt exist templatehelpers.ShowError(usermanager.ERR_INVALID_TOKEN, ctx, "register") } userID := usermanager.SearchUserByUsernameInDB(username) // check if a user with that name already exists if userID != -1 { tokenUserIDInt, err := strconv.Atoi(tokenUser.ID) // convert userID to int ... if err != nil { templatehelpers.ShowError(err.Error(), ctx, "register") return } if userID != tokenUserIDInt { // tries to steal another users identity templatehelpers.ShowError(usermanager.ERR_USERNAME_TAKEN, ctx, "register") return } // if it's his own name, that's "taken" he can change } if unusedToken { passwordBin, _ := bcrypt.GenerateFromPassword([]byte(password), 15) // hash password err := usermanager.RegisterUserWithToken(username, string(passwordBin), token) // register user if err != nil { templatehelpers.ShowError(err.Error(), ctx, "register") return } tokenString, err := user.Login(username, password) // try to login if err != nil { templatehelpers.ShowError(err.Error(), ctx, "login") } else { ctx.SetCookieKV("token", tokenString) templatehelpers.ShowNotification("registration successfull", ctx, "home") } } else { if err := usermanager.UserUpdateProcessor(username, password, tokenUserIDStr); err != nil { templatehelpers.ShowError(err.Error(), ctx, "register") return } else { tokenString, err := user.Login(username, password) // try to login with new data if err != nil { templatehelpers.ShowError(err.Error(), ctx, "login") } ctx.SetCookieKV("token", tokenString) templatehelpers.ShowNotification("reset successfull", ctx, "home") } } } func accountUpdateHandler(ctx *iris.Context) { username := ctx.FormValueString("username") // POST values password := ctx.FormValueString("password") userID := ctx.GetString("userID") if err := usermanager.UserUpdateProcessor(username, password, userID); err != nil { templatehelpers.ShowError(err.Error(), ctx, "account") return } templatehelpers.ShowNotification("updated successfull", ctx, "account") } func adminPostHandler(ctx *iris.Context) { _ = usermanager.GenerateTokens(5) // generate tokens and store in db, we don't need them now templatehelpers.ShowNotification("tokens generated", ctx, "admin") } func templateHandler(ctx *iris.Context) { var params usermanager.PageUserParams userID := ctx.GetString("userID") user, err := usermanager.GetUser(userID) if err != nil { if err.Error() != "User not logged in" { fmt.Println(err.Error()) } } template := "" switch ctx.RequestPath(false) { default: template = "home" params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, []string{}} case "/": template = "home" params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, []string{}} case "/account": template = "account" params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, []string{}} case "/help": template = "help" params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, []string{}} case "/admin": template = "admin" tokens := usermanager.GetTokens(false) params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, tokens} case "/login": template = "login" params = usermanager.PageUserParams{"0", "", template, "", "0", []string{}} case "/register": template = "register" params = usermanager.PageUserParams{"0", "", template, "", "0", []string{}} } ctx.MustRender(template + "_box.html", params); }