| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- package main
- import (
- "github.com/kataras/iris"
- "github.com/kataras/go-template/html"
- "fmt"
- "git.mmnx.de/Moe/databaseutils"
- "git.mmnx.de/Moe/usermanager"
- "git.mmnx.de/Moe/configutils"
- "golang.org/x/crypto/bcrypt"
- "errors"
- )
- type pageUserParams struct{
- HasError string
- Error string
- ReqDir string
- Username string
- Email string
- Admin string
- } // {Error: ""}
- 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("<b> " + input + "</b>")
- }*/
- /** ROUTING **/
- iris.UseTemplate(html.New(html.Config{
- Layout: "layouts/main.html",
- }))
- iris.Static("/js", "./static/js", 1)
- 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("/account", usermanager.AuthHandler, accountUpdateHandler)
- iris.Post("/admin", usermanager.AuthHandler, usermanager.AdminHandler, adminPostHandler)
- iris.Get("/login", templateHandler)
- iris.Get("/", usermanager.AuthHandler, templateHandler)
- iris.Get("/account", usermanager.AuthHandler, templateHandler)
- iris.Get("/help", usermanager.AuthHandler, templateHandler)
- iris.Get("/admin", usermanager.AuthHandler, usermanager.AdminHandler, func(ctx *iris.Context) { // TODO integrate in outsource (templateHandler)
- userID := ctx.GetString("userID")
- user, err := usermanager.GetUser(userID)
- tokens, err := databaseutils.DBUtil.GetRows("*", "tokens", "used", "0") // get unused tokens
- if err != nil {
- fmt.Println(err.Error()) // TODO: nicer
- }
- message := "" // string for textarea output in /admin
- for i, _ := range tokens {
- message += tokens[i][1] + "\n"
- }
- params := usermanager.PageUserParamsMessage{"0", "", "admin", user.Username, "", user.Admin, message}
- if err := ctx.Render("admin_box.html", params); err != nil {
- println(err.Error())
- }
- })
- /** 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 {
- ctx.Render("login_box.html", usermanager.PageParams{"1", err.Error(), "login", "0"})
- } else {
- ctx.SetCookieKV("token", tokenString)
- ctx.Redirect("/")
- // TODO: error-alternative success (main.html)
- }
- }
- func accountUpdateHandler(ctx *iris.Context) { // TODO tidy up?
- err := errors.New(""); err = nil
- username := ctx.FormValueString("username") // POST values
- password := ctx.FormValueString("password")
- userID := ctx.GetString("userID")
- usersArrayID := usermanager.SearchUser(userID)
- user := (*usermanager.Users)[usersArrayID] // user must be logged in to do this -> get from users list
- if username != "" && usermanager.SearchUserByUsername(username) != -1 && username != user.Username { // username can't be changed as there already exists a user with that name or it's the old name
- ctx.Render("account_box.html", usermanager.PageUserParams{"1", errors.New("Username already taken").Error(), "account", user.Username, user.Mail, user.Admin})
- return
- }
- needQuery := false
- if username != "" { // if not left empty (-> change)
- needQuery = true
- } else {
- username = user.Username // keep
- }
- hashedPassword := user.Password // we assumpt the user's not changing his password
- if password != "" { // if not left empty we change it
- needQuery = true
- hashedPassword, err = func (hashedPassword []byte, err error) (string, error) { // hash password, we use an anonymous function to convert it to string
- if err != nil { // should never happen
- ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin})
- return "", err
- }
- return string(hashedPassword), nil
- }(bcrypt.GenerateFromPassword([]byte(password), 15)) // this is the actual hashing call
- if err != nil { // should never happen
- ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin})
- return
- }
- }
- if !needQuery { // we don't need to update anything
- ctx.Render("account_box.html", usermanager.PageUserParams{"1", errors.New("nothing to update").Error(), "account", user.Username, user.Mail, user.Admin})
- return
- }
- (*usermanager.Users)[usermanager.SearchUser(userID)].Username = username // update values in runtime users list
- (*usermanager.Users)[usermanager.SearchUser(userID)].Password = hashedPassword
- err = (*usermanager.Users)[usermanager.SearchUser(userID)].Update() // try to update in db
- if err != nil { // failed to update
- ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin})
- return
- }
- // TODO success notifications
- if err != nil {
- ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin}) // TODO dynamic
- } else {
- ctx.Render("account_box.html", usermanager.PageUserParams{"0", "", "account", user.Username, user.Mail, user.Admin}) // TODO dynamic
- }
- }
- func adminPostHandler(ctx *iris.Context) {
- err := errors.New(""); err = nil
- userID := ctx.GetString("userID")
- usersArrayID := usermanager.SearchUser(userID)
- err = usermanager.GenerateTokens(5) // tokens
- if err != nil {
- ctx.Render("admin_box.html", usermanager.PageUserParams{"1", err.Error(), "admin", user.Username, user.Mail, user.Admin}) // TODO dynamic
- fmt.Println(err.Error())
- return
- }
- ctx.Redirect("/admin") // just redirect so that we see old+new tokens
- // TODO success notifications
- }
- func templateHandler(ctx *iris.Context) {
- template := ""
- switch ctx.RequestPath(false) {
- case "/":
- template = "home"
- case "/account":
- template = "account"
- case "/help":
- template = "help"
- case "/admin":
- template = "admin"
- case "/login":
- template = "login"
- }
- // fmt.Println(ctx.RequestPath(false))
- // fmt.Println(template)
- userID := ctx.GetString("userID")
- user, err := usermanager.GetUser(userID)
- if err != nil { // user is apparently not logged in -> login
- ctx.MustRender("login_box.html", pageUserParams{"1", err.Error(), template, "", "", "0"})
- return
- }
- params := usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin}
- ctx.MustRender(template + "_box.html", params);
- }
|