register.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. package register
  2. /*
  3. Register Module
  4. author: tobychui
  5. Register interface handler
  6. */
  7. import (
  8. "bufio"
  9. "encoding/base64"
  10. "encoding/json"
  11. "errors"
  12. "io/ioutil"
  13. "log"
  14. "net/http"
  15. "net/mail"
  16. "os"
  17. "strings"
  18. "github.com/valyala/fasttemplate"
  19. auth "imuslab.com/arozos/mod/auth"
  20. db "imuslab.com/arozos/mod/database"
  21. permission "imuslab.com/arozos/mod/permission"
  22. )
  23. type RegisterOptions struct {
  24. Hostname string
  25. VendorIcon string
  26. }
  27. type RegisterHandler struct {
  28. database *db.Database
  29. authAgent *auth.AuthAgent
  30. permissionHandler *permission.PermissionHandler
  31. options RegisterOptions
  32. DefaultUserGroup string
  33. AllowRegistry bool
  34. }
  35. func NewRegisterHandler(database *db.Database, authAgent *auth.AuthAgent, ph *permission.PermissionHandler, options RegisterOptions) *RegisterHandler {
  36. //Create the database for registration
  37. database.NewTable("register")
  38. //Check if the default group has been set. If not a new usergroup
  39. defaultUserGroup := ""
  40. if database.KeyExists("register", "defaultGroup") {
  41. //Use the configured default group
  42. database.Read("register", "defaultGroup", &defaultUserGroup)
  43. //Check the group exists
  44. if !ph.GroupExists(defaultUserGroup) {
  45. //Group not exists. Create default group.
  46. if !ph.GroupExists("default") {
  47. createDefaultGroup(ph)
  48. }
  49. defaultUserGroup = "default"
  50. }
  51. } else {
  52. //Default group not set or not exists. Create a new default group
  53. if !ph.GroupExists("default") {
  54. createDefaultGroup(ph)
  55. }
  56. defaultUserGroup = "default"
  57. }
  58. return &RegisterHandler{
  59. database: database,
  60. options: options,
  61. permissionHandler: ph,
  62. authAgent: authAgent,
  63. DefaultUserGroup: defaultUserGroup,
  64. AllowRegistry: true,
  65. }
  66. }
  67. //Create the default usergroup used by new users
  68. func createDefaultGroup(ph *permission.PermissionHandler) {
  69. //Default storage space: 15GB
  70. ph.NewPermissionGroup("default", false, 15<<30, []string{}, "Desktop")
  71. }
  72. func (h *RegisterHandler) HandleRegisterCheck(w http.ResponseWriter, r *http.Request) {
  73. if h.AllowRegistry {
  74. sendJSONResponse(w, "true")
  75. } else {
  76. sendJSONResponse(w, "false")
  77. }
  78. }
  79. //Handle and serve the register itnerface
  80. func (h *RegisterHandler) HandleRegisterInterface(w http.ResponseWriter, r *http.Request) {
  81. //Serve the register interface
  82. if h.AllowRegistry {
  83. template, err := ioutil.ReadFile("system/auth/register.system")
  84. if err != nil {
  85. log.Println("Template not found: system/auth/register.system")
  86. http.NotFound(w, r)
  87. return
  88. }
  89. //Load the vendor icon as base64
  90. imagecontent, _ := readImageFileAsBase64(h.options.VendorIcon)
  91. //Apply templates
  92. t := fasttemplate.New(string(template), "{{", "}}")
  93. s := t.ExecuteString(map[string]interface{}{
  94. "host_name": h.options.Hostname,
  95. "vendor_logo": imagecontent,
  96. })
  97. w.Write([]byte(s))
  98. } else {
  99. //Registry is closed
  100. http.NotFound(w, r)
  101. }
  102. }
  103. func readImageFileAsBase64(src string) (string, error) {
  104. f, err := os.Open(src)
  105. if err != nil {
  106. return "", err
  107. }
  108. reader := bufio.NewReader(f)
  109. content, err := ioutil.ReadAll(reader)
  110. if err != nil {
  111. return "", err
  112. }
  113. encoded := base64.StdEncoding.EncodeToString(content)
  114. return encoded, nil
  115. }
  116. //Get the default usergroup for this register handler
  117. func (h *RegisterHandler) GetDefaultUserGroup() string {
  118. return h.DefaultUserGroup
  119. }
  120. //Set the default usergroup for this register handler
  121. func (h *RegisterHandler) SetDefaultUserGroup(groupname string) error {
  122. if !h.permissionHandler.GroupExists(groupname) {
  123. return errors.New("Group not exists")
  124. }
  125. //Update the default registry in struct
  126. h.DefaultUserGroup = groupname
  127. //Write change to database
  128. h.database.Write("register", "defaultGroup", groupname)
  129. return nil
  130. }
  131. //Toggle registry on the fly
  132. func (h *RegisterHandler) SetAllowRegistry(allow bool) {
  133. h.AllowRegistry = allow
  134. }
  135. //Clearn Register information by removing all users info whose account is no longer registered
  136. func (h *RegisterHandler) CleanRegisters() {
  137. entries, _ := h.database.ListTable("register")
  138. for _, keypairs := range entries {
  139. if strings.Contains(string(keypairs[0]), "user/email/") {
  140. c := strings.Split(string(keypairs[0]), "/")
  141. //Get username and emails
  142. username := c[len(c)-1]
  143. if !h.authAgent.UserExists(username) {
  144. //Delete this record
  145. h.database.Delete("register", string(keypairs[0]))
  146. }
  147. }
  148. }
  149. }
  150. //List all User Emails, return [username(string), email(string), stillResitered(bool)]
  151. func (h *RegisterHandler) ListAllUserEmails() [][]interface{} {
  152. results := [][]interface{}{}
  153. entries, _ := h.database.ListTable("register")
  154. for _, keypairs := range entries {
  155. if strings.Contains(string(keypairs[0]), "user/email/") {
  156. c := strings.Split(string(keypairs[0]), "/")
  157. //Get username and emails
  158. username := c[len(c)-1]
  159. email := ""
  160. json.Unmarshal(keypairs[1], &email)
  161. //Check if the user still registered in the system
  162. userStillRegistered := h.authAgent.UserExists(username)
  163. results = append(results, []interface{}{username, email, userStillRegistered})
  164. }
  165. }
  166. return results
  167. }
  168. //Handle the request for creating a new user
  169. func (h *RegisterHandler) HandleRegisterRequest(w http.ResponseWriter, r *http.Request) {
  170. if h.AllowRegistry == false {
  171. sendErrorResponse(w, "Public account registry is currently closed")
  172. return
  173. }
  174. //Get input paramter
  175. email, err := mv(r, "email", true)
  176. if err != nil {
  177. sendErrorResponse(w, "Invalid Email")
  178. return
  179. }
  180. //Validate the email is a email
  181. if !isValidEmail(email) {
  182. sendErrorResponse(w, "Invalid or malformed email")
  183. return
  184. }
  185. username, err := mv(r, "username", true)
  186. if username == "" || strings.TrimSpace(username) == "" || err != nil {
  187. sendErrorResponse(w, "Invalid Username")
  188. return
  189. }
  190. password, err := mv(r, "password", true)
  191. if password == "" || err != nil {
  192. sendErrorResponse(w, "Invalid Password")
  193. return
  194. }
  195. //Check if password too short
  196. if len(password) < 8 {
  197. sendErrorResponse(w, "Password too short. Must be at least 8 characters.")
  198. return
  199. }
  200. //Check if the username is too short
  201. if len(username) < 2 {
  202. sendErrorResponse(w, "Username too short. Must be at least 2 characters.")
  203. return
  204. }
  205. //Check if the user already exists
  206. if h.authAgent.UserExists(username) {
  207. sendErrorResponse(w, "This username has already been used")
  208. return
  209. }
  210. //Get the default user group for public registration
  211. defaultGroup := h.DefaultUserGroup
  212. if h.permissionHandler.GroupExists(defaultGroup) == false {
  213. //Public registry user group not exists. Raise 500 Error
  214. log.Println("[CRITICAL] PUBLIC REGISTRY USER GROUP NOT FOUND! PLEASE RESTART YOUR SYSTEM!")
  215. sendErrorResponse(w, "Internal Server Error")
  216. return
  217. }
  218. //OK. Record this user to the system
  219. err = h.authAgent.CreateUserAccount(username, password, []string{defaultGroup})
  220. if err != nil {
  221. sendErrorResponse(w, err.Error())
  222. return
  223. }
  224. //Write email to database as well
  225. h.database.Write("register", "user/email/"+username, email)
  226. sendOK(w)
  227. log.Println("New User Registered: ", email, username, strings.Repeat("*", len(password)))
  228. }
  229. //Change Email for the registered user
  230. func (h *RegisterHandler) HandleEmailChange(w http.ResponseWriter, r *http.Request) {
  231. //Get input paramter
  232. email, err := mv(r, "email", true)
  233. if err != nil {
  234. sendErrorResponse(w, "Invalid Email")
  235. return
  236. }
  237. //Validate the email is a email
  238. if !isValidEmail(email) {
  239. sendErrorResponse(w, "Invalid or malformed email")
  240. return
  241. }
  242. //Get username from request
  243. username, err := h.authAgent.GetUserName(w, r)
  244. if err != nil {
  245. sendErrorResponse(w, "Unable to get username from request")
  246. return
  247. }
  248. //Write email to database as well
  249. h.database.Write("register", "user/email/"+username, email)
  250. }
  251. func isValidEmail(email string) bool {
  252. _, err := mail.ParseAddress(email)
  253. return err == nil
  254. }