implement api
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"go-nkode/hashset"
|
||||
m "go-nkode/models"
|
||||
py "go-nkode/py-builtin"
|
||||
"go-nkode/util"
|
||||
)
|
||||
|
||||
type Customer struct {
|
||||
@@ -128,16 +130,25 @@ func (c *Customer) IsValidNKode(passcodeAttrIdx []int) error {
|
||||
if !validIdx {
|
||||
return errors.New(fmt.Sprintf("One or more idx out of range 0-%d in IsValidNKode", c.Attributes.KeypadSize.TotalAttrs()-1))
|
||||
}
|
||||
passcodeSetVals := make([]uint64, nkodeLen)
|
||||
var err error
|
||||
for idx := range passcodeSetVals {
|
||||
passcodeSetVals := make(hashset.Set[uint64])
|
||||
passcodeAttrVals := make(hashset.Set[uint64])
|
||||
for idx := 0; idx < nkodeLen; idx++ {
|
||||
attrVal := c.Attributes.AttrVals[passcodeAttrIdx[idx]]
|
||||
passcodeSetVals[idx], err = c.Attributes.GetAttrSetVal(attrVal)
|
||||
setVal, err := c.Attributes.GetAttrSetVal(attrVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
passcodeSetVals.Add(setVal)
|
||||
passcodeAttrVals.Add(attrVal)
|
||||
}
|
||||
|
||||
if passcodeSetVals.Size() < c.NKodePolicy.DistinctSets {
|
||||
return errors.New(fmt.Sprintf("passcode has two few distinct sets min %d, has %d", c.NKodePolicy.DistinctSets, passcodeSetVals.Size()))
|
||||
}
|
||||
|
||||
if passcodeAttrVals.Size() < c.NKodePolicy.DistinctAttributes {
|
||||
return errors.New(fmt.Sprintf("passcode has two few distinct attributes min %d, has %d", c.NKodePolicy.DistinctAttributes, passcodeAttrVals.Size()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -154,3 +165,30 @@ func (c *Customer) GetLoginInterface(username string) ([]int, error) {
|
||||
c.Users[username] = user
|
||||
return user.Interface.IdxInterface, nil
|
||||
}
|
||||
|
||||
func (c *Customer) RenewKeys() error {
|
||||
oldAttrs := make([]uint64, c.Attributes.KeypadSize.TotalAttrs())
|
||||
oldSets := make([]uint64, c.Attributes.KeypadSize.AttrsPerKey)
|
||||
copy(oldAttrs, c.Attributes.AttrVals)
|
||||
copy(oldSets, c.Attributes.SetVals)
|
||||
|
||||
err := c.Attributes.Renew()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
attrsXor, err := util.XorLists(oldAttrs, c.Attributes.AttrVals)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
setXor, err := util.XorLists(oldSets, c.Attributes.SetVals)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
for _, user := range c.Users {
|
||||
err = user.RenewKeys(setXor, attrsXor)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -1,27 +1,11 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go-nkode/models"
|
||||
"go-nkode/util"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func SelectKeyByAttrIdx(interfaceUser []int, passcodeIdxs []int, keypadSize models.KeypadSize) ([]int, error) {
|
||||
selectedKeys := make([]int, len(passcodeIdxs))
|
||||
for idx := range passcodeIdxs {
|
||||
attrIdx := util.IndexOf[int](interfaceUser, passcodeIdxs[idx])
|
||||
keyNumb := attrIdx / keypadSize.AttrsPerKey
|
||||
if keyNumb < 0 || keyNumb >= keypadSize.NumbOfKeys {
|
||||
return nil, errors.New(fmt.Sprintf("index key number: %d out of range 0-%d", keyNumb, keypadSize.NumbOfKeys-1))
|
||||
}
|
||||
selectedKeys[idx] = keyNumb
|
||||
}
|
||||
return selectedKeys, nil
|
||||
}
|
||||
|
||||
func TestNewCustomerAttributes(t *testing.T) {
|
||||
keypad := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5}
|
||||
_, nil := NewCustomerAttributes(keypad)
|
||||
140
core/api/nkode_api.go
Normal file
140
core/api/nkode_api.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"go-nkode/models"
|
||||
)
|
||||
|
||||
type NKodeAPI struct {
|
||||
Customers map[uuid.UUID]Customer
|
||||
SignupSessions map[uuid.UUID]UserSignSession
|
||||
}
|
||||
|
||||
func NewNKodeAPI() NKodeAPI {
|
||||
return NKodeAPI{
|
||||
Customers: make(map[uuid.UUID]Customer),
|
||||
SignupSessions: make(map[uuid.UUID]UserSignSession),
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) CreateNewCustomer(keypadSize models.KeypadSize, nkodePolicy models.NKodePolicy) (*uuid.UUID, error) {
|
||||
newCustomer, err := NewCustomer(keypadSize, nkodePolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.Customers[newCustomer.CustomerId] = *newCustomer
|
||||
return &newCustomer.CustomerId, nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) GenerateSignupInterface(customerId uuid.UUID) (*uuid.UUID, []int, error) {
|
||||
customer, exists := n.Customers[customerId]
|
||||
if !exists {
|
||||
return nil, nil, errors.New(fmt.Sprintf("customer doesnt exists: %s", customerId.String()))
|
||||
}
|
||||
|
||||
signupSession, err := NewSignupSession(customer.Attributes.KeypadSize, customer.CustomerId)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
n.SignupSessions[signupSession.SessionId] = *signupSession
|
||||
return &signupSession.SessionId, signupSession.SetInterface, nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) SetNKode(username string, customerId uuid.UUID, keySelection []int, sessionId uuid.UUID) ([]int, error) {
|
||||
_, exists := n.Customers[customerId]
|
||||
if !exists {
|
||||
return nil, errors.New(fmt.Sprintf("set nkode customer id does not exist %s", customerId.String()))
|
||||
}
|
||||
|
||||
session, exists := n.SignupSessions[sessionId]
|
||||
if !exists {
|
||||
return nil, errors.New(fmt.Sprintf("session id does not exist %s", sessionId.String()))
|
||||
}
|
||||
confirmInterface, err := session.SetUserNKode(username, keySelection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.SignupSessions[sessionId] = session
|
||||
return confirmInterface, nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) ConfirmNKode(customerId uuid.UUID, keySelection []int, sessionId uuid.UUID) error {
|
||||
session, exists := n.SignupSessions[sessionId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("session id does not exist %s", sessionId.String()))
|
||||
}
|
||||
customer, exists := n.Customers[customerId]
|
||||
passcode, err := session.DeducePasscode(keySelection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = customer.IsValidNKode(passcode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = customer.AddNewUser(session.Username, passcode, session.LoginInterface)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete(n.SignupSessions, session.SessionId)
|
||||
n.Customers[customerId] = customer
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) GetLoginInterface(username string, customerId uuid.UUID) ([]int, error) {
|
||||
err := n.customerUserExists(username, customerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user := n.Customers[customerId].Users[username]
|
||||
err = user.Interface.PartialInterfaceShuffle()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.Customers[customerId].Users[username] = user
|
||||
return user.Interface.IdxInterface, nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) Login(customerId uuid.UUID, username string, keySelection []int) error {
|
||||
customer, exists := n.Customers[customerId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("customer %s does not exist", customerId.String()))
|
||||
}
|
||||
user, exists := customer.Users[username]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("user dne %s", username))
|
||||
}
|
||||
passcode, err := customer.ValidKeyEntry(username, keySelection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user.Renew {
|
||||
err = user.RefreshPasscode(passcode, customer.Attributes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) customerUserExists(username string, customerId uuid.UUID) error {
|
||||
customer, exists := n.Customers[customerId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("customer %s does not exist", customerId.String()))
|
||||
}
|
||||
_, exists = customer.Users[username]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("user dne %s", username))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) RenewAttributes(customerId uuid.UUID) error {
|
||||
customer, exists := n.Customers[customerId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("customer %s does not exist", customerId.String()))
|
||||
}
|
||||
return customer.RenewKeys()
|
||||
}
|
||||
159
core/api/nkode_api_handler.go
Normal file
159
core/api/nkode_api_handler.go
Normal file
@@ -0,0 +1,159 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"go-nkode/models"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
CreateNewCustomer = "/create-new-customer"
|
||||
GenerateSignupInterface = "/generate-signup-interface"
|
||||
SetNKode = "/set-nkode"
|
||||
ConfirmNKode = "/confirm-nkode"
|
||||
GetLoginInterface = "/get-login-interface"
|
||||
Login = "/login"
|
||||
RenewAttributes = "/renew-attributes"
|
||||
)
|
||||
|
||||
type NKodeHandler struct {
|
||||
Api NKodeAPI
|
||||
}
|
||||
|
||||
type NewCustomerPost struct {
|
||||
KeypadSize models.KeypadSize `json:"keypad_size"`
|
||||
NKodePolicy models.NKodePolicy `json:"nkode_policy"`
|
||||
}
|
||||
|
||||
type GenerateSignupInterfacePost struct {
|
||||
CustomerId uuid.UUID `json:"customer_id"`
|
||||
}
|
||||
|
||||
type SetNKodePost struct {
|
||||
Username string `json:"username"`
|
||||
CustomerId uuid.UUID `json:"customer_id"`
|
||||
KeySelection []int `json:"key_selection"`
|
||||
SessionId uuid.UUID `json:"session_id"`
|
||||
}
|
||||
|
||||
type ConfirmNKodePost struct {
|
||||
CustomerId uuid.UUID `json:"customer_id"`
|
||||
KeySelection []int `json:"key_selection"`
|
||||
SessionId uuid.UUID `json:"session_id"`
|
||||
}
|
||||
|
||||
type GetLoginInterfacePost struct {
|
||||
Username string `json:"username"`
|
||||
CustomerId uuid.UUID `json:"customer_id"`
|
||||
}
|
||||
|
||||
type LoginPost struct {
|
||||
CustomerId uuid.UUID `json:"customer_id"`
|
||||
Username string `json:"username"`
|
||||
KeySelection []int `json:"key_selection"`
|
||||
}
|
||||
|
||||
type RenewAttributesPost struct {
|
||||
CustomerId uuid.UUID `json:"customer_id"`
|
||||
}
|
||||
|
||||
func (h *NKodeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case CreateNewCustomer:
|
||||
h.CreateNewCustomerHandler(w, r)
|
||||
return
|
||||
case GenerateSignupInterface:
|
||||
h.GenerateSignupInterfaceHandler(w, r)
|
||||
case SetNKode:
|
||||
if r.Method != http.MethodPost {
|
||||
methodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
h.SetNKodeHandler(w, r)
|
||||
case ConfirmNKode:
|
||||
|
||||
if r.Method != http.MethodPost {
|
||||
methodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
case GetLoginInterface:
|
||||
if r.Method != http.MethodPost {
|
||||
methodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
|
||||
case Login:
|
||||
if r.Method != http.MethodPost {
|
||||
methodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
|
||||
case RenewAttributes:
|
||||
if r.Method != http.MethodPost {
|
||||
methodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
|
||||
default:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("404 not found"))
|
||||
}
|
||||
}
|
||||
|
||||
func internalServerErrorHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte("500 Internal Server Error"))
|
||||
}
|
||||
|
||||
func methodNotAllowed(w http.ResponseWriter) {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
w.Write([]byte("405 method not allowed"))
|
||||
}
|
||||
|
||||
func (h *NKodeHandler) CreateNewCustomerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
methodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
var customerPost NewCustomerPost
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&customerPost); err != nil {
|
||||
internalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
customerId, err := h.Api.CreateNewCustomer(customerPost.KeypadSize, customerPost.NKodePolicy)
|
||||
if err != nil {
|
||||
internalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
data := map[string]interface{}{
|
||||
"customer_id": customerId,
|
||||
}
|
||||
jsonBytes, err := json.Marshal(data)
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(jsonBytes)
|
||||
}
|
||||
|
||||
func (h *NKodeHandler) GenerateSignupInterfaceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
methodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
|
||||
var signupPost GenerateSignupInterfacePost
|
||||
if err := json.NewDecoder(r.Body).Decode(&signupPost); err != nil {
|
||||
internalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Println("Customer Id: ", signupPost.CustomerId)
|
||||
}
|
||||
|
||||
func (h *NKodeHandler) SetNKodeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
methodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
}
|
||||
48
core/api/nkode_api_test.go
Normal file
48
core/api/nkode_api_test.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go-nkode/models"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNKodeAPI(t *testing.T) {
|
||||
for idx := 0; idx < 10; idx++ {
|
||||
username := "test_username"
|
||||
passcodeLen := 4
|
||||
nkodePolicy := models.NewDefaultNKodePolicy()
|
||||
keypadSize := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3}
|
||||
nkodeApi := NewNKodeAPI()
|
||||
customerId, err := nkodeApi.CreateNewCustomer(keypadSize, nkodePolicy)
|
||||
assert.NoError(t, err)
|
||||
sessionId, setInterface, err := nkodeApi.GenerateSignupInterface(*customerId)
|
||||
assert.NoError(t, err)
|
||||
keypadSize = models.KeypadSize{AttrsPerKey: 3, NumbOfKeys: 3}
|
||||
userPasscode := setInterface[:passcodeLen]
|
||||
setKeySelect, err := SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize)
|
||||
assert.NoError(t, err)
|
||||
confirmInterface, err := nkodeApi.SetNKode(username, *customerId, setKeySelect, *sessionId)
|
||||
assert.NoError(t, err)
|
||||
confirmKeySelect, err := SelectKeyByAttrIdx(confirmInterface, userPasscode, keypadSize)
|
||||
err = nkodeApi.ConfirmNKode(*customerId, confirmKeySelect, *sessionId)
|
||||
assert.NoError(t, err)
|
||||
|
||||
keypadSize = models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3}
|
||||
loginInterface, err := nkodeApi.GetLoginInterface(username, *customerId)
|
||||
assert.NoError(t, err)
|
||||
loginKeySelection, err := SelectKeyByAttrIdx(loginInterface, userPasscode, keypadSize)
|
||||
assert.NoError(t, err)
|
||||
err = nkodeApi.Login(*customerId, username, loginKeySelection)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = nkodeApi.RenewAttributes(*customerId)
|
||||
assert.NoError(t, err)
|
||||
|
||||
loginInterface, err = nkodeApi.GetLoginInterface(username, *customerId)
|
||||
assert.NoError(t, err)
|
||||
loginKeySelection, err = SelectKeyByAttrIdx(loginInterface, userPasscode, keypadSize)
|
||||
assert.NoError(t, err)
|
||||
err = nkodeApi.Login(*customerId, username, loginKeySelection)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
}
|
||||
21
core/api/test_helper.go
Normal file
21
core/api/test_helper.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go-nkode/models"
|
||||
"go-nkode/util"
|
||||
)
|
||||
|
||||
func SelectKeyByAttrIdx(interfaceUser []int, passcodeIdxs []int, keypadSize models.KeypadSize) ([]int, error) {
|
||||
selectedKeys := make([]int, len(passcodeIdxs))
|
||||
for idx := range passcodeIdxs {
|
||||
attrIdx := util.IndexOf[int](interfaceUser, passcodeIdxs[idx])
|
||||
keyNumb := attrIdx / keypadSize.AttrsPerKey
|
||||
if keyNumb < 0 || keyNumb >= keypadSize.NumbOfKeys {
|
||||
return nil, errors.New(fmt.Sprintf("index key number: %d out of range 0-%d", keyNumb, keypadSize.NumbOfKeys-1))
|
||||
}
|
||||
selectedKeys[idx] = keyNumb
|
||||
}
|
||||
return selectedKeys, nil
|
||||
}
|
||||
46
core/api/user.go
Normal file
46
core/api/user.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
m "go-nkode/models"
|
||||
"go-nkode/util"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Username string
|
||||
EncipheredPasscode m.EncipheredNKode
|
||||
UserKeys UserCipherKeys
|
||||
Interface UserInterface
|
||||
Renew bool
|
||||
}
|
||||
|
||||
func (u *User) DecipherMask(setVals []uint64, passcodeLen int) ([]uint64, error) {
|
||||
return u.UserKeys.DecipherMask(u.EncipheredPasscode.Mask, setVals, passcodeLen)
|
||||
}
|
||||
|
||||
func (u *User) RenewKeys(setXor []uint64, attrXor []uint64) error {
|
||||
u.Renew = true
|
||||
var err error
|
||||
u.UserKeys.SetKey, err = util.XorLists(setXor, u.UserKeys.SetKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.UserKeys.AlphaKey, err = util.XorLists(attrXor, u.UserKeys.AlphaKey)
|
||||
return err
|
||||
}
|
||||
|
||||
func (u *User) RefreshPasscode(passcodeAttrIdx []int, customerAttributes CustomerAttributes) error {
|
||||
newKeys, err := NewUserCipherKeys(customerAttributes.KeypadSize, customerAttributes.SetVals, u.UserKeys.MaxNKodeLen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encipheredPasscode, err := newKeys.EncipherNKode(passcodeAttrIdx, customerAttributes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u.UserKeys = *newKeys
|
||||
u.EncipheredPasscode = *encipheredPasscode
|
||||
u.Renew = false
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
@@ -32,7 +32,7 @@ func NewUserCipherKeys(keypadSize models.KeypadSize, setVals []uint64, maxNKodeL
|
||||
return nil, err
|
||||
}
|
||||
|
||||
alphakey, _ := util.GenerateRandomNonRepeatingUint64(keypadSize.AttrsPerKey)
|
||||
alphakey, _ := util.GenerateRandomNonRepeatingUint64(keypadSize.TotalAttrs())
|
||||
passKey, _ := util.GenerateRandomNonRepeatingUint64(maxNKodeLen)
|
||||
maskKey, _ := util.GenerateRandomNonRepeatingUint64(maxNKodeLen)
|
||||
salt, _ := util.RandomBytes(10)
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -66,7 +66,7 @@ func (s *UserSignSession) DeducePasscode(confirmKeyEntry []int) ([]int, error) {
|
||||
return nil, errors.New("signup session username is nil")
|
||||
}
|
||||
|
||||
if len(confirmKeyEntry) == len(s.SetKeyEntry) {
|
||||
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)))
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
22
main.go
22
main.go
@@ -1,9 +1,23 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"go-nkode/core/api"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := 3
|
||||
b := a / 2
|
||||
fmt.Println(b)
|
||||
nkodeApi := api.NewNKodeAPI()
|
||||
handler := api.NKodeHandler{Api: nkodeApi}
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle(api.CreateNewCustomer, &handler)
|
||||
mux.Handle(api.GenerateSignupInterface, &handler)
|
||||
mux.Handle(api.SetNKode, &handler)
|
||||
mux.Handle(api.ConfirmNKode, &handler)
|
||||
mux.Handle(api.GetLoginInterface, &handler)
|
||||
mux.Handle(api.Login, &handler)
|
||||
mux.Handle(api.RenewAttributes, &handler)
|
||||
fmt.Println("Running on localhost:8080")
|
||||
log.Fatal(http.ListenAndServe("localhost:8080", mux))
|
||||
}
|
||||
|
||||
14
main_test.go
Normal file
14
main_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"go-nkode/core/api"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(t *testing.T) {
|
||||
base := "http://localhost:8080"
|
||||
|
||||
resp, err := http.Post(base+api.CreateNewCustomer, "application/json")
|
||||
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package models
|
||||
|
||||
type KeypadSize struct {
|
||||
AttrsPerKey int
|
||||
NumbOfKeys int
|
||||
AttrsPerKey int `json:"attrs_per_key"`
|
||||
NumbOfKeys int `json:"numb_of_keys"`
|
||||
}
|
||||
|
||||
func (kp *KeypadSize) TotalAttrs() int {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package models
|
||||
|
||||
type NKodePolicy struct {
|
||||
MaxNkodeLen int
|
||||
MinNkodeLen int
|
||||
DistinctSets int
|
||||
DistinctAttributes int
|
||||
LockOut int
|
||||
Expiration int // seconds, -1 no expiration
|
||||
MaxNkodeLen int `json:"max_nkode_len"`
|
||||
MinNkodeLen int `json:"min_nkode_len"`
|
||||
DistinctSets int `json:"distinct_sets"`
|
||||
DistinctAttributes int `json:"distinct_attributes"`
|
||||
LockOut int `json:"lock_out"`
|
||||
Expiration int `json:"expiration"` // seconds, -1 no expiration
|
||||
}
|
||||
|
||||
func NewDefaultNKodePolicy() NKodePolicy {
|
||||
|
||||
66
nkode_api.go
66
nkode_api.go
@@ -1,66 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"go-nkode/models"
|
||||
)
|
||||
|
||||
type NKodeAPI struct {
|
||||
Customers map[uuid.UUID]Customer
|
||||
SignupSessions map[uuid.UUID]UserSignSession
|
||||
}
|
||||
|
||||
func NewNKodeAPI() NKodeAPI {
|
||||
return NKodeAPI{
|
||||
Customers: make(map[uuid.UUID]Customer),
|
||||
SignupSessions: make(map[uuid.UUID]UserSignSession),
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) CreateNewCustomer(keypadSize models.KeypadSize, nkodePolicy models.NKodePolicy) (*uuid.UUID, error) {
|
||||
newCustomer, err := NewCustomer(keypadSize, nkodePolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.Customers[newCustomer.CustomerId] = *newCustomer
|
||||
return &newCustomer.CustomerId, nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) GenerateSignupInterface(customerId uuid.UUID) (*uuid.UUID, []int, error) {
|
||||
customer, exists := n.Customers[customerId]
|
||||
if !exists {
|
||||
return nil, nil, errors.New(fmt.Sprintf("customer doesnt exists: %s", customerId.String()))
|
||||
}
|
||||
|
||||
signupSession, err := NewSignupSession(customer.Attributes.KeypadSize, customer.CustomerId)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
n.SignupSessions[signupSession.SessionId] = *signupSession
|
||||
return &signupSession.SessionId, signupSession.SetInterface, nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) SetNKode(username string, customerId uuid.UUID, keySelection []int, sessionId uuid.UUID) ([]int, error) {
|
||||
customer, exists := n.Customers[customerId]
|
||||
if !exists {
|
||||
return nil, errors.New(fmt.Sprintf("set nkode customer id does not exist %s", customerId.String()))
|
||||
}
|
||||
_, exists = customer.Users[username]
|
||||
if exists {
|
||||
return nil, errors.New(fmt.Sprintf("user already exists %s", username))
|
||||
}
|
||||
|
||||
session, exists := n.SignupSessions[sessionId]
|
||||
if !exists {
|
||||
return nil, errors.New(fmt.Sprintf("session id does not exist %s", sessionId.String()))
|
||||
}
|
||||
confirmInterface, err := session.SetUserNKode(username, keySelection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return confirmInterface, nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) ConfirmNKode(username string, customerId uuid.UUID, confirmKeyEntry []int)
|
||||
17
user.go
17
user.go
@@ -1,17 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
m "go-nkode/models"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Username string
|
||||
EncipheredPasscode m.EncipheredNKode
|
||||
UserKeys UserCipherKeys
|
||||
Interface UserInterface
|
||||
Renew bool
|
||||
}
|
||||
|
||||
func (u *User) DecipherMask(setVals []uint64, passcodeLen int) ([]uint64, error) {
|
||||
return u.UserKeys.DecipherMask(u.EncipheredPasscode.Mask, setVals, passcodeLen)
|
||||
}
|
||||
Reference in New Issue
Block a user