A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

131 lines
3.7 KiB

  1. package writefreely
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "github.com/writeas/impart"
  6. "github.com/writeas/web-core/log"
  7. "net/http"
  8. )
  9. func handleWebSignup(app *app, w http.ResponseWriter, r *http.Request) error {
  10. reqJSON := IsJSON(r.Header.Get("Content-Type"))
  11. // Get params
  12. var ur userRegistration
  13. if reqJSON {
  14. decoder := json.NewDecoder(r.Body)
  15. err := decoder.Decode(&ur)
  16. if err != nil {
  17. log.Error("Couldn't parse signup JSON request: %v\n", err)
  18. return ErrBadJSON
  19. }
  20. } else {
  21. err := r.ParseForm()
  22. if err != nil {
  23. log.Error("Couldn't parse signup form request: %v\n", err)
  24. return ErrBadFormData
  25. }
  26. err = app.formDecoder.Decode(&ur, r.PostForm)
  27. if err != nil {
  28. log.Error("Couldn't decode signup form request: %v\n", err)
  29. return ErrBadFormData
  30. }
  31. }
  32. ur.Web = true
  33. ur.Normalize = true
  34. _, err := signupWithRegistration(app, ur, w, r)
  35. if err != nil {
  36. if err, ok := err.(impart.HTTPError); ok {
  37. session, _ := app.sessionStore.Get(r, cookieName)
  38. if session != nil {
  39. session.AddFlash(err.Message)
  40. session.Save(r, w)
  41. return impart.HTTPError{http.StatusFound, "/"}
  42. }
  43. }
  44. return err
  45. }
  46. return impart.HTTPError{http.StatusFound, "/"}
  47. }
  48. // { "username": "asdf" }
  49. // result: { code: 204 }
  50. func handleUsernameCheck(app *app, w http.ResponseWriter, r *http.Request) error {
  51. reqJSON := IsJSON(r.Header.Get("Content-Type"))
  52. // Get params
  53. var d struct {
  54. Username string `json:"username"`
  55. }
  56. if reqJSON {
  57. decoder := json.NewDecoder(r.Body)
  58. err := decoder.Decode(&d)
  59. if err != nil {
  60. log.Error("Couldn't decode username check: %v\n", err)
  61. return ErrBadFormData
  62. }
  63. } else {
  64. return impart.HTTPError{http.StatusNotAcceptable, "Must be JSON request"}
  65. }
  66. // Check if username is okay
  67. finalUsername := getSlug(d.Username, "")
  68. if finalUsername == "" {
  69. errMsg := "Invalid username"
  70. if d.Username != "" {
  71. // Username was provided, but didn't convert into valid latin characters
  72. errMsg += " - must have at least 2 letters or numbers"
  73. }
  74. return impart.HTTPError{http.StatusBadRequest, errMsg + "."}
  75. }
  76. if app.db.PostIDExists(finalUsername) {
  77. return impart.HTTPError{http.StatusConflict, "Username is already taken."}
  78. }
  79. var un string
  80. err := app.db.QueryRow("SELECT username FROM users WHERE username = ?", finalUsername).Scan(&un)
  81. switch {
  82. case err == sql.ErrNoRows:
  83. return impart.WriteSuccess(w, finalUsername, http.StatusOK)
  84. case err != nil:
  85. log.Error("Couldn't SELECT username: %v", err)
  86. return impart.HTTPError{http.StatusInternalServerError, "We messed up."}
  87. }
  88. // Username was found, so it's taken
  89. return impart.HTTPError{http.StatusConflict, "Username is already taken."}
  90. }
  91. func getValidUsername(app *app, reqName, prevName string) (string, *impart.HTTPError) {
  92. // Check if username is okay
  93. finalUsername := getSlug(reqName, "")
  94. if finalUsername == "" {
  95. errMsg := "Invalid username"
  96. if reqName != "" {
  97. // Username was provided, but didn't convert into valid latin characters
  98. errMsg += " - must have at least 2 letters or numbers"
  99. }
  100. return "", &impart.HTTPError{http.StatusBadRequest, errMsg + "."}
  101. }
  102. if finalUsername == prevName {
  103. return "", &impart.HTTPError{http.StatusNotModified, "Username unchanged."}
  104. }
  105. if app.db.PostIDExists(finalUsername) {
  106. return "", &impart.HTTPError{http.StatusConflict, "Username is already taken."}
  107. }
  108. var un string
  109. err := app.db.QueryRow("SELECT username FROM users WHERE username = ?", finalUsername).Scan(&un)
  110. switch {
  111. case err == sql.ErrNoRows:
  112. return finalUsername, nil
  113. case err != nil:
  114. log.Error("Couldn't SELECT username: %v", err)
  115. return "", &impart.HTTPError{http.StatusInternalServerError, "We messed up."}
  116. }
  117. // Username was found, so it's taken
  118. return "", &impart.HTTPError{http.StatusConflict, "Username is already taken."}
  119. }