Add bump with ip
This commit is contained in:
parent
7d96d46ac8
commit
1a31bb6b30
131
main.go
131
main.go
|
@ -2,19 +2,19 @@ package scsusers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"encoding/base32"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
"crypto/rand"
|
|
||||||
"encoding/json"
|
|
||||||
"encoding/base32"
|
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
|
||||||
|
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
type templates struct {
|
type templates struct {
|
||||||
Registration *template.Template
|
Registration *template.Template
|
||||||
|
@ -44,7 +44,7 @@ func Init(dbin *sqlx.DB, tp, sitename, fromaddr, smtpserver string) {
|
||||||
c.TablePrefix = tp
|
c.TablePrefix = tp
|
||||||
c.SiteName = sitename
|
c.SiteName = sitename
|
||||||
c.FromEmail = fromaddr
|
c.FromEmail = fromaddr
|
||||||
c.SMTPServer=smtpserver
|
c.SMTPServer = smtpserver
|
||||||
|
|
||||||
SetRegistrationTemplate("")
|
SetRegistrationTemplate("")
|
||||||
SetAlertTemplate("")
|
SetAlertTemplate("")
|
||||||
|
@ -52,7 +52,7 @@ func Init(dbin *sqlx.DB, tp, sitename, fromaddr, smtpserver string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UsernameAvailable(username string) bool {
|
func UsernameAvailable(username string) bool {
|
||||||
if len(username)==0 {
|
if len(username) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
var u string
|
var u string
|
||||||
|
@ -91,8 +91,8 @@ func Register(username, email, ip string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
log.Printf("scsusers.Register: Failed to send registration email, deleting user %s\n", username)
|
log.Printf("scsusers.Register: Failed to send registration email, deleting user %s\n", username)
|
||||||
q=fmt.Sprintf("delete from %s_auth where username ILIKE $1 AND password=$2", c.TablePrefix)
|
q = fmt.Sprintf("delete from %s_auth where username ILIKE $1 AND password=$2", c.TablePrefix)
|
||||||
_,err = c.db.Exec(q, username, string(crypt))
|
_, err = c.db.Exec(q, username, string(crypt))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.Register: Failed to delete new user %s: %s\n", username, err.Error())
|
log.Printf("scsusers.Register: Failed to delete new user %s: %s\n", username, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -100,9 +100,9 @@ func Register(username, email, ip string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Login(username, password string) bool {
|
func Login(username, password string) bool {
|
||||||
q:=fmt.Sprintf("select password from %s_auth where username ILIKE $1 AND status='active'",c.TablePrefix)
|
q := fmt.Sprintf("select password from %s_auth where username ILIKE $1 AND status='active'", c.TablePrefix)
|
||||||
var crypt string
|
var crypt string
|
||||||
err:=c.db.Get(&crypt, q, username)
|
err := c.db.Get(&crypt, q, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.Login: Failed login attempt for unknown username: %s\n", username)
|
log.Printf("scsusers.Login: Failed login attempt for unknown username: %s\n", username)
|
||||||
return false
|
return false
|
||||||
|
@ -117,9 +117,9 @@ func Login(username, password string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChangePassword(username, oldpass, newpass string) bool {
|
func ChangePassword(username, oldpass, newpass string) bool {
|
||||||
q:=fmt.Sprintf("select password from %s_auth where username ILIKE $1 AND status='active'",c.TablePrefix)
|
q := fmt.Sprintf("select password from %s_auth where username ILIKE $1 AND status='active'", c.TablePrefix)
|
||||||
var crypt string
|
var crypt string
|
||||||
err:=c.db.Get(&crypt, q, username)
|
err := c.db.Get(&crypt, q, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("scsusers.ChangePassword: Failed change attempt for unknown username: " + username)
|
log.Println("scsusers.ChangePassword: Failed change attempt for unknown username: " + username)
|
||||||
return false
|
return false
|
||||||
|
@ -129,9 +129,9 @@ func ChangePassword(username, oldpass, newpass string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
newcrypt, err := bcrypt.GenerateFromPassword([]byte(newpass), 10)
|
newcrypt, err := bcrypt.GenerateFromPassword([]byte(newpass), 10)
|
||||||
q=fmt.Sprintf("update %s_auth set password=$2 where username ILIKE $1", c.TablePrefix)
|
q = fmt.Sprintf("update %s_auth set password=$2 where username ILIKE $1", c.TablePrefix)
|
||||||
_,err=c.db.Exec(q, username, newcrypt)
|
_, err = c.db.Exec(q, username, newcrypt)
|
||||||
if err!= nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.ChangePassword: update failed for %s: %s\n", username, err.Error())
|
log.Printf("scsusers.ChangePassword: update failed for %s: %s\n", username, err.Error())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -142,8 +142,8 @@ func ChangePassword(username, oldpass, newpass string) bool {
|
||||||
|
|
||||||
func GetUserid(username string) int64 {
|
func GetUserid(username string) int64 {
|
||||||
var i int64
|
var i int64
|
||||||
q:=fmt.Sprintf("select userid from %s_auth where username ILIKE $1", c.TablePrefix)
|
q := fmt.Sprintf("select userid from %s_auth where username ILIKE $1", c.TablePrefix)
|
||||||
err:=c.db.Get(&i, q, username)
|
err := c.db.Get(&i, q, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.getUserId: Error loading user: %s : %s\n", username, err.Error())
|
log.Printf("scsusers.getUserId: Error loading user: %s : %s\n", username, err.Error())
|
||||||
return 0
|
return 0
|
||||||
|
@ -152,28 +152,28 @@ func GetUserid(username string) int64 {
|
||||||
}
|
}
|
||||||
func LoadUser(username string) (UserData, error) {
|
func LoadUser(username string) (UserData, error) {
|
||||||
var u UserData
|
var u UserData
|
||||||
q:=fmt.Sprintf("select data from %s_userdata where username ILIKE $1", c.TablePrefix)
|
q := fmt.Sprintf("select data from %s_userdata where username ILIKE $1", c.TablePrefix)
|
||||||
var d string
|
var d string
|
||||||
err:=c.db.Get(d, q, username)
|
err := c.db.Get(d, q, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.LoadUser: Error loading user: %s : %s\n", username, err.Error())
|
log.Printf("scsusers.LoadUser: Error loading user: %s : %s\n", username, err.Error())
|
||||||
return u, err
|
return u, err
|
||||||
}
|
}
|
||||||
err=json.Unmarshal([]byte(d), &u)
|
err = json.Unmarshal([]byte(d), &u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.LoadUser: Error decoding json on user %s. Unmarshal returned %s\n", username, err.Error())
|
log.Printf("scsusers.LoadUser: Error decoding json on user %s. Unmarshal returned %s\n", username, err.Error())
|
||||||
}
|
}
|
||||||
return u,err
|
return u, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveUser(username string, d UserData) bool {
|
func SaveUser(username string, d UserData) bool {
|
||||||
q:=fmt.Sprintf("update %s_userdata set data=$1 where username ILIKE $2")
|
q := fmt.Sprintf("update %s_userdata set data=$1 where username ILIKE $2")
|
||||||
j, err:=json.Marshal(d)
|
j, err := json.Marshal(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.SaveUser: json.Marshal failed for username %s : %s\n", username, err.Error())
|
log.Printf("scsusers.SaveUser: json.Marshal failed for username %s : %s\n", username, err.Error())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
_, err=c.db.Exec(q, username, j)
|
_, err = c.db.Exec(q, username, j)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.SaveUser: db.Exec failed for username %s : %s\n", username, err.Error())
|
log.Printf("scsusers.SaveUser: db.Exec failed for username %s : %s\n", username, err.Error())
|
||||||
return false
|
return false
|
||||||
|
@ -182,9 +182,9 @@ func SaveUser(username string, d UserData) bool {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Bump(username string) {
|
func Bump(username string, ip string) {
|
||||||
q:=fmt.Sprintf("update %s_auth set lastseen=CURRENT_TIMESTAMP where username ILIKE $1", c.TablePrefix)
|
q := fmt.Sprintf("update %s_auth set lastseen=CURRENT_TIMESTAMP, set lastseenip=$2 where username ILIKE $1", c.TablePrefix)
|
||||||
_, err :=c.db.Exec(q, username)
|
_, err := c.db.Exec(q, username, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.Bump: Error on user bump: %s : %s\n", username, err.Error())
|
log.Printf("scsusers.Bump: Error on user bump: %s : %s\n", username, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -195,41 +195,41 @@ type Metadata struct {
|
||||||
MetaValue string `db:meta_value`
|
MetaValue string `db:meta_value`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllMeta(username string) (map[string]string) {
|
func GetAllMeta(username string) map[string]string {
|
||||||
meta:=make(map[string]string)
|
meta := make(map[string]string)
|
||||||
q:=fmt.Sprintf(`select meta_key, meta_value
|
q := fmt.Sprintf(`select meta_key, meta_value
|
||||||
from %s_user_metadata where
|
from %s_user_metadata where
|
||||||
user_id=(select userid from %s_auth where username ILIKE $1)`,
|
user_id=(select userid from %s_auth where username ILIKE $1)`,
|
||||||
c.TablePrefix, c.TablePrefix)
|
c.TablePrefix, c.TablePrefix)
|
||||||
rows,err:=c.db.Queryx(q, username)
|
rows, err := c.db.Queryx(q, username)
|
||||||
if err != nil && err!=sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
log.Printf("scsusers.GetAllMeta: %s: %s\n", username, err.Error())
|
log.Printf("scsusers.GetAllMeta: %s: %s\n", username, err.Error())
|
||||||
return meta
|
return meta
|
||||||
}
|
}
|
||||||
var m Metadata
|
var m Metadata
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
err=rows.StructScan(&m)
|
err = rows.StructScan(&m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.GetAllMeta: StructScan: %s\n", username, err.Error())
|
log.Printf("scsusers.GetAllMeta: StructScan: %s\n", username, err.Error())
|
||||||
return meta
|
return meta
|
||||||
}
|
}
|
||||||
meta[m.MetaKey]=m.MetaValue
|
meta[m.MetaKey] = m.MetaValue
|
||||||
}
|
}
|
||||||
return meta
|
return meta
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMeta(username string, metakey string) string {
|
func GetMeta(username string, metakey string) string {
|
||||||
var v string
|
var v string
|
||||||
q:=fmt.Sprintf(`select meta_value from %s_user_metadata where
|
q := fmt.Sprintf(`select meta_value from %s_user_metadata where
|
||||||
user_id=(select userid from %s_auth where username ILIKE $1) AND meta_key=$2`, c.TablePrefix, c.TablePrefix)
|
user_id=(select userid from %s_auth where username ILIKE $1) AND meta_key=$2`, c.TablePrefix, c.TablePrefix)
|
||||||
err:=c.db.Get(&v, q, username, metakey)
|
err := c.db.Get(&v, q, username, metakey)
|
||||||
if err != nil && err!=sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
log.Printf("scsusers.GetMeta: %s - %s - %s\n", username, metakey, err.Error())
|
log.Printf("scsusers.GetMeta: %s - %s - %s\n", username, metakey, err.Error())
|
||||||
}
|
}
|
||||||
if v=="" {
|
if v == "" {
|
||||||
// get default user
|
// get default user
|
||||||
err:=c.db.Get(&v, q, "//default//", metakey)
|
err := c.db.Get(&v, q, "//default//", metakey)
|
||||||
if err != nil && err!=sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
log.Printf("scsusers.GetMeta: %s - %s - %s\n", username, metakey, err.Error())
|
log.Printf("scsusers.GetMeta: %s - %s - %s\n", username, metakey, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,31 +239,30 @@ func GetMeta(username string, metakey string) string {
|
||||||
|
|
||||||
func SetMeta(username string, metakey string, metavalue string) {
|
func SetMeta(username string, metakey string, metavalue string) {
|
||||||
var err error
|
var err error
|
||||||
if metavalue=="" {
|
if metavalue == "" {
|
||||||
q:=fmt.Sprintf(`delete from %s_user_metadata where user_id=(select userid from %s_auth where username ILIKE $1) AND meta_key=$2`,
|
q := fmt.Sprintf(`delete from %s_user_metadata where user_id=(select userid from %s_auth where username ILIKE $1) AND meta_key=$2`,
|
||||||
c.TablePrefix, c.TablePrefix)
|
c.TablePrefix, c.TablePrefix)
|
||||||
_, err=c.db.Exec(q, username, metakey)
|
_, err = c.db.Exec(q, username, metakey)
|
||||||
} else {
|
} else {
|
||||||
q:=fmt.Sprintf(`insert into %s_user_metadata (user_id, meta_key, meta_value) VALUES
|
q := fmt.Sprintf(`insert into %s_user_metadata (user_id, meta_key, meta_value) VALUES
|
||||||
((select userid from %s_auth where username ILIKE $1), $2, $3)`, c.TablePrefix, c.TablePrefix)
|
((select userid from %s_auth where username ILIKE $1), $2, $3)`, c.TablePrefix, c.TablePrefix)
|
||||||
_,err=c.db.Exec(q, username, metakey, metavalue)
|
_, err = c.db.Exec(q, username, metakey, metavalue)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("scsusers.SetMeta: %s %s %s %s\n", username, metakey, metavalue, err.Error())
|
log.Printf("scsusers.SetMeta: %s %s %s %s\n", username, metakey, metavalue, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func RecoverByUsername(u string) {
|
func RecoverByUsername(u string) {
|
||||||
var username, email string
|
var username, email string
|
||||||
q:=fmt.Sprintf("select username, email from %s_auth where username ILIKE $1", c.TablePrefix)
|
q := fmt.Sprintf("select username, email from %s_auth where username ILIKE $1", c.TablePrefix)
|
||||||
row:=c.db.QueryRow(q, u)
|
row := c.db.QueryRow(q, u)
|
||||||
err:=row.Scan(&username, &email)
|
err := row.Scan(&username, &email)
|
||||||
if err!=sql.ErrNoRows {
|
if err != sql.ErrNoRows {
|
||||||
recoverycode:=randBytes(16)
|
recoverycode := randBytes(16)
|
||||||
qq:=fmt.Sprintf("update %s_auth set recoverycode=$1, recoverytime=NOW() where username ILIKE $2", c.TablePrefix)
|
qq := fmt.Sprintf("update %s_auth set recoverycode=$1, recoverytime=NOW() where username ILIKE $2", c.TablePrefix)
|
||||||
_,err:=c.db.Exec(qq, recoverycode, username)
|
_, err := c.db.Exec(qq, recoverycode, username)
|
||||||
if err==nil {
|
if err == nil {
|
||||||
sendRecoveryEmail(email, username, string(recoverycode))
|
sendRecoveryEmail(email, username, string(recoverycode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,20 +270,19 @@ func RecoverByUsername(u string) {
|
||||||
|
|
||||||
func RecoverByEmail(e string) {
|
func RecoverByEmail(e string) {
|
||||||
var username, email string
|
var username, email string
|
||||||
q:=fmt.Sprintf("select username, email from %s_auth where email=$1", c.TablePrefix)
|
q := fmt.Sprintf("select username, email from %s_auth where email=$1", c.TablePrefix)
|
||||||
row:=c.db.QueryRow(q, e)
|
row := c.db.QueryRow(q, e)
|
||||||
err:=row.Scan(&username, &email)
|
err := row.Scan(&username, &email)
|
||||||
if err!=sql.ErrNoRows {
|
if err != sql.ErrNoRows {
|
||||||
recoverycode:=randBytes(16)
|
recoverycode := randBytes(16)
|
||||||
qq:=fmt.Sprintf("update %s_auth set recoverycode=$1, recoverytime=NOW() where username ILIKE $2", c.TablePrefix)
|
qq := fmt.Sprintf("update %s_auth set recoverycode=$1, recoverytime=NOW() where username ILIKE $2", c.TablePrefix)
|
||||||
_,err:=c.db.Exec(qq, recoverycode, username)
|
_, err := c.db.Exec(qq, recoverycode, username)
|
||||||
if err==nil {
|
if err == nil {
|
||||||
sendRecoveryEmail(email, username, string(recoverycode))
|
sendRecoveryEmail(email, username, string(recoverycode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func randBytes(n int) []byte {
|
func randBytes(n int) []byte {
|
||||||
randomBytes := make([]byte, 32)
|
randomBytes := make([]byte, 32)
|
||||||
_, err := rand.Read(randomBytes)
|
_, err := rand.Read(randomBytes)
|
||||||
|
@ -321,7 +319,6 @@ func sendRegistrationEmail(recipient, username, password string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func sendAlertEmail(username, recipient, message string) bool {
|
func sendAlertEmail(username, recipient, message string) bool {
|
||||||
data := struct {
|
data := struct {
|
||||||
SiteName string
|
SiteName string
|
||||||
|
@ -377,7 +374,6 @@ func sendRecoveryEmail(recipient, username, code string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func SetRegistrationTemplate(t string) bool {
|
func SetRegistrationTemplate(t string) bool {
|
||||||
if len(t) != 0 {
|
if len(t) != 0 {
|
||||||
r, err := template.New("reg").Parse(t)
|
r, err := template.New("reg").Parse(t)
|
||||||
|
@ -414,7 +410,6 @@ func SetAlertTemplate(t string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func SetRecoveryTemplate(t string) bool {
|
func SetRecoveryTemplate(t string) bool {
|
||||||
if len(t) != 0 {
|
if len(t) != 0 {
|
||||||
r, err := template.New("recovery").Parse(t)
|
r, err := template.New("recovery").Parse(t)
|
||||||
|
|
Loading…
Reference in New Issue