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.
 
 
 
 
 

122 lines
3.5 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. _, err := signupWithRegistration(app, ur, w, r)
  34. if err != nil {
  35. return err
  36. }
  37. return impart.HTTPError{http.StatusFound, "/"}
  38. }
  39. // { "username": "asdf" }
  40. // result: { code: 204 }
  41. func handleUsernameCheck(app *app, w http.ResponseWriter, r *http.Request) error {
  42. reqJSON := IsJSON(r.Header.Get("Content-Type"))
  43. // Get params
  44. var d struct {
  45. Username string `json:"username"`
  46. }
  47. if reqJSON {
  48. decoder := json.NewDecoder(r.Body)
  49. err := decoder.Decode(&d)
  50. if err != nil {
  51. log.Error("Couldn't decode username check: %v\n", err)
  52. return ErrBadFormData
  53. }
  54. } else {
  55. return impart.HTTPError{http.StatusNotAcceptable, "Must be JSON request"}
  56. }
  57. // Check if username is okay
  58. finalUsername := getSlug(d.Username, "")
  59. if finalUsername == "" {
  60. errMsg := "Invalid username"
  61. if d.Username != "" {
  62. // Username was provided, but didn't convert into valid latin characters
  63. errMsg += " - must have at least 2 letters or numbers"
  64. }
  65. return impart.HTTPError{http.StatusBadRequest, errMsg + "."}
  66. }
  67. if app.db.PostIDExists(finalUsername) {
  68. return impart.HTTPError{http.StatusConflict, "Username is already taken."}
  69. }
  70. var un string
  71. err := app.db.QueryRow("SELECT username FROM users WHERE username = ?", finalUsername).Scan(&un)
  72. switch {
  73. case err == sql.ErrNoRows:
  74. return impart.WriteSuccess(w, finalUsername, http.StatusOK)
  75. case err != nil:
  76. log.Error("Couldn't SELECT username: %v", err)
  77. return impart.HTTPError{http.StatusInternalServerError, "We messed up."}
  78. }
  79. // Username was found, so it's taken
  80. return impart.HTTPError{http.StatusConflict, "Username is already taken."}
  81. }
  82. func getValidUsername(app *app, reqName, prevName string) (string, *impart.HTTPError) {
  83. // Check if username is okay
  84. finalUsername := getSlug(reqName, "")
  85. if finalUsername == "" {
  86. errMsg := "Invalid username"
  87. if reqName != "" {
  88. // Username was provided, but didn't convert into valid latin characters
  89. errMsg += " - must have at least 2 letters or numbers"
  90. }
  91. return "", &impart.HTTPError{http.StatusBadRequest, errMsg + "."}
  92. }
  93. if finalUsername == prevName {
  94. return "", &impart.HTTPError{http.StatusNotModified, "Username unchanged."}
  95. }
  96. if app.db.PostIDExists(finalUsername) {
  97. return "", &impart.HTTPError{http.StatusConflict, "Username is already taken."}
  98. }
  99. var un string
  100. err := app.db.QueryRow("SELECT username FROM users WHERE username = ?", finalUsername).Scan(&un)
  101. switch {
  102. case err == sql.ErrNoRows:
  103. return finalUsername, nil
  104. case err != nil:
  105. log.Error("Couldn't SELECT username: %v", err)
  106. return "", &impart.HTTPError{http.StatusInternalServerError, "We messed up."}
  107. }
  108. // Username was found, so it's taken
  109. return "", &impart.HTTPError{http.StatusConflict, "Username is already taken."}
  110. }