diff --git a/core/api/nkode_handler.go b/core/api/nkode_handler.go index 1278dff..e448121 100644 --- a/core/api/nkode_handler.go +++ b/core/api/nkode_handler.go @@ -2,21 +2,19 @@ package api import ( "encoding/json" - "go-nkode/core/model" - "go-nkode/core/nkode" + m "go-nkode/core/model" "log" "net/http" ) type NKodeHandler struct { - Api nkode.NKodeAPI + Api m.NKodeAPIInterface } 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: @@ -31,8 +29,8 @@ func (h *NKodeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.RenewAttributesHandler(w, r) default: w.WriteHeader(http.StatusNotFound) - w.Write([]byte("404 not found")) - log.Fatal(r.URL.Path, " not found") + _, err := w.Write([]byte("404 not found")) + log.Println(err) } } @@ -41,31 +39,31 @@ func (h *NKodeHandler) CreateNewCustomerHandler(w http.ResponseWriter, r *http.R methodNotAllowed(w) return } - var customerPost model.NewCustomerPost + var customerPost m.NewCustomerPost err := decodeJson(w, r, &customerPost) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } customerId, err := h.Api.CreateNewCustomer(customerPost.KeypadSize, customerPost.NKodePolicy) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } - respBody := model.CreateNewCustomerResp{ + respBody := m.CreateNewCustomerResp{ CustomerId: *customerId, } respBytes, err := json.Marshal(respBody) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } _, err = w.Write(respBytes) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } @@ -79,33 +77,29 @@ func (h *NKodeHandler) GenerateSignupInterfaceHandler(w http.ResponseWriter, r * return } - var signupPost model.GenerateSignupInterfacePost + var signupPost m.GenerateSignupInterfacePost err := decodeJson(w, r, &signupPost) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } - sessionId, userInterface, err := h.Api.GenerateSignupInterface(signupPost.CustomerId) + resp, err := h.Api.GenerateSignupInterface(signupPost.CustomerId) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } - respBody := model.GenerateSignupInterfaceResp{ - SessionId: *sessionId, - UserInterface: userInterface, - } - respBytes, err := json.Marshal(respBody) + respBytes, err := json.Marshal(resp) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } _, err = w.Write(respBytes) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } @@ -118,31 +112,31 @@ func (h *NKodeHandler) SetNKodeHandler(w http.ResponseWriter, r *http.Request) { methodNotAllowed(w) return } - var setNKodePost model.SetNKodePost + var setNKodePost m.SetNKodePost err := decodeJson(w, r, &setNKodePost) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } - confirmInterface, err := h.Api.SetNKode(setNKodePost.Username, setNKodePost.CustomerId, setNKodePost.KeySelection, setNKodePost.SessionId) + confirmInterface, err := h.Api.SetNKode(setNKodePost.Username, setNKodePost.CustomerId, setNKodePost.SessionId, setNKodePost.KeySelection) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } - respBody := model.SetNKodeResp{UserInterface: confirmInterface} + respBody := m.SetNKodeResp{UserInterface: confirmInterface} respBytes, err := json.Marshal(respBody) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } _, err = w.Write(respBytes) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } @@ -156,16 +150,16 @@ func (h *NKodeHandler) ConfirmNKodeHandler(w http.ResponseWriter, r *http.Reques return } - var confirmNKodePost model.ConfirmNKodePost + var confirmNKodePost m.ConfirmNKodePost err := decodeJson(w, r, &confirmNKodePost) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } - err = h.Api.ConfirmNKode(confirmNKodePost.CustomerId, confirmNKodePost.KeySelection, confirmNKodePost.SessionId) + err = h.Api.ConfirmNKode(confirmNKodePost.CustomerId, confirmNKodePost.SessionId, confirmNKodePost.KeySelection) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } @@ -179,30 +173,30 @@ func (h *NKodeHandler) GetLoginInterfaceHandler(w http.ResponseWriter, r *http.R methodNotAllowed(w) return } - var loginInterfacePost model.GetLoginInterfacePost + var loginInterfacePost m.GetLoginInterfacePost err := decodeJson(w, r, &loginInterfacePost) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } loginInterface, err := h.Api.GetLoginInterface(loginInterfacePost.Username, loginInterfacePost.CustomerId) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } - respBody := model.GetLoginInterfaceResp{UserInterface: loginInterface} + respBody := m.GetLoginInterfaceResp{UserInterface: loginInterface} respBytes, err := json.Marshal(respBody) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } _, err = w.Write(respBytes) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } @@ -216,16 +210,16 @@ func (h *NKodeHandler) LoginHandler(w http.ResponseWriter, r *http.Request) { methodNotAllowed(w) return } - var loginPost model.LoginPost + var loginPost m.LoginPost err := decodeJson(w, r, &loginPost) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } err = h.Api.Login(loginPost.CustomerId, loginPost.Username, loginPost.KeySelection) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } @@ -238,18 +232,18 @@ func (h *NKodeHandler) RenewAttributesHandler(w http.ResponseWriter, r *http.Req methodNotAllowed(w) return } - var renewAttributesPost model.RenewAttributesPost + var renewAttributesPost m.RenewAttributesPost err := decodeJson(w, r, &renewAttributesPost) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } err = h.Api.RenewAttributes(renewAttributesPost.CustomerId) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) log.Fatal(err) return } @@ -260,14 +254,14 @@ func (h *NKodeHandler) RenewAttributesHandler(w http.ResponseWriter, r *http.Req func decodeJson(w http.ResponseWriter, r *http.Request, post any) error { err := json.NewDecoder(r.Body).Decode(&post) if err != nil { - internalServerErrorHandler(w, r) + internalServerErrorHandler(w) return err } return nil } -func internalServerErrorHandler(w http.ResponseWriter, r *http.Request) { +func internalServerErrorHandler(w http.ResponseWriter) { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("500 Internal Server Error")) } diff --git a/core/model/keypad_size.go b/core/model/keypad_size.go index 44eec43..3c8a47c 100644 --- a/core/model/keypad_size.go +++ b/core/model/keypad_size.go @@ -1,4 +1,4 @@ -package model +package m type KeypadSize struct { AttrsPerKey int `json:"attrs_per_key"` diff --git a/core/model/nkode_policy.go b/core/model/nkode_policy.go index 31690fd..9e03b0d 100644 --- a/core/model/nkode_policy.go +++ b/core/model/nkode_policy.go @@ -1,4 +1,4 @@ -package model +package m type NKodePolicy struct { MaxNkodeLen int `json:"max_nkode_len"` diff --git a/core/model/type.go b/core/model/type.go index d2fea45..e0faecf 100644 --- a/core/model/type.go +++ b/core/model/type.go @@ -1,6 +1,8 @@ -package model +package m -import "github.com/google/uuid" +import ( + "github.com/google/uuid" +) type SetNKodeResp struct { UserInterface []int `json:"user_interface"` @@ -12,52 +14,62 @@ type NewCustomerPost struct { } type GenerateSignupInterfacePost struct { - CustomerId uuid.UUID `json:"customer_id"` + CustomerId CustomerId `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"` + Username Username `json:"username"` + CustomerId CustomerId `json:"customer_id"` + KeySelection KeySelection `json:"key_selection"` + SessionId SessionId `json:"session_id"` } type ConfirmNKodePost struct { - CustomerId uuid.UUID `json:"customer_id"` - KeySelection []int `json:"key_selection"` - SessionId uuid.UUID `json:"session_id"` + CustomerId CustomerId `json:"customer_id"` + KeySelection KeySelection `json:"key_selection"` + SessionId SessionId `json:"session_id"` } type GetLoginInterfacePost struct { - Username string `json:"username"` - CustomerId uuid.UUID `json:"customer_id"` + Username Username `json:"username"` + CustomerId CustomerId `json:"customer_id"` } type LoginPost struct { - CustomerId uuid.UUID `json:"customer_id"` - Username string `json:"username"` - KeySelection []int `json:"key_selection"` + CustomerId CustomerId `json:"customer_id"` + Username Username `json:"username"` + KeySelection KeySelection `json:"key_selection"` } type RenewAttributesPost struct { - CustomerId uuid.UUID `json:"customer_id"` + CustomerId CustomerId `json:"customer_id"` } type CreateNewCustomerResp struct { - CustomerId uuid.UUID `json:"customer_id"` + CustomerId CustomerId `json:"customer_id"` } type GenerateSignupInterfaceResp struct { - SessionId uuid.UUID `json:"session_id"` - UserInterface []int `json:"user_interface"` + SessionId SessionId `json:"session_id"` + UserInterface IdxInterface `json:"user_interface"` } type GetLoginInterfaceResp struct { - UserInterface []int `json:"user_interface"` + UserInterface IdxInterface `json:"user_interface"` } type KeySelection []int type CustomerId uuid.UUID type SessionId uuid.UUID type Username string -type UserInterface []int +type IdxInterface []int + +type NKodeAPIInterface interface { + CreateNewCustomer(KeypadSize, NKodePolicy) (*CustomerId, error) + GenerateSignupInterface(CustomerId) (*GenerateSignupInterfaceResp, error) + SetNKode(Username, CustomerId, SessionId, KeySelection) (IdxInterface, error) + ConfirmNKode(CustomerId, SessionId, KeySelection) error + GetLoginInterface(username Username, customerId CustomerId) (IdxInterface, error) + Login(customerId CustomerId, username Username, keySelection KeySelection) error + RenewAttributes(customerId CustomerId) error +} diff --git a/core/nkode/customer.go b/core/nkode/customer.go index a66c0e6..5774f18 100644 --- a/core/nkode/customer.go +++ b/core/nkode/customer.go @@ -4,20 +4,20 @@ import ( "errors" "fmt" "github.com/google/uuid" - "go-nkode/core/model" + m "go-nkode/core/model" "go-nkode/hashset" py "go-nkode/py-builtin" "go-nkode/util" ) type Customer struct { - CustomerId uuid.UUID - NKodePolicy model.NKodePolicy + CustomerId m.CustomerId + NKodePolicy m.NKodePolicy Attributes CustomerAttributes - Users map[string]User + Users map[m.Username]User } -func NewCustomer(keypadSize model.KeypadSize, nkodePolicy model.NKodePolicy) (*Customer, error) { +func NewCustomer(keypadSize m.KeypadSize, nkodePolicy m.NKodePolicy) (*Customer, error) { if keypadSize.TotalAttrs() < nkodePolicy.DistinctAttributes { return nil, errors.New(fmt.Sprintf("incompadible nkode policy and keypad size TotalAttrs: %d < DistinctAttributes: %d", keypadSize.TotalAttrs(), nkodePolicy.DistinctAttributes)) } @@ -30,19 +30,19 @@ func NewCustomer(keypadSize model.KeypadSize, nkodePolicy model.NKodePolicy) (*C return nil, err } customer := Customer{ - CustomerId: uuid.New(), + CustomerId: m.CustomerId(uuid.New()), NKodePolicy: nkodePolicy, Attributes: *customerAttrs, - Users: make(map[string]User), + Users: make(map[m.Username]User), } return &customer, nil } -func (c *Customer) AddNewUser(username string, passcodeIdx []int, userInterface UserInterface) error { +func (c *Customer) AddNewUser(username m.Username, passcodeIdx []int, userInterface UserInterface) error { _, exists := c.Users[username] if exists { - return errors.New(fmt.Sprintf("User %s already exists for customer %s exists", username, c.CustomerId.String())) + return errors.New(fmt.Sprintf("User %s already exists for customer %+v exists", username, c.CustomerId)) } newKeys, err := NewUserCipherKeys(c.Attributes.KeypadSize, c.Attributes.SetVals, c.NKodePolicy.MaxNkodeLen) if err != nil { @@ -62,10 +62,10 @@ func (c *Customer) AddNewUser(username string, passcodeIdx []int, userInterface return nil } -func (c *Customer) ValidKeyEntry(username string, selectedKeys []int) ([]int, error) { +func (c *Customer) ValidKeyEntry(username m.Username, selectedKeys []int) ([]int, error) { user, exists := c.Users[username] if !exists { - return nil, errors.New(fmt.Sprintf("user %s does not exist for customer %s", username, c.CustomerId.String())) + return nil, errors.New(fmt.Sprintf("user %s does not exist for customer %+v", username, c.CustomerId)) } validKeys := py.All[int](selectedKeys, func(idx int) bool { @@ -152,10 +152,10 @@ func (c *Customer) IsValidNKode(passcodeAttrIdx []int) error { return nil } -func (c *Customer) GetLoginInterface(username string) ([]int, error) { +func (c *Customer) GetLoginInterface(username m.Username) ([]int, error) { user, exists := c.Users[username] if !exists { - return nil, errors.New(fmt.Sprintf("can't get login interface for non-existant user %s in customer %s", username, c.CustomerId.String())) + return nil, errors.New(fmt.Sprintf("can't get login interface for non-existant user %s in customer %s", username, c.CustomerId)) } err := user.Interface.PartialInterfaceShuffle() diff --git a/core/nkode/customer_attributes.go b/core/nkode/customer_attributes.go index 05fa477..5219f7a 100644 --- a/core/nkode/customer_attributes.go +++ b/core/nkode/customer_attributes.go @@ -11,10 +11,10 @@ import ( type CustomerAttributes struct { AttrVals []uint64 SetVals []uint64 - KeypadSize model.KeypadSize + KeypadSize m.KeypadSize } -func NewCustomerAttributes(keypadSize model.KeypadSize) (*CustomerAttributes, error) { +func NewCustomerAttributes(keypadSize m.KeypadSize) (*CustomerAttributes, error) { if keypadSize.IsDispersable() { return nil, errors.New("number of keys must be less than the number of attributes per key to be dispersion resistant") } diff --git a/core/nkode/customer_test.go b/core/nkode/customer_test.go index fe63079..cf76cc7 100644 --- a/core/nkode/customer_test.go +++ b/core/nkode/customer_test.go @@ -2,24 +2,30 @@ package nkode import ( "github.com/stretchr/testify/assert" - model2 "go-nkode/core/model" + m "go-nkode/core/model" "testing" ) -func TestNewCustomerAttributes(t *testing.T) { - keypad := model2.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} +func TestCustomer(t *testing.T) { + testNewCustomerAttributes(t) + testCustomerValidKeyEntry(t) + testCustomerIsValidNKode(t) +} + +func testNewCustomerAttributes(t *testing.T) { + keypad := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} _, nil := NewCustomerAttributes(keypad) assert.NoError(t, nil) } -func TestCustomer_ValidKeyEntry(t *testing.T) { - keypadSize := model2.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} - nkodePolicy := model2.NewDefaultNKodePolicy() +func testCustomerValidKeyEntry(t *testing.T) { + keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} + nkodePolicy := m.NewDefaultNKodePolicy() customer, err := NewCustomer(keypadSize, nkodePolicy) assert.NoError(t, err) newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) assert.NoError(t, err) - username := "testing123" + username := m.Username("testing123") passcodeIdx := []int{0, 1, 2, 3} err = customer.AddNewUser(username, passcodeIdx, *newUserInterface) assert.NoError(t, err) @@ -35,14 +41,14 @@ func TestCustomer_ValidKeyEntry(t *testing.T) { } } -func TestCustomer_IsValidNKode(t *testing.T) { - keypadSize := model2.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} - nkodePolicy := model2.NewDefaultNKodePolicy() +func testCustomerIsValidNKode(t *testing.T) { + keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} + nkodePolicy := m.NewDefaultNKodePolicy() customer, err := NewCustomer(keypadSize, nkodePolicy) assert.NoError(t, err) newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) assert.NoError(t, err) - username := "testing123" + username := m.Username("testing123") passcodeIdx := []int{0, 1, 2, 3} err = customer.AddNewUser(username, passcodeIdx, *newUserInterface) assert.NoError(t, err) diff --git a/core/nkode/nkode_api.go b/core/nkode/nkode_in_memory.go similarity index 62% rename from core/nkode/nkode_api.go rename to core/nkode/nkode_in_memory.go index e7287e3..f3a4317 100644 --- a/core/nkode/nkode_api.go +++ b/core/nkode/nkode_in_memory.go @@ -3,23 +3,22 @@ package nkode import ( "errors" "fmt" - "github.com/google/uuid" - "go-nkode/core/model" + m "go-nkode/core/model" ) -type NKodeAPI struct { - Customers map[uuid.UUID]Customer - SignupSessions map[uuid.UUID]UserSignSession +type NKodeInMemory struct { + Customers map[m.CustomerId]Customer + SignupSessions map[m.SessionId]UserSignSession } -func NewNKodeAPI() NKodeAPI { - return NKodeAPI{ - Customers: make(map[uuid.UUID]Customer), - SignupSessions: make(map[uuid.UUID]UserSignSession), +func NewNKodeInMemory() NKodeInMemory { + return NKodeInMemory{ + Customers: make(map[m.CustomerId]Customer), + SignupSessions: make(map[m.SessionId]UserSignSession), } } -func (n *NKodeAPI) CreateNewCustomer(keypadSize model.KeypadSize, nkodePolicy model.NKodePolicy) (*uuid.UUID, error) { +func (n *NKodeInMemory) CreateNewCustomer(keypadSize m.KeypadSize, nkodePolicy m.NKodePolicy) (*m.CustomerId, error) { newCustomer, err := NewCustomer(keypadSize, nkodePolicy) if err != nil { return nil, err @@ -28,29 +27,33 @@ func (n *NKodeAPI) CreateNewCustomer(keypadSize model.KeypadSize, nkodePolicy mo return &newCustomer.CustomerId, nil } -func (n *NKodeAPI) GenerateSignupInterface(customerId uuid.UUID) (*uuid.UUID, []int, error) { +func (n *NKodeInMemory) GenerateSignupInterface(customerId m.CustomerId) (*m.GenerateSignupInterfaceResp, error) { customer, exists := n.Customers[customerId] if !exists { - return nil, nil, errors.New(fmt.Sprintf("customer doesnt exists: %s", customerId.String())) + return nil, errors.New(fmt.Sprintf("customer doesnt exists: %s", customerId)) } signupSession, err := NewSignupSession(customer.Attributes.KeypadSize, customer.CustomerId) if err != nil { - return nil, nil, err + return nil, err } n.SignupSessions[signupSession.SessionId] = *signupSession - return &signupSession.SessionId, signupSession.SetInterface, nil + resp := m.GenerateSignupInterfaceResp{ + UserInterface: signupSession.SetIdxInterface, + SessionId: signupSession.SessionId, + } + return &resp, nil } -func (n *NKodeAPI) SetNKode(username string, customerId uuid.UUID, keySelection []int, sessionId uuid.UUID) ([]int, error) { +func (n *NKodeInMemory) SetNKode(username m.Username, customerId m.CustomerId, sessionId m.SessionId, keySelection m.KeySelection) (m.IdxInterface, error) { _, exists := n.Customers[customerId] if !exists { - return nil, errors.New(fmt.Sprintf("set nkode customer id does not exist %s", customerId.String())) + return nil, errors.New(fmt.Sprintf("set nkode customer id does not exist %s", customerId)) } session, exists := n.SignupSessions[sessionId] if !exists { - return nil, errors.New(fmt.Sprintf("session id does not exist %s", sessionId.String())) + return nil, errors.New(fmt.Sprintf("session id does not exist %s", sessionId)) } confirmInterface, err := session.SetUserNKode(username, keySelection) if err != nil { @@ -60,10 +63,10 @@ func (n *NKodeAPI) SetNKode(username string, customerId uuid.UUID, keySelection return confirmInterface, nil } -func (n *NKodeAPI) ConfirmNKode(customerId uuid.UUID, keySelection []int, sessionId uuid.UUID) error { +func (n *NKodeInMemory) ConfirmNKode(customerId m.CustomerId, sessionId m.SessionId, keySelection m.KeySelection) error { session, exists := n.SignupSessions[sessionId] if !exists { - return errors.New(fmt.Sprintf("session id does not exist %s", sessionId.String())) + return errors.New(fmt.Sprintf("session id does not exist %s", sessionId)) } customer, exists := n.Customers[customerId] passcode, err := session.DeducePasscode(keySelection) @@ -74,7 +77,7 @@ func (n *NKodeAPI) ConfirmNKode(customerId uuid.UUID, keySelection []int, sessio if err != nil { return err } - err = customer.AddNewUser(session.Username, passcode, session.LoginInterface) + err = customer.AddNewUser(session.Username, passcode, session.LoginUserInterface) if err != nil { return err } @@ -83,7 +86,7 @@ func (n *NKodeAPI) ConfirmNKode(customerId uuid.UUID, keySelection []int, sessio return nil } -func (n *NKodeAPI) GetLoginInterface(username string, customerId uuid.UUID) ([]int, error) { +func (n *NKodeInMemory) GetLoginInterface(username m.Username, customerId m.CustomerId) (m.IdxInterface, error) { err := n.customerUserExists(username, customerId) if err != nil { return nil, err @@ -97,10 +100,10 @@ func (n *NKodeAPI) GetLoginInterface(username string, customerId uuid.UUID) ([]i return user.Interface.IdxInterface, nil } -func (n *NKodeAPI) Login(customerId uuid.UUID, username string, keySelection []int) error { +func (n *NKodeInMemory) Login(customerId m.CustomerId, username m.Username, keySelection m.KeySelection) error { customer, exists := n.Customers[customerId] if !exists { - return errors.New(fmt.Sprintf("customer %s does not exist", customerId.String())) + return errors.New(fmt.Sprintf("customer %s does not exist", customerId)) } user, exists := customer.Users[username] if !exists { @@ -119,10 +122,10 @@ func (n *NKodeAPI) Login(customerId uuid.UUID, username string, keySelection []i return nil } -func (n *NKodeAPI) customerUserExists(username string, customerId uuid.UUID) error { +func (n *NKodeInMemory) customerUserExists(username m.Username, customerId m.CustomerId) error { customer, exists := n.Customers[customerId] if !exists { - return errors.New(fmt.Sprintf("customer %s does not exist", customerId.String())) + return errors.New(fmt.Sprintf("customer %s does not exist", customerId)) } _, exists = customer.Users[username] if !exists { @@ -131,10 +134,10 @@ func (n *NKodeAPI) customerUserExists(username string, customerId uuid.UUID) err return nil } -func (n *NKodeAPI) RenewAttributes(customerId uuid.UUID) error { +func (n *NKodeInMemory) RenewAttributes(customerId m.CustomerId) error { customer, exists := n.Customers[customerId] if !exists { - return errors.New(fmt.Sprintf("customer %s does not exist", customerId.String())) + return errors.New(fmt.Sprintf("customer %s does not exist", customerId)) } return customer.RenewKeys() } diff --git a/core/nkode/nkode_api_test.go b/core/nkode/nkode_in_memory_test.go similarity index 69% rename from core/nkode/nkode_api_test.go rename to core/nkode/nkode_in_memory_test.go index 7f5f679..49d3bf2 100644 --- a/core/nkode/nkode_api_test.go +++ b/core/nkode/nkode_in_memory_test.go @@ -2,32 +2,34 @@ package nkode import ( "github.com/stretchr/testify/assert" - "go-nkode/core/model" + m "go-nkode/core/model" "testing" ) func TestNKodeAPI(t *testing.T) { for idx := 0; idx < 10; idx++ { - username := "test_username" + username := m.Username("test_username") passcodeLen := 4 - nkodePolicy := model.NewDefaultNKodePolicy() - keypadSize := model.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} - nkodeApi := NewNKodeAPI() + nkodePolicy := m.NewDefaultNKodePolicy() + keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} + nkodeApi := NewNKodeInMemory() customerId, err := nkodeApi.CreateNewCustomer(keypadSize, nkodePolicy) assert.NoError(t, err) - sessionId, setInterface, err := nkodeApi.GenerateSignupInterface(*customerId) + signupResponse, err := nkodeApi.GenerateSignupInterface(*customerId) assert.NoError(t, err) - keypadSize = model.KeypadSize{AttrsPerKey: 3, NumbOfKeys: 3} + setInterface := signupResponse.UserInterface + sessionId := signupResponse.SessionId + keypadSize = m.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) + confirmInterface, err := nkodeApi.SetNKode(username, *customerId, sessionId, setKeySelect) assert.NoError(t, err) confirmKeySelect, err := SelectKeyByAttrIdx(confirmInterface, userPasscode, keypadSize) - err = nkodeApi.ConfirmNKode(*customerId, confirmKeySelect, *sessionId) + err = nkodeApi.ConfirmNKode(*customerId, sessionId, confirmKeySelect) assert.NoError(t, err) - keypadSize = model.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} + keypadSize = m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} loginInterface, err := nkodeApi.GetLoginInterface(username, *customerId) assert.NoError(t, err) loginKeySelection, err := SelectKeyByAttrIdx(loginInterface, userPasscode, keypadSize) diff --git a/core/nkode/nkode_sqlite.go b/core/nkode/nkode_sqlite.go new file mode 100644 index 0000000..324c377 --- /dev/null +++ b/core/nkode/nkode_sqlite.go @@ -0,0 +1 @@ +package nkode diff --git a/core/nkode/test_helper.go b/core/nkode/test_helper.go index 2b76b15..689e1e1 100644 --- a/core/nkode/test_helper.go +++ b/core/nkode/test_helper.go @@ -3,11 +3,11 @@ package nkode import ( "errors" "fmt" - "go-nkode/core/model" + m "go-nkode/core/model" "go-nkode/util" ) -func SelectKeyByAttrIdx(interfaceUser []int, passcodeIdxs []int, keypadSize model.KeypadSize) ([]int, error) { +func SelectKeyByAttrIdx(interfaceUser []int, passcodeIdxs []int, keypadSize m.KeypadSize) ([]int, error) { selectedKeys := make([]int, len(passcodeIdxs)) for idx := range passcodeIdxs { attrIdx := util.IndexOf[int](interfaceUser, passcodeIdxs[idx]) diff --git a/core/nkode/user.go b/core/nkode/user.go index cf7bafd..a860915 100644 --- a/core/nkode/user.go +++ b/core/nkode/user.go @@ -6,7 +6,7 @@ import ( ) type User struct { - Username string + Username m.Username EncipheredPasscode m.EncipheredNKode UserKeys UserCipherKeys Interface UserInterface diff --git a/core/nkode/user_cipher_keys.go b/core/nkode/user_cipher_keys.go index ca3d35d..6494cd7 100644 --- a/core/nkode/user_cipher_keys.go +++ b/core/nkode/user_cipher_keys.go @@ -4,7 +4,7 @@ import ( "crypto/sha256" "errors" "fmt" - "go-nkode/core/model" + m "go-nkode/core/model" "go-nkode/util" "golang.org/x/crypto/bcrypt" ) @@ -18,7 +18,7 @@ type UserCipherKeys struct { MaxNKodeLen int } -func NewUserCipherKeys(keypadSize model.KeypadSize, setVals []uint64, maxNKodeLen int) (*UserCipherKeys, error) { +func NewUserCipherKeys(keypadSize m.KeypadSize, setVals []uint64, maxNKodeLen int) (*UserCipherKeys, error) { if len(setVals) != keypadSize.AttrsPerKey { return nil, errors.New(fmt.Sprintf("setVals len != attrsPerKey, %d, %d", len(setVals), keypadSize.AttrsPerKey)) } @@ -165,7 +165,7 @@ func (u *UserCipherKeys) DecipherMask(mask string, setVals []uint64, passcodeLen return passcodeSet, nil } -func (u *UserCipherKeys) EncipherNKode(passcodeAttrIdx []int, customerAttrs CustomerAttributes) (*model.EncipheredNKode, error) { +func (u *UserCipherKeys) EncipherNKode(passcodeAttrIdx []int, customerAttrs CustomerAttributes) (*m.EncipheredNKode, error) { code, err := u.EncipherSaltHashCode(passcodeAttrIdx, customerAttrs) if err != nil { return nil, err @@ -180,7 +180,7 @@ func (u *UserCipherKeys) EncipherNKode(passcodeAttrIdx []int, customerAttrs Cust } } mask, err := u.EncipherMask(passcodeSet, customerAttrs) - encipheredCode := model.EncipheredNKode{ + encipheredCode := m.EncipheredNKode{ Code: code, Mask: mask, } diff --git a/core/nkode/user_interface.go b/core/nkode/user_interface.go index 98d6ca8..30c5eb0 100644 --- a/core/nkode/user_interface.go +++ b/core/nkode/user_interface.go @@ -3,17 +3,17 @@ package nkode import ( "errors" "fmt" - "go-nkode/core/model" + m "go-nkode/core/model" "go-nkode/hashset" "go-nkode/util" ) type UserInterface struct { - IdxInterface []int - KeypadSize model.KeypadSize + IdxInterface m.IdxInterface + KeypadSize m.KeypadSize } -func NewUserInterface(keypadSize model.KeypadSize) (*UserInterface, error) { +func NewUserInterface(keypadSize m.KeypadSize) (*UserInterface, error) { idxInterface := util.IdentityArray(keypadSize.TotalAttrs()) userInterface := UserInterface{ IdxInterface: idxInterface, diff --git a/core/nkode/user_signup_session.go b/core/nkode/user_signup_session.go index 4f60703..dc86af5 100644 --- a/core/nkode/user_signup_session.go +++ b/core/nkode/user_signup_session.go @@ -4,61 +4,61 @@ import ( "errors" "fmt" "github.com/google/uuid" - "go-nkode/core/model" + m "go-nkode/core/model" "go-nkode/hashset" - py_builtin "go-nkode/py-builtin" + py "go-nkode/py-builtin" "go-nkode/util" ) type UserSignSession struct { - SessionId uuid.UUID - CustomerId uuid.UUID - LoginInterface UserInterface - KeypadSize model.KeypadSize - SetInterface []int - ConfirmInterface []int - SetKeyEntry []int - Username string + SessionId m.SessionId + CustomerId m.CustomerId + LoginUserInterface UserInterface + Keypad m.KeypadSize + SetIdxInterface m.IdxInterface + ConfirmIdxInterface m.IdxInterface + SetKeySelection m.KeySelection + Username m.Username } -func NewSignupSession(keypadSize model.KeypadSize, customerId uuid.UUID) (*UserSignSession, error) { +func NewSignupSession(keypadSize m.KeypadSize, customerId m.CustomerId) (*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, + SessionId: m.SessionId(uuid.New()), + CustomerId: customerId, + LoginUserInterface: *loginInterface, + SetIdxInterface: signupInter.IdxInterface, + ConfirmIdxInterface: nil, + SetKeySelection: nil, + Username: "", + Keypad: 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 +func (s *UserSignSession) DeducePasscode(confirmKeyEntry m.KeySelection) ([]int, error) { + validEntry := py.All[int](confirmKeyEntry, func(i int) bool { + return 0 <= i && i < s.LoginUserInterface.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)) + return nil, errors.New(fmt.Sprintf("Invalid Key entry. One or more key index: %#v, not in range 0-%d", confirmKeyEntry, s.LoginUserInterface.KeypadSize.NumbOfKeys)) } - if s.SetInterface == nil { + if s.SetIdxInterface == nil { return nil, errors.New("signup session set interface is nil") } - if s.ConfirmInterface == nil { + if s.ConfirmIdxInterface == nil { return nil, errors.New("signup session confirm interface is nil") } - if s.SetKeyEntry == nil { + if s.SetKeySelection == nil { return nil, errors.New("signup session set key entry is nil") } @@ -66,16 +66,16 @@ func (s *UserSignSession) DeducePasscode(confirmKeyEntry []int) ([]int, error) { 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))) + if len(confirmKeyEntry) != len(s.SetKeySelection) { + return nil, errors.New(fmt.Sprintf("confirm and set key entry lenght mismatch %d != %d", len(confirmKeyEntry), len(s.SetKeySelection))) } passcodeLen := len(confirmKeyEntry) - setKeyVals, err := s.getSelectedKeyVals(s.SetKeyEntry, s.SetInterface) + setKeyVals, err := s.getSelectedKeyVals(s.SetKeySelection, s.SetIdxInterface) if err != nil { return nil, err } - confirmKeyVals, err := s.getSelectedKeyVals(confirmKeyEntry, s.ConfirmInterface) + confirmKeyVals, err := s.getSelectedKeyVals(confirmKeyEntry, s.ConfirmIdxInterface) passcode := make([]int, passcodeLen) for idx := 0; idx < passcodeLen; idx++ { @@ -94,28 +94,28 @@ func (s *UserSignSession) DeducePasscode(confirmKeyEntry []int) ([]int, error) { 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 +func (s *UserSignSession) SetUserNKode(username m.Username, keySelection m.KeySelection) (m.IdxInterface, error) { + validKeySelection := py.All[int](keySelection, func(i int) bool { + return 0 <= i && i < s.Keypad.NumbOfKeys }) if !validKeySelection { - return nil, errors.New(fmt.Sprintf("one or key selection is out of range 0-%d", s.KeypadSize.NumbOfKeys-1)) + return nil, errors.New(fmt.Sprintf("one or key selection is out of range 0-%d", s.Keypad.NumbOfKeys-1)) } - s.SetKeyEntry = keySelection + s.SetKeySelection = keySelection s.Username = username - setInterface := UserInterface{IdxInterface: s.SetInterface, KeypadSize: s.KeypadSize} + setInterface := UserInterface{IdxInterface: s.SetIdxInterface, KeypadSize: s.Keypad} err := setInterface.DisperseInterface() if err != nil { return nil, err } - s.ConfirmInterface = setInterface.IdxInterface - return s.ConfirmInterface, nil + s.ConfirmIdxInterface = setInterface.IdxInterface + return s.ConfirmIdxInterface, nil } -func (s *UserSignSession) getSelectedKeyVals(keySelections []int, userInterface []int) ([][]int, error) { - keypadInterface, err := util.ListToMatrix(userInterface, s.KeypadSize.AttrsPerKey) +func (s *UserSignSession) getSelectedKeyVals(keySelections m.KeySelection, userInterface []int) ([][]int, error) { + keypadInterface, err := util.ListToMatrix(userInterface, s.Keypad.AttrsPerKey) if err != nil { return nil, err } @@ -155,7 +155,7 @@ func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) { } signupUserInterface := UserInterface{ IdxInterface: util.MatrixToList(attrSetView), - KeypadSize: model.KeypadSize{ + KeypadSize: m.KeypadSize{ AttrsPerKey: numbOfKeys, NumbOfKeys: numbOfKeys, }, diff --git a/core/nkode/user_test.go b/core/nkode/user_test.go index 910817d..6bb10a6 100644 --- a/core/nkode/user_test.go +++ b/core/nkode/user_test.go @@ -2,13 +2,13 @@ package nkode import ( "github.com/stretchr/testify/assert" - "go-nkode/core/model" - py_builtin "go-nkode/py-builtin" + m "go-nkode/core/model" + py "go-nkode/py-builtin" "testing" ) func TestUserCipherKeys_EncipherSaltHashCode(t *testing.T) { - keypadSize := model.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} + keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} maxNKodeLen := 10 customerAttrs, err := NewCustomerAttributes(keypadSize) assert.NoError(t, err) @@ -22,7 +22,7 @@ func TestUserCipherKeys_EncipherSaltHashCode(t *testing.T) { } func TestUserCipherKeys_EncipherDecipherMask(t *testing.T) { - keypadSize := model.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} + keypadSize := m.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} maxNKodeLen := 10 customerAttrs, err := NewCustomerAttributes(keypadSize) @@ -48,7 +48,7 @@ func TestUserCipherKeys_EncipherDecipherMask(t *testing.T) { } func TestUserInterface_RandomShuffle(t *testing.T) { - keypadSize := model.KeypadSize{ + keypadSize := m.KeypadSize{ AttrsPerKey: 10, NumbOfKeys: 5, } @@ -73,7 +73,7 @@ func TestUserInterface_RandomShuffle(t *testing.T) { func TestUserInterface_DisperseInterface(t *testing.T) { for idx := 0; idx < 10000; idx++ { - keypadSize := model.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} + keypadSize := m.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} userInterface, err := NewUserInterface(keypadSize) assert.NoError(t, err) @@ -92,7 +92,7 @@ func TestUserInterface_DisperseInterface(t *testing.T) { } func TestUserInterface_PartialInterfaceShuffle(t *testing.T) { - keypadSize := model.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} + keypadSize := m.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} userInterface, err := NewUserInterface(keypadSize) assert.NoError(t, err) preShuffle := userInterface.IdxInterface @@ -105,12 +105,12 @@ func TestUserInterface_PartialInterfaceShuffle(t *testing.T) { shuffleCompare[idx] = val == postShuffle[idx] } - allTrue := py_builtin.All[bool](shuffleCompare, func(n bool) bool { + allTrue := py.All[bool](shuffleCompare, func(n bool) bool { return n == true }) assert.False(t, allTrue) - allFalse := py_builtin.All[bool](shuffleCompare, func(n bool) bool { + allFalse := py.All[bool](shuffleCompare, func(n bool) bool { return n == false }) diff --git a/main.go b/main.go index 947f74e..a8f53c2 100644 --- a/main.go +++ b/main.go @@ -9,8 +9,8 @@ import ( ) func main() { - nkodeApi := nkode.NewNKodeAPI() - handler := api.NKodeHandler{Api: nkodeApi} + nkodeApi := nkode.NewNKodeInMemory() + handler := api.NKodeHandler{Api: &nkodeApi} mux := http.NewServeMux() mux.Handle(api.CreateNewCustomer, &handler) mux.Handle(api.GenerateSignupInterface, &handler) @@ -19,6 +19,6 @@ func main() { mux.Handle(api.GetLoginInterface, &handler) mux.Handle(api.Login, &handler) mux.Handle(api.RenewAttributes, &handler) - fmt.Println("Running on localhost:8080") + fmt.Println("Running on localhost:8080...") log.Fatal(http.ListenAndServe("localhost:8080", mux)) } diff --git a/main_test.go b/main_test.go index 3297c63..2979ff7 100644 --- a/main_test.go +++ b/main_test.go @@ -5,7 +5,7 @@ import ( "encoding/json" "github.com/stretchr/testify/assert" "go-nkode/core/api" - "go-nkode/core/model" + m "go-nkode/core/model" "go-nkode/core/nkode" "io" "net/http" @@ -14,55 +14,55 @@ import ( func TestApi(t *testing.T) { base := "http://localhost:8080" - newCustomerBody := model.NewCustomerPost{ - KeypadSize: model.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10}, - NKodePolicy: model.NewDefaultNKodePolicy(), + newCustomerBody := m.NewCustomerPost{ + KeypadSize: m.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10}, + NKodePolicy: m.NewDefaultNKodePolicy(), } - var customerResp model.CreateNewCustomerResp + var customerResp m.CreateNewCustomerResp testApiCall(t, base+api.CreateNewCustomer, newCustomerBody, &customerResp) - signupInterfaceBody := model.GetLoginInterfacePost{CustomerId: customerResp.CustomerId} - var signupInterfaceResp model.GenerateSignupInterfaceResp + signupInterfaceBody := m.GetLoginInterfacePost{CustomerId: customerResp.CustomerId} + var signupInterfaceResp m.GenerateSignupInterfaceResp testApiCall(t, base+api.GenerateSignupInterface, signupInterfaceBody, &signupInterfaceResp) - username := "test_username" + username := m.Username("test_username") passcodeLen := 4 setInterface := signupInterfaceResp.UserInterface userPasscode := setInterface[:passcodeLen] - keypadSize := model.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 5} + keypadSize := m.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 5} setKeySelection, err := nkode.SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize) assert.NoError(t, err) - setNKodeBody := model.SetNKodePost{ + setNKodeBody := m.SetNKodePost{ CustomerId: customerResp.CustomerId, Username: username, SessionId: signupInterfaceResp.SessionId, KeySelection: setKeySelection, } - var setNKodeResp model.SetNKodeResp + var setNKodeResp m.SetNKodeResp testApiCall(t, base+api.SetNKode, setNKodeBody, &setNKodeResp) confirmInterface := setNKodeResp.UserInterface confirmKeySelection, err := nkode.SelectKeyByAttrIdx(confirmInterface, userPasscode, keypadSize) assert.NoError(t, err) - confirmNKodeBody := model.ConfirmNKodePost{ + confirmNKodeBody := m.ConfirmNKodePost{ CustomerId: customerResp.CustomerId, KeySelection: confirmKeySelection, SessionId: signupInterfaceResp.SessionId, } testApiCall(t, base+api.ConfirmNKode, confirmNKodeBody, nil) - loginInterfaceBody := model.GetLoginInterfacePost{ + loginInterfaceBody := m.GetLoginInterfacePost{ CustomerId: customerResp.CustomerId, Username: username, } - var loginInterfaceResp model.GetLoginInterfaceResp + var loginInterfaceResp m.GetLoginInterfaceResp testApiCall(t, base+api.GetLoginInterface, loginInterfaceBody, &loginInterfaceResp) - keypadSize = model.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10} + keypadSize = m.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10} loginKeySelection, err := nkode.SelectKeyByAttrIdx(loginInterfaceResp.UserInterface, userPasscode, keypadSize) assert.NoError(t, err) - loginBody := model.LoginPost{ + loginBody := m.LoginPost{ CustomerId: customerResp.CustomerId, Username: username, KeySelection: loginKeySelection, @@ -70,12 +70,12 @@ func TestApi(t *testing.T) { testApiCall(t, base+api.Login, loginBody, nil) - renewBody := model.RenewAttributesPost{CustomerId: customerResp.CustomerId} + renewBody := m.RenewAttributesPost{CustomerId: customerResp.CustomerId} testApiCall(t, base+api.RenewAttributes, renewBody, nil) loginKeySelection, err = nkode.SelectKeyByAttrIdx(loginInterfaceResp.UserInterface, userPasscode, keypadSize) assert.NoError(t, err) - loginBody = model.LoginPost{ + loginBody = m.LoginPost{ CustomerId: customerResp.CustomerId, Username: username, KeySelection: loginKeySelection,