reorganize code
This commit is contained in:
11
core/api/endpoints.go
Normal file
11
core/api/endpoints.go
Normal 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"
|
||||
)
|
||||
@@ -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
278
core/api/nkode_handler.go
Normal 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"))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package models
|
||||
package model
|
||||
|
||||
type KeypadSize struct {
|
||||
AttrsPerKey int `json:"attrs_per_key"`
|
||||
@@ -1,4 +1,4 @@
|
||||
package models
|
||||
package model
|
||||
|
||||
type NKodePolicy struct {
|
||||
MaxNkodeLen int `json:"max_nkode_len"`
|
||||
40
core/model/post.go
Normal file
40
core/model/post.go
Normal 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
20
core/model/response.go
Normal 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"`
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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])
|
||||
@@ -1,7 +1,7 @@
|
||||
package api
|
||||
package nkode
|
||||
|
||||
import (
|
||||
m "go-nkode/models"
|
||||
m "go-nkode/core/model"
|
||||
"go-nkode/util"
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
},
|
||||
@@ -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
|
||||
3
main.go
3
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)
|
||||
|
||||
75
main_test.go
75
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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user