user signup sessions

This commit is contained in:
2024-08-19 19:13:17 -05:00
parent 8673eb9869
commit 603936b50c
8 changed files with 381 additions and 30 deletions

164
user_signup_session.go Normal file
View File

@@ -0,0 +1,164 @@
package main
import (
"errors"
"fmt"
"github.com/google/uuid"
"go-nkode/hashset"
"go-nkode/models"
py_builtin "go-nkode/py-builtin"
"go-nkode/util"
)
type UserSignSession struct {
SessionId uuid.UUID
CustomerId uuid.UUID
LoginInterface UserInterface
KeypadSize models.KeypadSize
SetInterface []int
ConfirmInterface []int
SetKeyEntry []int
Username string
}
func NewSignupSession(keypadSize models.KeypadSize, customerId uuid.UUID) (*UserSignSession, error) {
loginInterface, err := NewUserInterface(keypadSize)
if err != nil {
return nil, err
}
signupInter, err := signupInterface(*loginInterface)
session := UserSignSession{
SessionId: uuid.New(),
CustomerId: customerId,
LoginInterface: *loginInterface,
SetInterface: signupInter.IdxInterface,
ConfirmInterface: nil,
SetKeyEntry: nil,
Username: "",
KeypadSize: signupInter.KeypadSize,
}
return &session, nil
}
func (s *UserSignSession) DeducePasscode(confirmKeyEntry []int) ([]int, error) {
validEntry := py_builtin.All[int](confirmKeyEntry, func(i int) bool {
return 0 <= i && i < s.LoginInterface.KeypadSize.NumbOfKeys
})
if !validEntry {
return nil, errors.New(fmt.Sprintf("Invalid Key entry. One or more key index: %#v, not in range 0-%d", confirmKeyEntry, s.LoginInterface.KeypadSize.NumbOfKeys))
}
if s.SetInterface == nil {
return nil, errors.New("signup session set interface is nil")
}
if s.ConfirmInterface == nil {
return nil, errors.New("signup session confirm interface is nil")
}
if s.SetKeyEntry == nil {
return nil, errors.New("signup session set key entry is nil")
}
if s.Username == "" {
return nil, errors.New("signup session username is nil")
}
if len(confirmKeyEntry) == len(s.SetKeyEntry) {
return nil, errors.New(fmt.Sprintf("confirm and set key entry lenght mismatch %d != %d", len(confirmKeyEntry), len(s.SetKeyEntry)))
}
passcodeLen := len(confirmKeyEntry)
setKeyVals, err := s.getSelectedKeyVals(s.SetKeyEntry, s.SetInterface)
if err != nil {
return nil, err
}
confirmKeyVals, err := s.getSelectedKeyVals(confirmKeyEntry, s.ConfirmInterface)
passcode := make([]int, passcodeLen)
for idx := 0; idx < passcodeLen; idx++ {
setKey := hashset.NewSetFromSlice[int](setKeyVals[idx])
confirmKey := hashset.NewSetFromSlice[int](confirmKeyVals[idx])
intersection := setKey.Intersect(confirmKey)
if intersection.Size() < 1 {
return nil, errors.New(fmt.Sprintf("set and confirm do not intersect at index %d", idx))
}
if intersection.Size() > 1 {
return nil, errors.New(fmt.Sprintf("set and confirm intersect at more than one point at index %d", idx))
}
intersectionSlice := intersection.ToSlice()
passcode[idx] = intersectionSlice[0]
}
return passcode, nil
}
func (s *UserSignSession) SetUserNKode(username string, keySelection []int) ([]int, error) {
validKeySelection := py_builtin.All[int](keySelection, func(i int) bool {
return 0 <= i && i < s.KeypadSize.NumbOfKeys
})
if !validKeySelection {
return nil, errors.New(fmt.Sprintf("one or key selection is out of range 0-%d", s.KeypadSize.NumbOfKeys-1))
}
s.SetKeyEntry = keySelection
s.Username = username
setInterface := UserInterface{IdxInterface: s.SetInterface, KeypadSize: s.KeypadSize}
err := setInterface.DisperseInterface()
if err != nil {
return nil, err
}
s.ConfirmInterface = setInterface.IdxInterface
return s.ConfirmInterface, nil
}
func (s *UserSignSession) getSelectedKeyVals(keySelections []int, userInterface []int) ([][]int, error) {
keypadInterface, err := util.ListToMatrix(userInterface, s.KeypadSize.AttrsPerKey)
if err != nil {
return nil, err
}
keyVals := make([][]int, len(keySelections))
for idx, keyIdx := range keySelections {
keyVals[idx] = keypadInterface[keyIdx]
}
return keyVals, nil
}
func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) {
if baseUserInterface.KeypadSize.IsDispersable() {
return nil, errors.New("keypad is dispersable, can't use signupInterface")
}
err := baseUserInterface.RandomShuffle()
if err != nil {
return nil, err
}
interfaceMatrix, err := baseUserInterface.InterfaceMatrix()
if err != nil {
return nil, err
}
attrSetView, err := util.MatrixTranspose(interfaceMatrix)
if err != nil {
return nil, err
}
err = util.FisherYatesShuffle[[]int](&attrSetView)
if err != nil {
return nil, err
}
numbOfKeys := baseUserInterface.KeypadSize.NumbOfKeys
attrSetView = attrSetView[:numbOfKeys]
attrSetView, err = util.MatrixTranspose(attrSetView)
if err != nil {
return nil, err
}
signupUserInterface := UserInterface{
IdxInterface: util.MatrixToList(attrSetView),
KeypadSize: models.KeypadSize{
AttrsPerKey: numbOfKeys,
NumbOfKeys: numbOfKeys,
},
}
return &signupUserInterface, nil
}