diff --git a/main.go b/main.go new file mode 100644 index 0000000..de8d81d --- /dev/null +++ b/main.go @@ -0,0 +1,201 @@ +package scsusers + +import ( + "bytes" + "database/sql" + "fmt" + "github.com/jmoiron/sqlx" + "golang.org/x/crypto/bcrypt" + "html/template" + "log" + "math/rand" + "net/smtp" + "strings" +) + +type templates struct { + Registration *template.Template + Alert *template.Template + Recovery *template.Template +} + +type config struct { + SiteName string + FromEmail string + Templates templates + db *sqlx.DB + TablePrefix string +} + +var c config + +func Init(dbin *sqlx.DB, tp, sitename, fromaddr string) { + c.db = dbin + c.TablePrefix = tp + c.SiteName = sitename + c.FromEmail = fromaddr + + SetRegistrationTemplate("") + SetAlertTemplate("") + SetRecoveryTemplate("") + +} + +func UsernameAvailable(username string) bool { + + q := fmt.Sprintf("select username from %s_auth where username=$1", c.TablePrefix) + err := c.db.Get(q, username) + if err == sql.ErrNoRows { + return true + } + return false +} + +/* Check for username availability, add to database, send email */ + +func Register(username, email, ip string) bool { + if !UsernameAvailable(username) { + return false + } + pass := randBytes(16) + crypt, err := bcrypt.GenerateFromPassword(pass, 20) + if err != nil { + log.Printf("Bcrypt GenerateFromPassword failed? Pass is %s and error is %s\n", pass, err.Error()) + return false + } + q := fmt.Sprintf("insert into %s_auth (username, email, password, registration_date, registration_ip) values ($1, $2, $3, NOW(), $4)", c.TablePrefix) + _, err = c.db.Exec(q, username, email, crypt, ip) + if err != nil { + return false + } + + return true +} + +func randBytes(n int) []byte { + const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return b +} + +func sendRegistrationEmail(recipient, username, password string) bool { + data := struct { + SiteName string + FromEmail string + UserName string + Pass string + }{ + SiteName: c.SiteName, + FromEmail: c.FromEmail, + UserName: username, + Pass: password, + } + var body bytes.Buffer + err := c.Templates.Registration.Execute(&body, data) + if err != nil { + log.Printf("Registration template failed to execute: %v returned %s\n", data, err.Error()) + return false + } + subject := fmt.Sprintf("Welcome to %s", c.SiteName) + err = SendMail("localhost:25", c.FromEmail, subject, body.String(), recipient) + if err != nil { + log.Printf("Error sending mail to %s: %s\n", recipient, err.Error()) + return false + } + return true +} + +func SetRegistrationTemplate(t string) bool { + if len(t) != 0 { + r, err := template.New("reg").Parse(t) + if err != nil { + c.Templates.Registration = r + return true + } + } + df := `
Hello {{.UserName}}! Welcome to {{.SiteName}}! We've created your account with the username you selected and the following password: {{.Pass}}
You can change your password to whatever you want once you log in.