sophuwu.site > goauth   
              79
            
             package goauth

import (
	"crypto/rand"
	"crypto/sha256"
	"crypto/subtle"
	"fmt"
	"github.com/pquerna/otp/totp"
	"os"
	"time"
)

// User struct for storing user data
type User struct {
	Name string
	Hash []byte
	Salt []byte
	OtpS string
}

func salt(n int) []byte {
	var s = make([]byte, n)
	_, err := rand.Read(s)
	if err != nil {
		panic(err)
	}
	return s
}
func hash(b ...[]byte) []byte {
	h := sha256.New()
	for _, v := range b {
		h.Write(v)
	}
	return h.Sum(nil)
}

func (u *User) SetPass(pass string) {
	u.Salt = salt(16)
	u.Hash = hash([]byte(pass), u.Salt)
}

func (u *User) CheckPass(pass string) bool {
	return subtle.ConstantTimeCompare(u.Hash, hash([]byte(pass), u.Salt)) == 1
}

// NewUser creates a new user
func NewUser(name, pass string) (User, error) {
	var u User
	u.Name = name
	u.SetPass(pass)
	otp, e := totp.Generate(totp.GenerateOpts{Issuer: "soph.local", AccountName: u.Name})
	if e != nil {
		return u, e
	}
	u.OtpS = otp.Secret()
	q, e := GenQR(otp.URL(),
		"One Time Password:",
		"  User  : "+u.Name,
		"  Issuer: "+"local",
		"  Secret: "+otp.Secret(),
		"  Period: "+fmt.Sprint(time.Duration(otp.Period()*10e8).String()),
		"  Digits: "+fmt.Sprintf("%d", otp.Digits()),
		"  Algo  : "+fmt.Sprintf("%s", otp.Algorithm()),
		"Scan the QR code with your authenticator app.",
	)
	if e != nil {
		return u, e
	}
	fmt.Println(q.String())
	os.WriteFile(u.Name+".png", q.Png(), 0644)
	return u, nil
}

// CheckPassword checks if the password is correct
func CheckPassword(name, pass string) bool {
	return false
}

// subtle.ConstantTimeCompare([]byte(expectedPass), []byte(pass)) == 1