The new Ripple frontend.
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.

helpers.go 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package main
  2. import (
  3. gocontext "context"
  4. "crypto/md5"
  5. "encoding/json"
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "net/url"
  10. "strings"
  11. "time"
  12. "bytes"
  13. "github.com/gin-gonic/gin"
  14. "zxq.co/ripple/hanayo/modules/bbcode"
  15. tp "zxq.co/ripple/hanayo/modules/top-passwords"
  16. "zxq.co/ripple/rippleapi/common"
  17. )
  18. //go:generate go run scripts/generate_mappings.go -g
  19. //go:generate go run scripts/top_passwords.go
  20. func cmd5(s string) string {
  21. return fmt.Sprintf("%x", md5.Sum([]byte(s)))
  22. }
  23. func validatePassword(p string) string {
  24. if len(p) < 8 {
  25. return "Your password is too short! It must be at least 8 characters long."
  26. }
  27. for _, k := range tp.TopPasswords {
  28. if k == p {
  29. return "Your password is one of the most common passwords on the entire internet. No way we're letting you use that!"
  30. }
  31. }
  32. return ""
  33. }
  34. func recaptchaCheck(c *gin.Context) bool {
  35. f := make(url.Values)
  36. f.Add("secret", config.RecaptchaPrivate)
  37. f.Add("response", c.PostForm("g-recaptcha-response"))
  38. f.Add("remoteip", clientIP(c))
  39. req, err := http.Post("https://www.google.com/recaptcha/api/siteverify",
  40. "application/x-www-form-urlencoded", strings.NewReader(f.Encode()))
  41. if err != nil {
  42. c.Error(err)
  43. return false
  44. }
  45. data, err := ioutil.ReadAll(req.Body)
  46. if err != nil {
  47. c.Error(err)
  48. return false
  49. }
  50. var e struct {
  51. Success bool `json:"success"`
  52. }
  53. err = json.Unmarshal(data, &e)
  54. if err != nil {
  55. c.Error(err)
  56. return false
  57. }
  58. return e.Success
  59. }
  60. func parseBBCode(c *gin.Context) {
  61. body, err := ioutil.ReadAll(c.Request.Body)
  62. if err != nil {
  63. c.Error(err)
  64. c.String(200, "Error")
  65. return
  66. }
  67. d := bbcode.Compile(string(body))
  68. c.String(200, d)
  69. }
  70. func discordFinish(c *gin.Context) {
  71. sess := getSession(c)
  72. defer func() {
  73. sess.Save()
  74. c.Redirect(302, "/settings/discord")
  75. }()
  76. ctx := getContext(c)
  77. if ok, _ := CSRF.Validate(ctx.User.ID, c.Query("state")); !ok {
  78. addMessage(c, errorMessage{T(c, "Your session has expired. Please try redoing what you were trying to do.")})
  79. return
  80. }
  81. if ctx.User.Privileges&common.UserPrivilegeDonor == 0 {
  82. addMessage(c, errorMessage{T(c, "You're not a donor!")})
  83. return
  84. }
  85. reqCtx, _ := gocontext.WithTimeout(gocontext.Background(), time.Second*20)
  86. tok, err := getDiscord().Exchange(reqCtx, c.Query("code"))
  87. if err != nil {
  88. c.Error(err)
  89. addMessage(c, errorMessage{T(c, "An error occurred.")})
  90. return
  91. }
  92. // Yoloest error handling ever
  93. // Here we're getting the user ID of our user on discord
  94. req, _ := http.NewRequest("GET", "https://discordapp.com/api/users/@me", nil)
  95. req.Header.Set("Authorization", "Bearer "+tok.AccessToken)
  96. resp, _ := http.DefaultClient.Do(req)
  97. rawData, _ := ioutil.ReadAll(resp.Body)
  98. var x struct {
  99. ID string `json:"id"`
  100. }
  101. err = json.Unmarshal(rawData, &x)
  102. if err != nil {
  103. c.Error(err)
  104. addMessage(c, errorMessage{T(c, "An error occurred.")})
  105. return
  106. }
  107. // Here, instead, we're telling donorbot about the user.
  108. // setup post data
  109. vals := make(url.Values, 2)
  110. vals.Set("discord_id", x.ID)
  111. vals.Set("secret", config.DonorBotSecret)
  112. // send request
  113. resp, err = http.Post(config.DonorBotURL+"/api/v1/give_donor", "application/x-www-form-urlencoded", bytes.NewReader([]byte(vals.Encode())))
  114. if err != nil {
  115. c.Error(err)
  116. addMessage(c, errorMessage{T(c, "An error occurred.")})
  117. return
  118. }
  119. var o struct {
  120. Status int `json:"status"`
  121. }
  122. json.NewDecoder(resp.Body).Decode(&o)
  123. switch o.Status {
  124. case 200:
  125. // move on
  126. case 404:
  127. addMessage(c, errorMessage{T(c, "You've not joined the discord server! Links to it are below on the page. Please join the server before attempting to connect your account to Discord.")})
  128. default:
  129. c.Error(fmt.Errorf("donorbot: %d", resp.StatusCode))
  130. addMessage(c, errorMessage{T(c, "An error occurred.")})
  131. return
  132. }
  133. db.Exec("INSERT INTO discord_roles (id, userid, discordid, roleid) VALUES (NULL, ?, ?, 0)", ctx.User.ID, x.ID)
  134. addMessage(c, successMessage{T(c, "Your account has been linked successfully!")})
  135. }
  136. func mustCSRFGenerate(u int) string {
  137. v, err := CSRF.Generate(u)
  138. if err != nil {
  139. panic(err)
  140. }
  141. return v
  142. }
  143. var blogRedirectMap = map[string]string{
  144. "/posts/moving-to-a-new-server": "https://blog.ripple.moe/moving-to-a-new-server-11155949edca",
  145. "/posts/ripple-qa-3": "https://blog.ripple.moe/ripple-q-a-3-28c9851f42b3",
  146. "/posts/hanayo-is-now-the-ripple-website": "https://blog.ripple.moe/hanayo-is-now-the-ripple-website-3bcfaab60c4f",
  147. "/posts/ripple-qa-2": "https://blog.ripple.moe/ripple-q-a-2-1204be5ffeef",
  148. "/posts/hanayo-is-live": "https://blog.ripple.moe/hanayo-is-live-still-not-replacing-the-official-site-f2b751a5baf7",
  149. "/posts/ripple-qa-1": "https://blog.ripple.moe/ripple-q-a-1-51181dd8df65",
  150. "/posts/why-am-i-randomly-gaining-losing-pp": "https://blog.ripple.moe/why-am-i-randomly-gaining-losing-pp-595aedfdc5db",
  151. "/posts/more-love-for-donors": "https://blog.ripple.moe/more-love-for-donors-96c889a9d95f",
  152. "/posts/happy-birthday-ripple": "https://blog.ripple.moe/happy-birthday-ripple-fbc4bbc47936",
  153. "/posts/going-back-open-source": "https://blog.ripple.moe/going-back-open-source-a53469e15658",
  154. "/posts/the-useless-things-we-make-during-weekends-series-continues": "https://blog.ripple.moe/the-useless-things-we-make-during-weekends-series-continues-1a06671ff5c2",
  155. "/posts/performance-points-pp": "https://blog.ripple.moe/performance-points-pp-d02e0353ad81",
  156. "/posts/why-are-you-introducing-so-many-bugs-its-not-like-we-asked-for-them": "https://blog.ripple.moe/why-are-you-introducing-so-many-bugs-its-not-like-we-asked-for-them-c650a8ea9667",
  157. "/posts/going-closed-source": "https://blog.ripple.moe/going-closed-source-5c0a991f581f",
  158. "/posts/changes-in-administration": "https://blog.ripple.moe/changes-in-administration-983114dc6332",
  159. "/posts/its-dangerous-to-go-alone": "https://blog.ripple.moe/its-dangerous-to-go-alone-ef7fa98f2975",
  160. "/posts/we-got-a-blog": "https://blog.ripple.moe/we-got-a-blog-81a0af62b410",
  161. }
  162. func blogRedirect(c *gin.Context) {
  163. a := c.Param("url")
  164. red := blogRedirectMap[a]
  165. if red == "" {
  166. red = "https://blog.ripple.moe"
  167. }
  168. c.Redirect(301, red)
  169. }