main.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package main
  2. import (
  3. "github.com/kataras/iris"
  4. "github.com/kataras/go-template/html"
  5. "fmt"
  6. "git.mmnx.de/Moe/databaseutils"
  7. "git.mmnx.de/Moe/usermanager"
  8. "git.mmnx.de/Moe/configutils"
  9. "golang.org/x/crypto/bcrypt"
  10. "errors"
  11. )
  12. type pageUserParams struct{
  13. HasError string
  14. Error string
  15. ReqDir string
  16. Username string
  17. Email string
  18. Admin string
  19. } // {Error: ""}
  20. func main() {
  21. conf := configutils.ReadConfig("config.json") // read config
  22. configutils.Conf = &conf // store conf globally accessible
  23. databaseutils.DBUtil = &databaseutils.DBUtils{configutils.Conf.DBUser, configutils.Conf.DBPass, configutils.Conf.DBHost, configutils.Conf.DBName, nil} // init dbutils
  24. databaseutils.DBUtil.Connect() // connect to db
  25. users := make([]usermanager.User, 0) // users list
  26. usermanager.Users = &users // store globally accessible
  27. fmt.Print("") // for not needing to remove fmt ...
  28. iris.Config.IsDevelopment = true
  29. //iris.Config.Render.Template.Gzip = true
  30. /** HELPER FUNCTION EXAMPLE **/
  31. /*config := html.DefaultConfig()
  32. config.Layout = "layouts/main.html"
  33. config.Helpers["boldme"] = func(input string) raymond.SafeString {
  34. return raymond.SafeString("<b> " + input + "</b>")
  35. }*/
  36. /** ROUTING **/
  37. iris.UseTemplate(html.New(html.Config{
  38. Layout: "layouts/main.html",
  39. }))
  40. iris.Static("/js", "./static/js", 1)
  41. iris.Static("/css", "./static/css", 1)
  42. iris.Static("/img", "./static/img", 1)
  43. iris.Static("/static", "./static/static", 1)
  44. iris.Post("/login", loginHandler) // login form handler
  45. iris.Post("/account", usermanager.AuthHandler, accountUpdateHandler)
  46. iris.Post("/admin", usermanager.AuthHandler, usermanager.AdminHandler, adminPostHandler)
  47. iris.Get("/login", templateHandler)
  48. iris.Get("/", usermanager.AuthHandler, templateHandler)
  49. iris.Get("/account", usermanager.AuthHandler, templateHandler)
  50. iris.Get("/help", usermanager.AuthHandler, templateHandler)
  51. iris.Get("/admin", usermanager.AuthHandler, usermanager.AdminHandler, templateHandler)
  52. /** OTHER **/
  53. iris.Listen(":8080")
  54. }
  55. func loginHandler(ctx *iris.Context) {
  56. username := ctx.FormValueString("username") // POST values from login form
  57. password := ctx.FormValueString("password")
  58. user := usermanager.User{} // new user
  59. tokenString, err := user.Login(username, password) // try to login
  60. if err != nil {
  61. ctx.Render("login_box.html", usermanager.PageParams{"1", err.Error(), "login", "0"})
  62. } else {
  63. ctx.SetCookieKV("token", tokenString)
  64. ctx.Redirect("/")
  65. // TODO: error-alternative success (main.html)
  66. }
  67. }
  68. func accountUpdateHandler(ctx *iris.Context) { // TODO tidy up?
  69. err := errors.New(""); err = nil
  70. username := ctx.FormValueString("username") // POST values
  71. password := ctx.FormValueString("password")
  72. userID := ctx.GetString("userID")
  73. usersArrayID := usermanager.SearchUser(userID)
  74. user := (*usermanager.Users)[usersArrayID] // user must be logged in to do this -> get from users list
  75. 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
  76. ctx.Render("account_box.html", usermanager.PageUserParams{"1", errors.New("Username already taken").Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
  77. return
  78. }
  79. needQuery := false
  80. if username != "" { // if not left empty (-> change)
  81. needQuery = true
  82. } else {
  83. username = user.Username // keep
  84. }
  85. hashedPassword := user.Password // we assumpt the user's not changing his password
  86. if password != "" { // if not left empty we change it
  87. needQuery = true
  88. hashedPassword, err = func (hashedPassword []byte, err error) (string, error) { // hash password, we use an anonymous function to convert it to string
  89. if err != nil { // should never happen
  90. ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
  91. return "", err
  92. }
  93. return string(hashedPassword), nil
  94. }(bcrypt.GenerateFromPassword([]byte(password), 15)) // this is the actual hashing call
  95. if err != nil { // should never happen
  96. ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
  97. return
  98. }
  99. }
  100. if !needQuery { // we don't need to update anything
  101. ctx.Render("account_box.html", usermanager.PageUserParams{"1", errors.New("nothing to update").Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
  102. return
  103. }
  104. (*usermanager.Users)[usermanager.SearchUser(userID)].Username = username // update values in runtime users list
  105. (*usermanager.Users)[usermanager.SearchUser(userID)].Password = hashedPassword
  106. err = (*usermanager.Users)[usermanager.SearchUser(userID)].Update() // try to update in db
  107. if err != nil { // failed to update
  108. ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
  109. return
  110. }
  111. // TODO success notifications
  112. if err != nil {
  113. ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}}) // TODO dynamic
  114. } else {
  115. ctx.Render("account_box.html", usermanager.PageUserParams{"0", "", "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}}) // TODO dynamic
  116. }
  117. }
  118. func adminPostHandler(ctx *iris.Context) {
  119. _ = usermanager.GenerateTokens(5) // generate tokens and store in db, we don't need them now
  120. ctx.Redirect("/admin") // just redirect so that we see old+new tokens
  121. // TODO success notifications
  122. }
  123. func templateHandler(ctx *iris.Context) {
  124. var params usermanager.PageUserParams
  125. userID := ctx.GetString("userID")
  126. user, err := usermanager.GetUser(userID)
  127. if err != nil { // user is apparently not logged in -> login
  128. ctx.MustRender("login_box.html", pageUserParams{"1", err.Error(), "login", "", "", "0"})
  129. return
  130. }
  131. template := ""
  132. switch ctx.RequestPath(false) {
  133. default:
  134. template = "home"
  135. params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{}}
  136. case "/":
  137. template = "home"
  138. params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{}}
  139. case "/account":
  140. template = "account"
  141. params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{}}
  142. case "/help":
  143. template = "help"
  144. params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{}}
  145. case "/admin":
  146. template = "admin"
  147. tokens, err := databaseutils.DBUtil.GetRows("*", "tokens", "used", "0") // get unused tokens // TODO: outsource in function GetTokens()
  148. if err != nil {
  149. fmt.Println(err.Error()) // TODO: nicer / outsource
  150. }
  151. message := "" // string for textarea output in /admin
  152. for i, _ := range tokens { // TODO outsource
  153. message += tokens[i][1] + "\n"
  154. } // TODO outsource function until here
  155. params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{message}}
  156. case "/login":
  157. template = "login"
  158. params = usermanager.PageUserParams{"0", "", template, "", "", "0", []string{"ayy", "lmao"}}
  159. }
  160. // fmt.Println(ctx.RequestPath(false))
  161. // fmt.Println(template)
  162. ctx.MustRender(template + "_box.html", params);
  163. }