reorganize code

This commit is contained in:
2024-08-23 10:18:39 -05:00
parent 6a56b2300a
commit dbc8ca3d29
20 changed files with 476 additions and 214 deletions

11
core/api/endpoints.go Normal file
View File

@@ -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"
)

View File

@@ -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
}
}

278
core/api/nkode_handler.go Normal file
View File

@@ -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"))
}

View File

@@ -1,4 +1,4 @@
package models package model
type KeypadSize struct { type KeypadSize struct {
AttrsPerKey int `json:"attrs_per_key"` AttrsPerKey int `json:"attrs_per_key"`

View File

@@ -1,4 +1,4 @@
package models package model
type NKodePolicy struct { type NKodePolicy struct {
MaxNkodeLen int `json:"max_nkode_len"` MaxNkodeLen int `json:"max_nkode_len"`

40
core/model/post.go Normal file
View File

@@ -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"`
}

20
core/model/response.go Normal file
View File

@@ -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"`
}

View File

@@ -1,23 +1,23 @@
package api package nkode
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/google/uuid" "github.com/google/uuid"
"go-nkode/core/model"
"go-nkode/hashset" "go-nkode/hashset"
m "go-nkode/models"
py "go-nkode/py-builtin" py "go-nkode/py-builtin"
"go-nkode/util" "go-nkode/util"
) )
type Customer struct { type Customer struct {
CustomerId uuid.UUID CustomerId uuid.UUID
NKodePolicy m.NKodePolicy NKodePolicy model.NKodePolicy
Attributes CustomerAttributes Attributes CustomerAttributes
Users map[string]User 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 { 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)) return nil, errors.New(fmt.Sprintf("incompadible nkode policy and keypad size TotalAttrs: %d < DistinctAttributes: %d", keypadSize.TotalAttrs(), nkodePolicy.DistinctAttributes))
} }

View File

@@ -1,9 +1,9 @@
package api package nkode
import ( import (
"errors" "errors"
"fmt" "fmt"
"go-nkode/models" "go-nkode/core/model"
"go-nkode/util" "go-nkode/util"
) )
@@ -11,10 +11,10 @@ import (
type CustomerAttributes struct { type CustomerAttributes struct {
AttrVals []uint64 AttrVals []uint64
SetVals []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() { if keypadSize.IsDispersable() {
return nil, errors.New("number of keys must be less than the number of attributes per key to be dispersion resistant") return nil, errors.New("number of keys must be less than the number of attributes per key to be dispersion resistant")
} }

View File

@@ -1,20 +1,20 @@
package api package nkode
import ( import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"go-nkode/models" model2 "go-nkode/core/model"
"testing" "testing"
) )
func TestNewCustomerAttributes(t *testing.T) { func TestNewCustomerAttributes(t *testing.T) {
keypad := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} keypad := model2.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5}
_, nil := NewCustomerAttributes(keypad) _, nil := NewCustomerAttributes(keypad)
assert.NoError(t, nil) assert.NoError(t, nil)
} }
func TestCustomer_ValidKeyEntry(t *testing.T) { func TestCustomer_ValidKeyEntry(t *testing.T) {
keypadSize := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} keypadSize := model2.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7}
nkodePolicy := models.NewDefaultNKodePolicy() nkodePolicy := model2.NewDefaultNKodePolicy()
customer, err := NewCustomer(keypadSize, nkodePolicy) customer, err := NewCustomer(keypadSize, nkodePolicy)
assert.NoError(t, err) assert.NoError(t, err)
newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize)
@@ -36,8 +36,8 @@ func TestCustomer_ValidKeyEntry(t *testing.T) {
} }
func TestCustomer_IsValidNKode(t *testing.T) { func TestCustomer_IsValidNKode(t *testing.T) {
keypadSize := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7} keypadSize := model2.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 7}
nkodePolicy := models.NewDefaultNKodePolicy() nkodePolicy := model2.NewDefaultNKodePolicy()
customer, err := NewCustomer(keypadSize, nkodePolicy) customer, err := NewCustomer(keypadSize, nkodePolicy)
assert.NoError(t, err) assert.NoError(t, err)
newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize) newUserInterface, err := NewUserInterface(customer.Attributes.KeypadSize)

View File

@@ -1,10 +1,10 @@
package api package nkode
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/google/uuid" "github.com/google/uuid"
"go-nkode/models" "go-nkode/core/model"
) )
type NKodeAPI struct { 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) newCustomer, err := NewCustomer(keypadSize, nkodePolicy)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -1,8 +1,8 @@
package api package nkode
import ( import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"go-nkode/models" "go-nkode/core/model"
"testing" "testing"
) )
@@ -10,14 +10,14 @@ func TestNKodeAPI(t *testing.T) {
for idx := 0; idx < 10; idx++ { for idx := 0; idx < 10; idx++ {
username := "test_username" username := "test_username"
passcodeLen := 4 passcodeLen := 4
nkodePolicy := models.NewDefaultNKodePolicy() nkodePolicy := model.NewDefaultNKodePolicy()
keypadSize := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} keypadSize := model.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3}
nkodeApi := NewNKodeAPI() nkodeApi := NewNKodeAPI()
customerId, err := nkodeApi.CreateNewCustomer(keypadSize, nkodePolicy) customerId, err := nkodeApi.CreateNewCustomer(keypadSize, nkodePolicy)
assert.NoError(t, err) assert.NoError(t, err)
sessionId, setInterface, err := nkodeApi.GenerateSignupInterface(*customerId) sessionId, setInterface, err := nkodeApi.GenerateSignupInterface(*customerId)
assert.NoError(t, err) assert.NoError(t, err)
keypadSize = models.KeypadSize{AttrsPerKey: 3, NumbOfKeys: 3} keypadSize = model.KeypadSize{AttrsPerKey: 3, NumbOfKeys: 3}
userPasscode := setInterface[:passcodeLen] userPasscode := setInterface[:passcodeLen]
setKeySelect, err := SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize) setKeySelect, err := SelectKeyByAttrIdx(setInterface, userPasscode, keypadSize)
assert.NoError(t, err) assert.NoError(t, err)
@@ -27,7 +27,7 @@ func TestNKodeAPI(t *testing.T) {
err = nkodeApi.ConfirmNKode(*customerId, confirmKeySelect, *sessionId) err = nkodeApi.ConfirmNKode(*customerId, confirmKeySelect, *sessionId)
assert.NoError(t, err) assert.NoError(t, err)
keypadSize = models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3} keypadSize = model.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 3}
loginInterface, err := nkodeApi.GetLoginInterface(username, *customerId) loginInterface, err := nkodeApi.GetLoginInterface(username, *customerId)
assert.NoError(t, err) assert.NoError(t, err)
loginKeySelection, err := SelectKeyByAttrIdx(loginInterface, userPasscode, keypadSize) loginKeySelection, err := SelectKeyByAttrIdx(loginInterface, userPasscode, keypadSize)

View File

@@ -1,13 +1,13 @@
package api package nkode
import ( import (
"errors" "errors"
"fmt" "fmt"
"go-nkode/models" "go-nkode/core/model"
"go-nkode/util" "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)) selectedKeys := make([]int, len(passcodeIdxs))
for idx := range passcodeIdxs { for idx := range passcodeIdxs {
attrIdx := util.IndexOf[int](interfaceUser, passcodeIdxs[idx]) attrIdx := util.IndexOf[int](interfaceUser, passcodeIdxs[idx])

View File

@@ -1,7 +1,7 @@
package api package nkode
import ( import (
m "go-nkode/models" m "go-nkode/core/model"
"go-nkode/util" "go-nkode/util"
) )

View File

@@ -1,10 +1,10 @@
package api package nkode
import ( import (
"crypto/sha256" "crypto/sha256"
"errors" "errors"
"fmt" "fmt"
"go-nkode/models" "go-nkode/core/model"
"go-nkode/util" "go-nkode/util"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
@@ -18,7 +18,7 @@ type UserCipherKeys struct {
MaxNKodeLen int 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 { if len(setVals) != keypadSize.AttrsPerKey {
return nil, errors.New(fmt.Sprintf("setVals len != attrsPerKey, %d, %d", 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 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) code, err := u.EncipherSaltHashCode(passcodeAttrIdx, customerAttrs)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -180,7 +180,7 @@ func (u *UserCipherKeys) EncipherNKode(passcodeAttrIdx []int, customerAttrs Cust
} }
} }
mask, err := u.EncipherMask(passcodeSet, customerAttrs) mask, err := u.EncipherMask(passcodeSet, customerAttrs)
encipheredCode := models.EncipheredNKode{ encipheredCode := model.EncipheredNKode{
Code: code, Code: code,
Mask: mask, Mask: mask,
} }

View File

@@ -1,19 +1,19 @@
package api package nkode
import ( import (
"errors" "errors"
"fmt" "fmt"
"go-nkode/core/model"
"go-nkode/hashset" "go-nkode/hashset"
"go-nkode/models"
"go-nkode/util" "go-nkode/util"
) )
type UserInterface struct { type UserInterface struct {
IdxInterface []int 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()) idxInterface := util.IdentityArray(keypadSize.TotalAttrs())
userInterface := UserInterface{ userInterface := UserInterface{
IdxInterface: idxInterface, IdxInterface: idxInterface,

View File

@@ -1,11 +1,11 @@
package api package nkode
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/google/uuid" "github.com/google/uuid"
"go-nkode/core/model"
"go-nkode/hashset" "go-nkode/hashset"
"go-nkode/models"
py_builtin "go-nkode/py-builtin" py_builtin "go-nkode/py-builtin"
"go-nkode/util" "go-nkode/util"
) )
@@ -14,14 +14,14 @@ type UserSignSession struct {
SessionId uuid.UUID SessionId uuid.UUID
CustomerId uuid.UUID CustomerId uuid.UUID
LoginInterface UserInterface LoginInterface UserInterface
KeypadSize models.KeypadSize KeypadSize model.KeypadSize
SetInterface []int SetInterface []int
ConfirmInterface []int ConfirmInterface []int
SetKeyEntry []int SetKeyEntry []int
Username string 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) loginInterface, err := NewUserInterface(keypadSize)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -155,7 +155,7 @@ func signupInterface(baseUserInterface UserInterface) (*UserInterface, error) {
} }
signupUserInterface := UserInterface{ signupUserInterface := UserInterface{
IdxInterface: util.MatrixToList(attrSetView), IdxInterface: util.MatrixToList(attrSetView),
KeypadSize: models.KeypadSize{ KeypadSize: model.KeypadSize{
AttrsPerKey: numbOfKeys, AttrsPerKey: numbOfKeys,
NumbOfKeys: numbOfKeys, NumbOfKeys: numbOfKeys,
}, },

View File

@@ -1,14 +1,14 @@
package api package nkode
import ( import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"go-nkode/models" "go-nkode/core/model"
py_builtin "go-nkode/py-builtin" py_builtin "go-nkode/py-builtin"
"testing" "testing"
) )
func TestUserCipherKeys_EncipherSaltHashCode(t *testing.T) { func TestUserCipherKeys_EncipherSaltHashCode(t *testing.T) {
keypadSize := models.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5} keypadSize := model.KeypadSize{AttrsPerKey: 10, NumbOfKeys: 5}
maxNKodeLen := 10 maxNKodeLen := 10
customerAttrs, err := NewCustomerAttributes(keypadSize) customerAttrs, err := NewCustomerAttributes(keypadSize)
assert.NoError(t, err) assert.NoError(t, err)
@@ -22,7 +22,7 @@ func TestUserCipherKeys_EncipherSaltHashCode(t *testing.T) {
} }
func TestUserCipherKeys_EncipherDecipherMask(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 maxNKodeLen := 10
customerAttrs, err := NewCustomerAttributes(keypadSize) customerAttrs, err := NewCustomerAttributes(keypadSize)
@@ -48,7 +48,7 @@ func TestUserCipherKeys_EncipherDecipherMask(t *testing.T) {
} }
func TestUserInterface_RandomShuffle(t *testing.T) { func TestUserInterface_RandomShuffle(t *testing.T) {
keypadSize := models.KeypadSize{ keypadSize := model.KeypadSize{
AttrsPerKey: 10, AttrsPerKey: 10,
NumbOfKeys: 5, NumbOfKeys: 5,
} }
@@ -73,7 +73,7 @@ func TestUserInterface_RandomShuffle(t *testing.T) {
func TestUserInterface_DisperseInterface(t *testing.T) { func TestUserInterface_DisperseInterface(t *testing.T) {
for idx := 0; idx < 10000; idx++ { for idx := 0; idx < 10000; idx++ {
keypadSize := models.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10} keypadSize := model.KeypadSize{AttrsPerKey: 7, NumbOfKeys: 10}
userInterface, err := NewUserInterface(keypadSize) userInterface, err := NewUserInterface(keypadSize)
assert.NoError(t, err) assert.NoError(t, err)
@@ -92,7 +92,7 @@ func TestUserInterface_DisperseInterface(t *testing.T) {
} }
func TestUserInterface_PartialInterfaceShuffle(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) userInterface, err := NewUserInterface(keypadSize)
assert.NoError(t, err) assert.NoError(t, err)
preShuffle := userInterface.IdxInterface preShuffle := userInterface.IdxInterface

View File

@@ -3,12 +3,13 @@ package main
import ( import (
"fmt" "fmt"
"go-nkode/core/api" "go-nkode/core/api"
"go-nkode/core/nkode"
"log" "log"
"net/http" "net/http"
) )
func main() { func main() {
nkodeApi := api.NewNKodeAPI() nkodeApi := nkode.NewNKodeAPI()
handler := api.NKodeHandler{Api: nkodeApi} handler := api.NKodeHandler{Api: nkodeApi}
mux := http.NewServeMux() mux := http.NewServeMux()
mux.Handle(api.CreateNewCustomer, &handler) mux.Handle(api.CreateNewCustomer, &handler)

View File

@@ -1,14 +1,85 @@
package main package main
import ( import (
"bytes"
"encoding/json"
"github.com/stretchr/testify/assert"
"go-nkode/core/api" "go-nkode/core/api"
"go-nkode/core/model"
"go-nkode/core/nkode"
"io"
"net/http" "net/http"
"testing" "testing"
) )
func TestMain(t *testing.T) { func TestApi(t *testing.T) {
base := "http://localhost:8080" 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)
}
}