From dbc8ca3d293e4b4992cd74f686f8a38b0841a668 Mon Sep 17 00:00:00 2001 From: Donovan Date: Fri, 23 Aug 2024 10:18:39 -0500 Subject: [PATCH] reorganize code --- core/api/endpoints.go | 11 + core/api/nkode_api_handler.go | 159 ---------- core/api/nkode_handler.go | 278 ++++++++++++++++++ models/models.go => core/model/keypad_size.go | 2 +- {models => core/model}/nkode_policy.go | 2 +- core/model/post.go | 40 +++ core/model/response.go | 20 ++ core/{api => nkode}/customer.go | 8 +- core/{api => nkode}/customer_attributes.go | 8 +- core/{api => nkode}/customer_test.go | 14 +- core/{api => nkode}/nkode_api.go | 6 +- core/{api => nkode}/nkode_api_test.go | 12 +- core/{api => nkode}/test_helper.go | 6 +- core/{api => nkode}/user.go | 4 +- core/{api => nkode}/user_cipher_keys.go | 10 +- core/{api => nkode}/user_interface.go | 8 +- core/{api => nkode}/user_signup_session.go | 10 +- core/{api => nkode}/user_test.go | 14 +- main.go | 3 +- main_test.go | 75 ++++- 20 files changed, 476 insertions(+), 214 deletions(-) create mode 100644 core/api/endpoints.go delete mode 100644 core/api/nkode_api_handler.go create mode 100644 core/api/nkode_handler.go rename models/models.go => core/model/keypad_size.go (95%) rename {models => core/model}/nkode_policy.go (97%) create mode 100644 core/model/post.go create mode 100644 core/model/response.go rename core/{api => nkode}/customer.go (97%) rename core/{api => nkode}/customer_attributes.go (92%) rename core/{api => nkode}/customer_test.go (81%) rename core/{api => nkode}/nkode_api.go (96%) rename core/{api => nkode}/nkode_api_test.go (84%) rename core/{api => nkode}/test_helper.go (86%) rename core/{api => nkode}/user.go (96%) rename core/{api => nkode}/user_cipher_keys.go (95%) rename core/{api => nkode}/user_interface.go (96%) rename core/{api => nkode}/user_signup_session.go (95%) rename core/{api => nkode}/user_test.go (91%) diff --git a/core/api/endpoints.go b/core/api/endpoints.go new file mode 100644 index 0000000..48995e1 --- /dev/null +++ b/core/api/endpoints.go @@ -0,0 +1,11 @@ +package api + +const ( + CreateNewCustomer = "/create-new-customer" + GenerateSignupInterface = "/generate-signup-interface" + SetNKode = "/set-nkode" + ConfirmNKode = "/confirm-nkode" + GetLoginInterface = "/get-login-interface" + Login = "/login" + RenewAttributes = "/renew-attributes" +) diff --git a/core/api/nkode_api_handler.go b/core/api/nkode_api_handler.go deleted file mode 100644 index fe57024..0000000 --- a/core/api/nkode_api_handler.go +++ /dev/null @@ -1,159 +0,0 @@ -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 - } -} diff --git a/core/api/nkode_handler.go b/core/api/nkode_handler.go new file mode 100644 index 0000000..1278dff --- /dev/null +++ b/core/api/nkode_handler.go @@ -0,0 +1,278 @@ +package api + +import ( + "encoding/json" + "go-nkode/core/model" + "go-nkode/core/nkode" + "log" + "net/http" +) + +type NKodeHandler struct { + Api nkode.NKodeAPI +} + +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: + h.SetNKodeHandler(w, r) + case ConfirmNKode: + h.ConfirmNKodeHandler(w, r) + case GetLoginInterface: + h.GetLoginInterfaceHandler(w, r) + case Login: + h.LoginHandler(w, r) + case RenewAttributes: + h.RenewAttributesHandler(w, r) + default: + w.WriteHeader(http.StatusNotFound) + w.Write([]byte("404 not found")) + log.Fatal(r.URL.Path, " not found") + } +} + +func (h *NKodeHandler) CreateNewCustomerHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + methodNotAllowed(w) + return + } + var customerPost model.NewCustomerPost + err := decodeJson(w, r, &customerPost) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + customerId, err := h.Api.CreateNewCustomer(customerPost.KeypadSize, customerPost.NKodePolicy) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + respBody := model.CreateNewCustomerResp{ + CustomerId: *customerId, + } + respBytes, err := json.Marshal(respBody) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + _, err = w.Write(respBytes) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + w.WriteHeader(http.StatusOK) +} + +func (h *NKodeHandler) GenerateSignupInterfaceHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + methodNotAllowed(w) + return + } + + var signupPost model.GenerateSignupInterfacePost + err := decodeJson(w, r, &signupPost) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + sessionId, userInterface, err := h.Api.GenerateSignupInterface(signupPost.CustomerId) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + respBody := model.GenerateSignupInterfaceResp{ + SessionId: *sessionId, + UserInterface: userInterface, + } + respBytes, err := json.Marshal(respBody) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + _, err = w.Write(respBytes) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + w.WriteHeader(http.StatusOK) +} + +func (h *NKodeHandler) SetNKodeHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + methodNotAllowed(w) + return + } + var setNKodePost model.SetNKodePost + err := decodeJson(w, r, &setNKodePost) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + confirmInterface, err := h.Api.SetNKode(setNKodePost.Username, setNKodePost.CustomerId, setNKodePost.KeySelection, setNKodePost.SessionId) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + respBody := model.SetNKodeResp{UserInterface: confirmInterface} + + respBytes, err := json.Marshal(respBody) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + _, err = w.Write(respBytes) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + w.WriteHeader(http.StatusOK) +} + +func (h *NKodeHandler) ConfirmNKodeHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + methodNotAllowed(w) + return + } + + var confirmNKodePost model.ConfirmNKodePost + err := decodeJson(w, r, &confirmNKodePost) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + err = h.Api.ConfirmNKode(confirmNKodePost.CustomerId, confirmNKodePost.KeySelection, confirmNKodePost.SessionId) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + w.WriteHeader(http.StatusOK) + +} + +func (h *NKodeHandler) GetLoginInterfaceHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + methodNotAllowed(w) + return + } + var loginInterfacePost model.GetLoginInterfacePost + err := decodeJson(w, r, &loginInterfacePost) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + loginInterface, err := h.Api.GetLoginInterface(loginInterfacePost.Username, loginInterfacePost.CustomerId) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + respBody := model.GetLoginInterfaceResp{UserInterface: loginInterface} + respBytes, err := json.Marshal(respBody) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + _, err = w.Write(respBytes) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + w.WriteHeader(http.StatusOK) + +} + +func (h *NKodeHandler) LoginHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + methodNotAllowed(w) + return + } + var loginPost model.LoginPost + err := decodeJson(w, r, &loginPost) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + err = h.Api.Login(loginPost.CustomerId, loginPost.Username, loginPost.KeySelection) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + w.WriteHeader(http.StatusOK) +} + +func (h *NKodeHandler) RenewAttributesHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + methodNotAllowed(w) + return + } + var renewAttributesPost model.RenewAttributesPost + err := decodeJson(w, r, &renewAttributesPost) + + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + err = h.Api.RenewAttributes(renewAttributesPost.CustomerId) + if err != nil { + internalServerErrorHandler(w, r) + log.Fatal(err) + return + } + + w.WriteHeader(http.StatusOK) +} + +func decodeJson(w http.ResponseWriter, r *http.Request, post any) error { + err := json.NewDecoder(r.Body).Decode(&post) + if err != nil { + internalServerErrorHandler(w, r) + return err + } + return nil + +} + +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")) +} diff --git a/models/models.go b/core/model/keypad_size.go similarity index 95% rename from models/models.go rename to core/model/keypad_size.go index b9f96fd..44eec43 100644 --- a/models/models.go +++ b/core/model/keypad_size.go @@ -1,4 +1,4 @@ -package models +package model type KeypadSize struct { AttrsPerKey int `json:"attrs_per_key"` diff --git a/models/nkode_policy.go b/core/model/nkode_policy.go similarity index 97% rename from models/nkode_policy.go rename to core/model/nkode_policy.go index 1c6c6f5..31690fd 100644 --- a/models/nkode_policy.go +++ b/core/model/nkode_policy.go @@ -1,4 +1,4 @@ -package models +package model type NKodePolicy struct { MaxNkodeLen int `json:"max_nkode_len"` diff --git a/core/model/post.go b/core/model/post.go new file mode 100644 index 0000000..83f1a76 --- /dev/null +++ b/core/model/post.go @@ -0,0 +1,40 @@ +package model + +import "github.com/google/uuid" + +type NewCustomerPost struct { + KeypadSize KeypadSize `json:"keypad_size"` + NKodePolicy 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"` +} diff --git a/core/model/response.go b/core/model/response.go new file mode 100644 index 0000000..745b9f4 --- /dev/null +++ b/core/model/response.go @@ -0,0 +1,20 @@ +package model + +import "github.com/google/uuid" + +type CreateNewCustomerResp struct { + CustomerId uuid.UUID `json:"customer_id"` +} + +type GenerateSignupInterfaceResp struct { + SessionId uuid.UUID `json:"session_id"` + UserInterface []int `json:"user_interface"` +} + +type SetNKodeResp struct { + UserInterface []int `json:"user_interface"` +} + +type GetLoginInterfaceResp struct { + UserInterface []int `json:"user_interface"` +} diff --git a/core/api/customer.go b/core/nkode/customer.go similarity index 97% rename from core/api/customer.go rename to core/nkode/customer.go index c96614f..a66c0e6 100644 --- a/core/api/customer.go +++ b/core/nkode/customer.go @@ -1,23 +1,23 @@ -package api +package nkode import ( "errors" "fmt" "github.com/google/uuid" + "go-nkode/core/model" "go-nkode/hashset" - m "go-nkode/models" py "go-nkode/py-builtin" "go-nkode/util" ) type Customer struct { CustomerId uuid.UUID - NKodePolicy m.NKodePolicy + NKodePolicy model.NKodePolicy Attributes CustomerAttributes Users map[string]User } -func NewCustomer(keypadSize m.KeypadSize, nkodePolicy m.NKodePolicy) (*Customer, error) { +func NewCustomer(keypadSize model.KeypadSize, nkodePolicy model.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)) } diff --git a/core/api/customer_attributes.go b/core/nkode/customer_attributes.go similarity index 92% rename from core/api/customer_attributes.go rename to core/nkode/customer_attributes.go index 0c70bfb..05fa477 100644 --- a/core/api/customer_attributes.go +++ b/core/nkode/customer_attributes.go @@ -1,9 +1,9 @@ -package api +package nkode import ( "errors" "fmt" - "go-nkode/models" + "go-nkode/core/model" "go-nkode/util" ) @@ -11,10 +11,10 @@ import ( type CustomerAttributes struct { AttrVals []uint64 SetVals []uint64 - KeypadSize models.KeypadSize + KeypadSize model.KeypadSize } -func NewCustomerAttributes(keypadSize models.KeypadSize) (*CustomerAttributes, error) { +func NewCustomerAttributes(keypadSize model.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/api/customer_test.go b/core/nkode/customer_test.go similarity index 81% rename from core/api/customer_test.go rename to core/nkode/customer_test.go index 5989e70..fe63079 100644 --- a/core/api/customer_test.go +++ b/core/nkode/customer_test.go @@ -1,20 +1,20 @@ -package api +package nkode import ( "github.com/stretchr/testify/assert" - "go-nkode/models" + model2 "go-nkode/core/model" "testing" ) func TestNewCustomerAttributes(t *testing.T) { - keypad := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} + keypad := model2.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} _, nil := NewCustomerAttributes(keypad) assert.NoError(t, nil) } func TestCustomer_ValidKeyEntry(t *testing.T) { - keypadSize := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} - nkodePolicy := models.NewDefaultNKodePolicy() + keypadSize := model2.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} + nkodePolicy := model2.NewDefaultNKodePolicy() customer, err := NewCustomer(keypadSize, nkodePolicy) assert.NoError(t, err) newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) @@ -36,8 +36,8 @@ func TestCustomer_ValidKeyEntry(t *testing.T) { } func TestCustomer_IsValidNKode(t *testing.T) { - keypadSize := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} - nkodePolicy := models.NewDefaultNKodePolicy() + keypadSize := model2.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} + nkodePolicy := model2.NewDefaultNKodePolicy() customer, err := NewCustomer(keypadSize, nkodePolicy) assert.NoError(t, err) newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) diff --git a/core/api/nkode_api.go b/core/nkode/nkode_api.go similarity index 96% rename from core/api/nkode_api.go rename to core/nkode/nkode_api.go index ded571a..e7287e3 100644 --- a/core/api/nkode_api.go +++ b/core/nkode/nkode_api.go @@ -1,10 +1,10 @@ -package api +package nkode import ( "errors" "fmt" "github.com/google/uuid" - "go-nkode/models" + "go-nkode/core/model" ) type NKodeAPI struct { @@ -19,7 +19,7 @@ func NewNKodeAPI() NKodeAPI { } } -func (n *NKodeAPI) CreateNewCustomer(keypadSize models.KeypadSize, nkodePolicy models.NKodePolicy) (*uuid.UUID, error) { +func (n *NKodeAPI) CreateNewCustomer(keypadSize model.KeypadSize, nkodePolicy model.NKodePolicy) (*uuid.UUID, error) { newCustomer, err := NewCustomer(keypadSize, nkodePolicy) if err != nil { return nil, err diff --git a/core/api/nkode_api_test.go b/core/nkode/nkode_api_test.go similarity index 84% rename from core/api/nkode_api_test.go rename to core/nkode/nkode_api_test.go index 6ff93e9..7f5f679 100644 --- a/core/api/nkode_api_test.go +++ b/core/nkode/nkode_api_test.go @@ -1,8 +1,8 @@ -package api +package nkode import ( "github.com/stretchr/testify/assert" - "go-nkode/models" + "go-nkode/core/model" "testing" ) @@ -10,14 +10,14 @@ 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} + nkodePolicy := model.NewDefaultNKodePolicy() + keypadSize := model.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} + keypadSize = model.KeypadSize{AttrsPerKey: 3, NumbOfKeys: 3} userPasscode := setInterface[:passcodeLen] setKeySelect, err := SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize) assert.NoError(t, err) @@ -27,7 +27,7 @@ func TestNKodeAPI(t *testing.T) { err = nkodeApi.ConfirmNKode(*customerId, confirmKeySelect, *sessionId) assert.NoError(t, err) - keypadSize = models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} + keypadSize = model.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/api/test_helper.go b/core/nkode/test_helper.go similarity index 86% rename from core/api/test_helper.go rename to core/nkode/test_helper.go index b1bbed4..2b76b15 100644 --- a/core/api/test_helper.go +++ b/core/nkode/test_helper.go @@ -1,13 +1,13 @@ -package api +package nkode import ( "errors" "fmt" - "go-nkode/models" + "go-nkode/core/model" "go-nkode/util" ) -func SelectKeyByAttrIdx(interfaceUser []int, passcodeIdxs []int, keypadSize models.KeypadSize) ([]int, error) { +func SelectKeyByAttrIdx(interfaceUser []int, passcodeIdxs []int, keypadSize model.KeypadSize) ([]int, error) { selectedKeys := make([]int, len(passcodeIdxs)) for idx := range passcodeIdxs { attrIdx := util.IndexOf[int](interfaceUser, passcodeIdxs[idx]) diff --git a/core/api/user.go b/core/nkode/user.go similarity index 96% rename from core/api/user.go rename to core/nkode/user.go index 5912b28..cf7bafd 100644 --- a/core/api/user.go +++ b/core/nkode/user.go @@ -1,7 +1,7 @@ -package api +package nkode import ( - m "go-nkode/models" + m "go-nkode/core/model" "go-nkode/util" ) diff --git a/core/api/user_cipher_keys.go b/core/nkode/user_cipher_keys.go similarity index 95% rename from core/api/user_cipher_keys.go rename to core/nkode/user_cipher_keys.go index ddd5431..ca3d35d 100644 --- a/core/api/user_cipher_keys.go +++ b/core/nkode/user_cipher_keys.go @@ -1,10 +1,10 @@ -package api +package nkode import ( "crypto/sha256" "errors" "fmt" - "go-nkode/models" + "go-nkode/core/model" "go-nkode/util" "golang.org/x/crypto/bcrypt" ) @@ -18,7 +18,7 @@ type UserCipherKeys struct { MaxNKodeLen int } -func NewUserCipherKeys(keypadSize models.KeypadSize, setVals []uint64, maxNKodeLen int) (*UserCipherKeys, error) { +func NewUserCipherKeys(keypadSize model.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) (*models.EncipheredNKode, error) { +func (u *UserCipherKeys) EncipherNKode(passcodeAttrIdx []int, customerAttrs CustomerAttributes) (*model.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 := models.EncipheredNKode{ + encipheredCode := model.EncipheredNKode{ Code: code, Mask: mask, } diff --git a/core/api/user_interface.go b/core/nkode/user_interface.go similarity index 96% rename from core/api/user_interface.go rename to core/nkode/user_interface.go index 377158b..98d6ca8 100644 --- a/core/api/user_interface.go +++ b/core/nkode/user_interface.go @@ -1,19 +1,19 @@ -package api +package nkode import ( "errors" "fmt" + "go-nkode/core/model" "go-nkode/hashset" - "go-nkode/models" "go-nkode/util" ) type UserInterface struct { IdxInterface []int - KeypadSize models.KeypadSize + KeypadSize model.KeypadSize } -func NewUserInterface(keypadSize models.KeypadSize) (*UserInterface, error) { +func NewUserInterface(keypadSize model.KeypadSize) (*UserInterface, error) { idxInterface := util.IdentityArray(keypadSize.TotalAttrs()) userInterface := UserInterface{ IdxInterface: idxInterface, diff --git a/core/api/user_signup_session.go b/core/nkode/user_signup_session.go similarity index 95% rename from core/api/user_signup_session.go rename to core/nkode/user_signup_session.go index 3f2e25a..4f60703 100644 --- a/core/api/user_signup_session.go +++ b/core/nkode/user_signup_session.go @@ -1,11 +1,11 @@ -package api +package nkode import ( "errors" "fmt" "github.com/google/uuid" + "go-nkode/core/model" "go-nkode/hashset" - "go-nkode/models" py_builtin "go-nkode/py-builtin" "go-nkode/util" ) @@ -14,14 +14,14 @@ type UserSignSession struct { SessionId uuid.UUID CustomerId uuid.UUID LoginInterface UserInterface - KeypadSize models.KeypadSize + KeypadSize model.KeypadSize SetInterface []int ConfirmInterface []int SetKeyEntry []int Username string } -func NewSignupSession(keypadSize models.KeypadSize, customerId uuid.UUID) (*UserSignSession, error) { +func NewSignupSession(keypadSize model.KeypadSize, customerId uuid.UUID) (*UserSignSession, error) { loginInterface, err := NewUserInterface(keypadSize) if err != nil { return nil, err @@ -155,7 +155,7 @@ func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) { } signupUserInterface := UserInterface{ IdxInterface: util.MatrixToList(attrSetView), - KeypadSize: models.KeypadSize{ + KeypadSize: model.KeypadSize{ AttrsPerKey: numbOfKeys, NumbOfKeys: numbOfKeys, }, diff --git a/core/api/user_test.go b/core/nkode/user_test.go similarity index 91% rename from core/api/user_test.go rename to core/nkode/user_test.go index e0a3642..910817d 100644 --- a/core/api/user_test.go +++ b/core/nkode/user_test.go @@ -1,14 +1,14 @@ -package api +package nkode import ( "github.com/stretchr/testify/assert" - "go-nkode/models" + "go-nkode/core/model" py_builtin "go-nkode/py-builtin" "testing" ) func TestUserCipherKeys_EncipherSaltHashCode(t *testing.T) { - keypadSize := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} + keypadSize := model.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 := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} + keypadSize := model.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 := models.KeypadSize{ + keypadSize := model.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 := models.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} + keypadSize := model.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 := models.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} + keypadSize := model.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} userInterface, err := NewUserInterface(keypadSize) assert.NoError(t, err) preShuffle := userInterface.IdxInterface diff --git a/main.go b/main.go index dbfaa91..947f74e 100644 --- a/main.go +++ b/main.go @@ -3,12 +3,13 @@ package main import ( "fmt" "go-nkode/core/api" + "go-nkode/core/nkode" "log" "net/http" ) func main() { - nkodeApi := api.NewNKodeAPI() + nkodeApi := nkode.NewNKodeAPI() handler := api.NKodeHandler{Api: nkodeApi} mux := http.NewServeMux() mux.Handle(api.CreateNewCustomer, &handler) diff --git a/main_test.go b/main_test.go index 19f976e..47976d9 100644 --- a/main_test.go +++ b/main_test.go @@ -1,14 +1,85 @@ package main import ( + "bytes" + "encoding/json" + "github.com/stretchr/testify/assert" "go-nkode/core/api" + "go-nkode/core/model" + "go-nkode/core/nkode" + "io" "net/http" "testing" ) -func TestMain(t *testing.T) { +func TestApi(t *testing.T) { base := "http://localhost:8080" + newCustomerBody := model.NewCustomerPost{ + KeypadSize: model.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10}, + NKodePolicy: model.NewDefaultNKodePolicy(), + } - resp, err := http.Post(base+api.CreateNewCustomer, "application/json") + var customerResp model.CreateNewCustomerResp + testApiCall(t, base+api.CreateNewCustomer, newCustomerBody, &customerResp) + + signupInterfaceBody := model.GetLoginInterfacePost{CustomerId: customerResp.CustomerId} + var signupInterfaceResp model.GenerateSignupInterfaceResp + testApiCall(t, base+api.GenerateSignupInterface, signupInterfaceBody, &signupInterfaceResp) + + username := "test_username" + passcodeLen := 4 + setInterface := signupInterfaceResp.UserInterface + userPasscode := setInterface[:passcodeLen] + keypadSize := model.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 5} + setKeySelection, err := nkode.SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize) + assert.NoError(t, err) + setNKodeBody := model.SetNKodePost{ + CustomerId: customerResp.CustomerId, + Username: username, + SessionId: signupInterfaceResp.SessionId, + KeySelection: setKeySelection, + } + var setNKodeResp model.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{ + CustomerId: customerResp.CustomerId, + KeySelection: confirmKeySelection, + SessionId: signupInterfaceResp.SessionId, + } + testApiCall(t, base+api.ConfirmNKode, confirmNKodeBody, nil) + + loginInterfaceBody := model.GetLoginInterfacePost{ + CustomerId: customerResp.CustomerId, + Username: username, + } + + keypadSize = model.KeypadSize{NumbOfKeys: 5, AttrsPerKey: 10} } + +func Unmarshal(t *testing.T, resp *http.Response, data any) { + responseBody, err := io.ReadAll(resp.Body) + assert.NoError(t, err) + err = json.Unmarshal(responseBody, data) + assert.NoError(t, err) +} + +func Marshal(t *testing.T, data any) *bytes.Reader { + jsonBytes, err := json.Marshal(data) + assert.NoError(t, err) + reader := bytes.NewReader(jsonBytes) + return reader +} + +func testApiCall(t *testing.T, endpointStr string, postBody any, respBody any) { + reader := Marshal(t, postBody) + resp, err := http.Post(endpointStr, "application/json", reader) + assert.NoError(t, err) + assert.Equal(t, resp.StatusCode, http.StatusOK) + if respBody != nil { + Unmarshal(t, resp, respBody) + } +}