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.
 
 
 
 
 

137 lines
3.7 KiB

  1. /*
  2. * Copyright © 2018-2021 Musing Studio LLC.
  3. *
  4. * This file is part of WriteFreely.
  5. *
  6. * WriteFreely is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License, included
  8. * in the LICENSE file in this source code package.
  9. */
  10. package author
  11. import (
  12. "github.com/writeas/web-core/log"
  13. "github.com/writefreely/writefreely/config"
  14. "os"
  15. "path/filepath"
  16. "regexp"
  17. )
  18. // Regex pattern for valid usernames
  19. var validUsernameReg = regexp.MustCompile("^[a-zA-Z0-9][a-zA-Z0-9-]*$")
  20. // List of reserved usernames
  21. var reservedUsernames = map[string]bool{
  22. "a": true,
  23. "about": true,
  24. "add": true,
  25. "admin": true,
  26. "administrator": true,
  27. "adminzone": true,
  28. "api": true,
  29. "article": true,
  30. "articles": true,
  31. "auth": true,
  32. "authenticate": true,
  33. "browse": true,
  34. "c": true,
  35. "categories": true,
  36. "category": true,
  37. "changes": true,
  38. "community": true,
  39. "create": true,
  40. "css": true,
  41. "data": true,
  42. "dev": true,
  43. "developers": true,
  44. "draft": true,
  45. "drafts": true,
  46. "edit": true,
  47. "edits": true,
  48. "faq": true,
  49. "feed": true,
  50. "feedback": true,
  51. "guide": true,
  52. "guides": true,
  53. "help": true,
  54. "index": true,
  55. "invite": true,
  56. "js": true,
  57. "login": true,
  58. "logout": true,
  59. "me": true,
  60. "media": true,
  61. "meta": true,
  62. "metadata": true,
  63. "new": true,
  64. "news": true,
  65. "oauth": true,
  66. "post": true,
  67. "posts": true,
  68. "privacy": true,
  69. "publication": true,
  70. "publications": true,
  71. "publish": true,
  72. "random": true,
  73. "read": true,
  74. "reader": true,
  75. "register": true,
  76. "remove": true,
  77. "signin": true,
  78. "signout": true,
  79. "signup": true,
  80. "start": true,
  81. "status": true,
  82. "summary": true,
  83. "support": true,
  84. "tag": true,
  85. "tags": true,
  86. "team": true,
  87. "template": true,
  88. "templates": true,
  89. "terms": true,
  90. "terms-of-service": true,
  91. "termsofservice": true,
  92. "theme": true,
  93. "themes": true,
  94. "tips": true,
  95. "tos": true,
  96. "update": true,
  97. "updates": true,
  98. "user": true,
  99. "users": true,
  100. "yourname": true,
  101. }
  102. // IsValidUsername returns true if a given username is neither reserved nor
  103. // of the correct format.
  104. func IsValidUsername(cfg *config.Config, username string) bool {
  105. // Username has to be above a character limit
  106. if len(username) < cfg.App.MinUsernameLen {
  107. return false
  108. }
  109. // Username is invalid if page with the same name exists. So traverse
  110. // available pages, adding them to reservedUsernames map that'll be checked
  111. // later.
  112. err := filepath.Walk(filepath.Join(cfg.Server.PagesParentDir, "pages"), func(path string, i os.FileInfo, err error) error {
  113. if err != nil {
  114. return err
  115. }
  116. reservedUsernames[i.Name()] = true
  117. return nil
  118. })
  119. if err != nil {
  120. log.Error("[IMPORTANT WARNING]: Could not determine IsValidUsername! %s", err)
  121. return false
  122. }
  123. // Username is invalid if it is reserved!
  124. if _, reserved := reservedUsernames[username]; reserved {
  125. return false
  126. }
  127. // TODO: use correct regexp function here
  128. return len(validUsernameReg.FindStringSubmatch(username)) > 0
  129. }