auth.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/apexskier/httpauth"
  5. "golang.org/x/crypto/bcrypt"
  6. "html/template"
  7. "net/http"
  8. )
  9. var (
  10. backend httpauth.GobFileAuthBackend
  11. aaa httpauth.Authorizer
  12. roles map[string]httpauth.Role
  13. authFile = "admin/auth.gob"
  14. )
  15. func initAuth() {
  16. var err error
  17. // authFile must exist in site home.
  18. // could intruduce a way to dynamically create one or just default install it
  19. backend, err = httpauth.NewGobFileAuthBackend(authFile)
  20. if err != nil {
  21. panic(err)
  22. }
  23. // create some default roles
  24. roles = make(map[string]httpauth.Role)
  25. roles["user"] = 30
  26. roles["admin"] = 80
  27. aaa, err = httpauth.NewAuthorizer(backend, []byte("cookie-encryption-key"), "user", roles)
  28. // create a default user
  29. hash, err := bcrypt.GenerateFromPassword([]byte("adminadmin"), bcrypt.DefaultCost)
  30. if err != nil {
  31. panic(err)
  32. }
  33. defaultUser := httpauth.UserData{Username: "admin", Email: "admin@localhost", Hash: hash, Role: "admin"}
  34. err = backend.SaveUser(defaultUser)
  35. if err != nil {
  36. panic(err)
  37. }
  38. }
  39. func isAuth(w http.ResponseWriter, r *http.Request, admin Location, role string) {
  40. // first check if you are logged in to the admin if not then redirect to login page
  41. title := r.URL.Path[len(admin.Root):]
  42. if err := aaa.Authorize(w, r, true); err != nil && title != "login/" {
  43. fmt.Println(err)
  44. http.Redirect(w, r, admin.Root+"login/", http.StatusSeeOther)
  45. return
  46. }
  47. // next check if you have the required role
  48. if err_role := aaa.AuthorizeRole(w, r, role, false); err_role != nil {
  49. fmt.Println(err_role)
  50. return
  51. }
  52. }
  53. func loginHandler(w http.ResponseWriter, r *http.Request, admin Location) {
  54. if r.Method == "POST" {
  55. username := r.PostFormValue("username")
  56. password := r.PostFormValue("password")
  57. if err := aaa.Login(w, r, username, password, "/"); err != nil && err.Error() == "already authenticated" {
  58. http.Redirect(w, r, admin.Root, http.StatusSeeOther)
  59. } else if err != nil {
  60. fmt.Println(err)
  61. http.Redirect(w, r, admin.Root+"/login/", http.StatusSeeOther)
  62. }
  63. } else {
  64. title := r.URL.Path[len(admin.Root+"login/"):]
  65. p := &Content{Path: title}
  66. renderTemplateContent(w, "login.html", p)
  67. }
  68. }
  69. func adminUsersHandler(w http.ResponseWriter, r *http.Request, admin Location) {
  70. isAuth(w, r, admin, "admin")
  71. if r.Method == "POST" {
  72. var user httpauth.UserData
  73. user.Username = r.PostFormValue("username")
  74. user.Email = r.PostFormValue("email")
  75. password := r.PostFormValue("password")
  76. user.Role = r.PostFormValue("role")
  77. if err := aaa.Register(w, r, user, password); err != nil {
  78. // maybe something
  79. }
  80. }
  81. if user, err := aaa.CurrentUser(w, r); err == nil {
  82. type data struct {
  83. User httpauth.UserData
  84. Roles map[string]httpauth.Role
  85. Users []httpauth.UserData
  86. Msg []string
  87. }
  88. messages := aaa.Messages(w, r)
  89. users, err := backend.Users()
  90. if err != nil {
  91. panic(err)
  92. }
  93. d := data{User: user, Roles: roles, Users: users, Msg: messages}
  94. var templates = template.Must(template.ParseGlob("admin/templates/*"))
  95. t_err := templates.ExecuteTemplate(w, "manage-accounts.html", d)
  96. if t_err != nil {
  97. http.Error(w, err.Error(), http.StatusInternalServerError)
  98. }
  99. }
  100. }
  101. func logoutHandler(w http.ResponseWriter, r *http.Request, admin Location) {
  102. if err := aaa.Logout(w, r); err != nil {
  103. fmt.Println(err)
  104. // this shouldn't happen
  105. return
  106. }
  107. http.Redirect(w, r, admin.Root+"/login/", http.StatusSeeOther)
  108. }