diff --git a/pages/signup.go b/pages/signup.go index 1da9f5e..0bf21a1 100644 --- a/pages/signup.go +++ b/pages/signup.go @@ -14,40 +14,54 @@ import ( log "github.com/sirupsen/logrus" ) -// SignupPage is the signup page handler +type formValues struct { + Username string + Email string + SshPublicKey string + IPAddress string + CaptchaResponse string +} +type CaptchaResponse struct { + Success bool `json:"success"` +} + +// SignupPage is the signup page handler func SignupPage(c *fiber.Ctx) error { SignupIP, SignupIPExists := os.LookupEnv("PUBLAPI_SIGNUP_IP") - if SignupIPExists == true { + if SignupIPExists { if c.IP() != SignupIP { log.Info("Request made from invalid IP: ", c.IP()) return c.SendStatus(fiber.StatusForbidden) } } - username := c.FormValue("username") - email := c.FormValue("email") - ssh := c.FormValue("ssh") - ip := c.FormValue("ip") - captchaResp := c.FormValue("h-captcha-response") - if captchaResp == "" { + formValues := formValues{ + Username: c.FormValue("username"), + Email: c.FormValue("email"), + SshPublicKey: c.FormValue("ssh"), + IPAddress: c.FormValue("ip"), + CaptchaResponse: c.FormValue("h-captcha-response"), + } + + if formValues.CaptchaResponse == "" { log.Error("Nice try, but the registration won't work unless you answer the captcha.") return c.SendStatus(fiber.StatusBadRequest) } - if username == "" || email == "" || ssh == "" || ip == "" { - log.Error("username, email, ssh and ip must be filled", username, email, ssh, ip) + if formValues.Username == "" || formValues.Email == "" || formValues.SshPublicKey == "" || formValues.IPAddress == "" { + log.Error("username, email, ssh and ip must be filled", formValues.Username, formValues.Email, formValues.SshPublicKey, formValues.IPAddress) return c.SendStatus(fiber.StatusBadRequest) } raid, ok := os.LookupEnv("PUBLAPI_RAID_MODE") if !ok || raid == "1" { log.Warn( "PUBLAPI_RAID_MODE is on, accepting every request as OK and not doing anything...\n User info: ", - username, + formValues.Username, " ", - email, + formValues.Email, " ", - ip, + formValues.IPAddress, " ", ) return c.SendStatus(fiber.StatusOK) @@ -55,10 +69,10 @@ func SignupPage(c *fiber.Ctx) error { // Check the captcha validation. - captchaSecret, ok := os.LookupEnv("PUBLAPI_CAPTCHA_SECRET") + captchaSecret, _ := os.LookupEnv("PUBLAPI_CAPTCHA_SECRET") params := url.Values{} - params.Add("response", captchaResp) + params.Add("response", formValues.CaptchaResponse) params.Add("secret", captchaSecret) body := strings.NewReader(params.Encode()) @@ -82,30 +96,27 @@ func SignupPage(c *fiber.Ctx) error { sb := string(bod) log.Info("Captcha response: ", sb) - type CaptchaResponse struct { - Success bool `json:"success"` - } - var captchaResponse CaptchaResponse + captchaResponse := CaptchaResponse{} err = json.Unmarshal([]byte(sb), &captchaResponse) if err != nil { log.Error("Error unmarshalling captcha response", err) } - if captchaResponse.Success == false { + if !captchaResponse.Success { log.Error("Captcha validation failed") return c.JSON(fiber.Map{ - "username": username, - "message": "Sorry! But the captcha validation failed. Please try again.", + "username": formValues.CaptchaResponse, + "message": "Sorry, but the captcha validation failed. Please try again.", "status": c.Response().StatusCode(), }) } else { // Check if user already exists // We'll check the home folder and see if the username folder exists. - _, err := os.Stat("/home/" + username) + _, err := os.Stat("/home/" + formValues.Username) if err == nil { - log.Error("User already exists : ", username) + log.Error("User already exists : ", formValues.Username) return c.JSON(fiber.Map{ - "username": username, + "username": formValues.Username, "message": "User already exists. Please choose a different username.", "status": c.Response().StatusCode(), }) @@ -113,28 +124,28 @@ func SignupPage(c *fiber.Ctx) error { // create user file - f, err := os.Create("/var/publapi/users/" + username + ".sh") + f, err := os.Create("/var/publapi/users/" + formValues.Username + ".sh") if err != nil { log.Error("Error creating user file", err) return c.SendStatus(fiber.StatusInternalServerError) } defer f.Close() - chmoderr := os.Chmod("/var/publapi/users/"+username+".sh", 0700) + chmoderr := os.Chmod("/var/publapi/users/"+formValues.Username+".sh", 0700) if chmoderr != nil { log.Error(err) } - Bashscript := strings.ReplaceAll(utils.Bashscript, "{{sshkey}}", ssh) - Bashscript = strings.ReplaceAll(Bashscript, "{{email}}", email) - Bashscript = strings.ReplaceAll(Bashscript, "{{username}}", username) + bashScript := strings.ReplaceAll(utils.BashScript, "{{sshkey}}", formValues.SshPublicKey) + bashScript = strings.ReplaceAll(bashScript, "{{email}}", formValues.Email) + bashScript = strings.ReplaceAll(bashScript, "{{username}}", formValues.Username) // write to file - _, err = f.WriteString(Bashscript) + _, err = f.WriteString(bashScript) if err != nil { log.Error("Error writing to user file", err) return c.SendStatus(fiber.StatusInternalServerError) } log.Info( - "Registration request for " + username + " has been submitted by the frontend and has been written to /var/publapi/users/" + username + ".sh", + "Registration request for " + formValues.Username + " has been submitted by the frontend and has been written to /var/publapi/users/" + formValues.Username + ".sh", ) // send notification to user that their reg request was sent @@ -150,14 +161,14 @@ func SignupPage(c *fiber.Ctx) error { shoutrrrUrl := os.Getenv("PUBLAPI_NOTIFY_SHOUTRRRURL") + os.Getenv("PUBLAPI_NOTIFY_ROOMS") err = shoutrrr.Send( shoutrrrUrl, - "New user signup! Please review /var/publapi/users/"+username+".sh to approve or deny the user. IP: "+ip+" Email: "+email, + "New user signup! Please review /var/publapi/users/"+formValues.Username+".sh to approve or deny the user. IP: "+formValues.IPAddress+" Email: "+formValues.Email, ) if err != nil { log.Error("Error sending notification to admins", err) //return c.SendStatus(fiber.StatusInternalServerError) } return c.JSON(fiber.Map{ - "username": username, + "username": formValues.Username, "message": "User created! Please allow us 24 hours or more to review your account.", "status": c.Response().StatusCode(), }) diff --git a/pages/users.go b/pages/users.go index 5d85abc..53d4446 100644 --- a/pages/users.go +++ b/pages/users.go @@ -16,14 +16,14 @@ import ( "github.com/spf13/viper" ) -type Userstruct struct { +type UserStruct struct { Status int `json:"status"` Online int `json:"online"` Total int `json:"total"` - Users []Userinfo `json:"users"` + Users []UserInfo `json:"users"` } -type Userinfo struct { +type UserInfo struct { Name string `json:"name"` FullName string `json:"fullName"` Desc string `json:"desc"` @@ -38,7 +38,7 @@ type Userinfo struct { Loc string `json:"loc"` } -type ByAdminAndName []Userinfo +type ByAdminAndName []UserInfo func (a ByAdminAndName) Len() int { return len(a) } func (a ByAdminAndName) Less(i, j int) bool { @@ -58,7 +58,7 @@ func UserError(message string, username string, err error) { log.Error("error", message, log.Any("err", err), "username", username) } -func userdata(username, usersonline, ops string) Userinfo { +func userData(username, usersonline, ops string) UserInfo { regex := "(^| )" + username + "($| )" isonline, err := regexp.MatchString(string(regex), string(usersonline)) if err != nil { @@ -80,7 +80,7 @@ func userdata(username, usersonline, ops string) Userinfo { if error != nil { if os.IsNotExist(error) { log.Error(username + " does not have a meta-info.toml") - var user Userinfo + var user UserInfo user.Name = username user.Created, _ = strconv.Atoi(crdstr) if isonline { @@ -99,7 +99,7 @@ func userdata(username, usersonline, ops string) Userinfo { viper.SetConfigFile(filename) if err := viper.ReadInConfig(); err != nil { log.Error("message", "Couldn't read a users meta-info.toml file.", "error", log.Any("err", err), "user", username) - user := Userinfo{ + user := UserInfo{ Name: username, } user.Created, _ = strconv.Atoi(crdstr) @@ -115,27 +115,25 @@ func userdata(username, usersonline, ops string) Userinfo { } return user } - var user Userinfo - user = Userinfo{} - user.Name = username + user := UserInfo{ + Name: username, + FullName: viper.GetString("fullname"), + Capsule: viper.GetString("gemini"), + Website: viper.GetString("website"), + Desc: viper.GetString("description"), + Email: viper.GetString("email"), + Matrix: viper.GetString("matrix"), + Fediverse: viper.GetString("fediverse"), + Loc: viper.GetString("location"), + Op: false, + Online: false, + } user.Created, _ = strconv.Atoi(crdstr) - user.FullName = viper.GetString("fullname") - user.Capsule = viper.GetString("gemini") - user.Website = viper.GetString("website") - user.Desc = viper.GetString("description") - user.Email = viper.GetString("email") - user.Matrix = viper.GetString("matrix") - user.Fediverse = viper.GetString("fediverse") - user.Loc = viper.GetString("location") if isop { user.Op = true - } else { - user.Op = false } if isonline { user.Online = true - } else { - user.Online = false } return user } @@ -148,18 +146,18 @@ func UsersPage(c *fiber.Ctx) error { }) } // Get the number of users online - usersonline, err := exec.Command("bash", "-c", "/usr/bin/users").Output() + usersOnline, err := exec.Command("bash", "-c", "/usr/bin/users").Output() if err != nil { log.Error("error", log.Any("error", err)) return c.SendStatus(fiber.StatusInternalServerError) } - usersonlinestr := string(usersonline) - usersonlinededup := utils.Dedup(usersonlinestr) + usersOnlineStr := string(usersOnline) + usersOnlineDedup := utils.Dedup(usersOnlineStr) var output int - if strings.Contains(usersonlinededup, " ") { - outputa := int(strings.Count(usersonlinededup, " ")) + if strings.Contains(usersOnlineDedup, " ") { + outputa := int(strings.Count(usersOnlineDedup, " ")) output = outputa + 1 - } else if usersonlinededup == "" { + } else if usersOnlineDedup == "" { output = 0 } else { output = 1 @@ -181,23 +179,23 @@ func UsersPage(c *fiber.Ctx) error { userstr2 := strings.TrimSuffix(userstr, "\n") usersarr := strings.Split(userstr2, "\n") // Fill user info - var userinfostruct []Userinfo + var userInfoStruct []UserInfo for i := 0; i < len(usersarr); i++ { uname := string(usersarr[i]) - userinfostruct = append( - userinfostruct, - userdata( + userInfoStruct = append( + userInfoStruct, + userData( uname, - strings.TrimSuffix(usersonlinededup, "\n"), + strings.TrimSuffix(usersOnlineDedup, "\n"), strings.TrimSuffix(opstr, "\n"), ), ) } - sort.Sort(ByAdminAndName(userinfostruct)) - data := Userstruct{ + sort.Sort(ByAdminAndName(userInfoStruct)) + data := UserStruct{ Status: c.Response().StatusCode(), Online: output, - Users: userinfostruct, + Users: userInfoStruct, Total: int(strings.Count(userstr, "\n")), } return c.JSON(data) diff --git a/utils/main.go b/utils/main.go index 588be9a..2b75b00 100644 --- a/utils/main.go +++ b/utils/main.go @@ -6,7 +6,7 @@ import ( ) //go:embed signup-script-template -var Bashscript string +var BashScript string func Dedup(input string) string { unique := []string{}