131 lines
2.4 KiB
Go
131 lines
2.4 KiB
Go
package storage
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.zomo.dev/zomo/discord-retokenizer/util"
|
|
"github.com/go-redis/redis/v9"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
func UpdateUsername(username string) {
|
|
if username != "" {
|
|
client.Set(ctx, "username", username, 0)
|
|
}
|
|
}
|
|
|
|
func UpdatePassword(password string) {
|
|
if password != "" {
|
|
passHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
client.Set(ctx, "password", string(passHash), 0)
|
|
}
|
|
}
|
|
|
|
func CheckLogin(username string, password string, ip string) (bool, string) {
|
|
if username == "" || password == "" {
|
|
return false, ""
|
|
}
|
|
|
|
user, err := client.Get(ctx, "username").Result()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
pass, err := client.Get(ctx, "password").Result()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(user, username)
|
|
|
|
if user != username {
|
|
return false, ""
|
|
}
|
|
|
|
err = bcrypt.CompareHashAndPassword([]byte(pass), []byte(password))
|
|
if err != nil {
|
|
return false, ""
|
|
}
|
|
|
|
return true, createLoginToken(ip)
|
|
}
|
|
|
|
type LoginToken struct {
|
|
Token string `json:"token"`
|
|
IP string `json:"ip"`
|
|
End string `json:"end"`
|
|
}
|
|
|
|
func (t LoginToken) MarshalBinary() ([]byte, error) {
|
|
return json.Marshal(t)
|
|
}
|
|
|
|
func (t *LoginToken) UnmarshalBinary(data []byte) error {
|
|
return json.Unmarshal(data, t)
|
|
}
|
|
|
|
func createLoginToken(ip string) string {
|
|
token := util.GeneratePassword(32)
|
|
|
|
tokenHash, err := bcrypt.GenerateFromPassword([]byte(token), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
tokenData := LoginToken{
|
|
Token: string(tokenHash),
|
|
IP: ip,
|
|
End: token[len(token) - 4:],
|
|
}
|
|
|
|
member := redis.Z{
|
|
Score: float64(time.Now().Unix() + 4 * 60 * 60),
|
|
Member: tokenData,
|
|
}
|
|
|
|
err = client.ZAdd(ctx, "loginTokens", member).Err()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return token
|
|
}
|
|
|
|
func CheckLoginToken(token string, ip string) bool {
|
|
|
|
expired, err := client.ZRangeByScore(ctx, "loginTokens", &redis.ZRangeBy{
|
|
Min: "-inf",
|
|
Max: fmt.Sprintf("%d", time.Now().Unix()),
|
|
}).Result()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
for _, e := range expired {
|
|
client.ZRem(ctx, "loginTokens", e)
|
|
}
|
|
|
|
var current []LoginToken
|
|
err = client.ZRange(ctx, "loginTokens", 0, -1).ScanSlice(¤t)
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("%v\n", current)
|
|
|
|
for _, c := range current {
|
|
err = bcrypt.CompareHashAndPassword([]byte(c.Token), []byte(token))
|
|
if err == nil && ip == c.IP {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
} |