implement gin nkode api
This commit is contained in:
@@ -33,11 +33,8 @@ func NewNKodeAPI(repo repository.CustomerUserRepository, queue *email.Queue) NKo
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) CreateNewCustomer(nkodePolicy entities.NKodePolicy, id *entities.CustomerId) (*entities.CustomerId, error) {
|
||||
func (n *NKodeAPI) CreateNewCustomer(nkodePolicy entities.NKodePolicy) (*entities.CustomerId, error) {
|
||||
newCustomer, err := entities.NewCustomer(nkodePolicy)
|
||||
if id != nil {
|
||||
newCustomer.Id = *id
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -49,6 +46,18 @@ func (n *NKodeAPI) CreateNewCustomer(nkodePolicy entities.NKodePolicy, id *entit
|
||||
return &newCustomer.Id, nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) CreateCustomerWithID(id entities.CustomerId, nkodePolicy entities.NKodePolicy) error {
|
||||
newCustomer, err := entities.NewCustomer(nkodePolicy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newCustomer.Id = id
|
||||
if err = n.repo.CreateCustomer(*newCustomer); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) GenerateSignupResetInterface(userEmail entities.UserEmail, customerId entities.CustomerId, kp entities.KeypadDimension, reset bool) (*entities.SignupResetInterface, error) {
|
||||
user, err := n.repo.GetUser(userEmail, customerId)
|
||||
if err != nil {
|
||||
@@ -265,3 +274,18 @@ func (n *NKodeAPI) ResetNKode(userEmail entities.UserEmail, customerId entities.
|
||||
n.emailQueue.AddEmail(email)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NKodeAPI) Signout(userEmail entities.UserEmail, customerId entities.CustomerId) error {
|
||||
user, err := n.repo.GetUser(userEmail, customerId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user == nil {
|
||||
log.Printf("user %s for customer %s dne", userEmail, customerId)
|
||||
return config.ErrUserForCustomerDNE
|
||||
}
|
||||
if err = n.repo.UpdateUserRefreshToken(user.Id, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func testNKodeAPI(t *testing.T, db repository.CustomerUserRepository) {
|
||||
nkodePolicy := entities.NewDefaultNKodePolicy()
|
||||
keypadSize := entities.KeypadDimension{AttrsPerKey: attrsPerKey, NumbOfKeys: numbOfKeys}
|
||||
nkodeApi := NewNKodeAPI(db, queue)
|
||||
customerId, err := nkodeApi.CreateNewCustomer(nkodePolicy, nil)
|
||||
customerId, err := nkodeApi.CreateNewCustomer(nkodePolicy)
|
||||
assert.NoError(t, err)
|
||||
signupResponse, err := nkodeApi.GenerateSignupResetInterface(userEmail, *customerId, keypadSize, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -3,12 +3,12 @@ package entities
|
||||
import "git.infra.nkode.tech/dkelly/nkode-core/config"
|
||||
|
||||
type NKodePolicy struct {
|
||||
MaxNkodeLen int `json:"max_nkode_len"`
|
||||
MinNkodeLen int `json:"min_nkode_len"`
|
||||
DistinctSets int `json:"distinct_sets"`
|
||||
DistinctAttributes int `json:"distinct_attributes"`
|
||||
LockOut int `json:"lock_out"`
|
||||
Expiration int `json:"expiration"` // seconds, -1 no expiration
|
||||
MaxNkodeLen int `json:"max_nkode_len" form:"max_nkode_len" binding:"required"`
|
||||
MinNkodeLen int `json:"min_nkode_len" form:"min_nkode_len" binding:"required"`
|
||||
DistinctSets int `json:"distinct_sets" form:"distinct_sets" binding:"required"`
|
||||
DistinctAttributes int `json:"distinct_attributes" form:"distinct_attributes" binding:"required"`
|
||||
LockOut int `json:"lock_out" form:"lock_out" binding:"required"`
|
||||
Expiration int `json:"expiration" form:"expiration" binding:"required"` // seconds, -1 no expiration
|
||||
}
|
||||
|
||||
func NewDefaultNKodePolicy() NKodePolicy {
|
||||
|
||||
25
go.mod
25
go.mod
@@ -27,8 +27,33 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.9 // indirect
|
||||
github.com/aws/smithy-go v1.22.1 // indirect
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.10.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
70
go.sum
70
go.sum
@@ -28,31 +28,101 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.33.9 h1:BRVDbewN6VZcwr+FBOszDKvYeXY1
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.9/go.mod h1:f6vjfZER1M17Fokn0IzssOTMT2N8ZSq+7jnNF0tArvw=
|
||||
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
|
||||
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
||||
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
||||
340
handler/handler.go
Normal file
340
handler/handler.go
Normal file
@@ -0,0 +1,340 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"git.infra.nkode.tech/dkelly/nkode-core/api"
|
||||
"git.infra.nkode.tech/dkelly/nkode-core/config"
|
||||
"git.infra.nkode.tech/dkelly/nkode-core/entities"
|
||||
"git.infra.nkode.tech/dkelly/nkode-core/models"
|
||||
"git.infra.nkode.tech/dkelly/nkode-core/security"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type NkodeHandler struct {
|
||||
API api.NKodeAPI
|
||||
Logger *log.Logger
|
||||
}
|
||||
|
||||
const (
|
||||
malformedCustomerId = "malformed customer id"
|
||||
malformedUserEmail = "malformed user email"
|
||||
malformedSessionId = "malformed session id"
|
||||
invalidKeypadDimensions = "invalid keypad dimensions"
|
||||
)
|
||||
|
||||
func (h *NkodeHandler) RegisterRoutes(r *gin.Engine) {
|
||||
r.Group("/v1/nkode")
|
||||
{
|
||||
r.POST("/create-new-customer", h.CreateNewCustomerHandler)
|
||||
r.POST("/generate-signup-reset-interface", h.SignupResetHandler)
|
||||
r.POST("/set-nkode", h.SetNKodeHandler)
|
||||
r.POST("/confirm-nkode", h.ConfirmNKodeHandler)
|
||||
r.POST("/get-login-interface", h.GetLoginInterfaceHandler)
|
||||
r.POST("/login", h.LoginHandler)
|
||||
r.POST("/renew-attributes", h.RenewAttributesHandler)
|
||||
r.POST("/random-svg-interface", h.RandomSvgInterfaceHandler)
|
||||
r.POST("/refresh-token", h.RefreshTokenHandler)
|
||||
r.POST("/reset-nkode", h.ResetNKodeHandler)
|
||||
r.POST("/signout", h.SignoutHandler)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) CreateNewCustomerHandler(c *gin.Context) {
|
||||
var newCustomerPost entities.NKodePolicy
|
||||
if err := c.ShouldBind(&newCustomerPost); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
customerId, err := h.API.CreateNewCustomer(newCustomerPost)
|
||||
if err != nil {
|
||||
c.String(500, "Internal Server Error")
|
||||
return
|
||||
}
|
||||
h.Logger.Println("create new customer")
|
||||
c.JSON(200, gin.H{"customer_id": customerId})
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) SignupResetHandler(c *gin.Context) {
|
||||
h.Logger.Println("generate signup reset interface")
|
||||
var postBody models.SignupRestPostBody
|
||||
if err := c.ShouldBind(&postBody); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
kp := entities.KeypadDimension{
|
||||
AttrsPerKey: postBody.AttrsPerKey,
|
||||
NumbOfKeys: postBody.NumbOfKeys,
|
||||
}
|
||||
|
||||
if err := kp.IsValidKeypadDimension(); err != nil {
|
||||
c.String(400, invalidKeypadDimensions)
|
||||
return
|
||||
}
|
||||
|
||||
customerId, err := uuid.Parse(postBody.CustomerId)
|
||||
if err != nil {
|
||||
c.String(400, malformedCustomerId)
|
||||
return
|
||||
}
|
||||
|
||||
userEmail, err := entities.ParseEmail(postBody.UserEmail)
|
||||
if err != nil {
|
||||
c.String(400, malformedUserEmail)
|
||||
return
|
||||
}
|
||||
resp, err := h.API.GenerateSignupResetInterface(userEmail, entities.CustomerId(customerId), kp, postBody.Reset)
|
||||
if err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp)
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) SetNKodeHandler(c *gin.Context) {
|
||||
h.Logger.Println("set nkode")
|
||||
var postBody models.SetNKodePost
|
||||
if err := c.ShouldBind(&postBody); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
customerId, err := uuid.Parse(postBody.CustomerId)
|
||||
if err != nil {
|
||||
c.String(400, malformedCustomerId)
|
||||
return
|
||||
}
|
||||
sessionId, err := uuid.Parse(postBody.SessionId)
|
||||
if err != nil {
|
||||
c.String(400, malformedSessionId)
|
||||
return
|
||||
}
|
||||
|
||||
confirmInterface, err := h.API.SetNKode(entities.CustomerId(customerId), entities.SessionId(sessionId), postBody.KeySelection)
|
||||
if err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
resp := models.SetNKodeResp{UserInterface: confirmInterface}
|
||||
c.JSON(200, resp)
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) ConfirmNKodeHandler(c *gin.Context) {
|
||||
h.Logger.Println("confirm nkode")
|
||||
var postBody models.ConfirmNKodePost
|
||||
if err := c.ShouldBind(&postBody); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
customerId, err := uuid.Parse(postBody.CustomerId)
|
||||
if err != nil {
|
||||
c.String(400, malformedCustomerId)
|
||||
return
|
||||
}
|
||||
sessionId, err := uuid.Parse(postBody.SessionId)
|
||||
if err != nil {
|
||||
c.String(400, malformedSessionId)
|
||||
return
|
||||
}
|
||||
if err := h.API.ConfirmNKode(entities.CustomerId(customerId), entities.SessionId(sessionId), postBody.KeySelection); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
c.Status(200)
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) GetLoginInterfaceHandler(c *gin.Context) {
|
||||
h.Logger.Println("get login interface")
|
||||
var loginInterfacePost models.LoginInterfacePost
|
||||
if err := c.ShouldBind(&loginInterfacePost); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
customerId, err := uuid.Parse(loginInterfacePost.CustomerId)
|
||||
if err != nil {
|
||||
c.String(400, malformedCustomerId)
|
||||
return
|
||||
}
|
||||
|
||||
userEmail, err := entities.ParseEmail(loginInterfacePost.UserEmail)
|
||||
if err != nil {
|
||||
c.String(400, malformedUserEmail)
|
||||
return
|
||||
}
|
||||
postBody, err := h.API.GetLoginInterface(userEmail, entities.CustomerId(customerId))
|
||||
if err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, postBody)
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) LoginHandler(c *gin.Context) {
|
||||
h.Logger.Println("login")
|
||||
|
||||
var loginPost models.LoginPost
|
||||
if err := c.ShouldBind(&loginPost); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
customerId, err := uuid.Parse(loginPost.CustomerId)
|
||||
if err != nil {
|
||||
c.String(400, malformedCustomerId)
|
||||
return
|
||||
}
|
||||
|
||||
userEmail, err := entities.ParseEmail(loginPost.UserEmail)
|
||||
if err != nil {
|
||||
c.String(400, malformedUserEmail)
|
||||
return
|
||||
}
|
||||
jwtToken, err := h.API.Login(entities.CustomerId(customerId), userEmail, loginPost.KeySelection)
|
||||
if err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, jwtToken)
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) RenewAttributesHandler(c *gin.Context) {
|
||||
h.Logger.Println("renew attributes")
|
||||
|
||||
var renewAttributesPost models.RenewAttributesPost
|
||||
if err := c.ShouldBind(&renewAttributesPost); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
customerId, err := uuid.Parse(renewAttributesPost.CustomerId)
|
||||
if err != nil {
|
||||
c.String(400, malformedCustomerId)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.API.RenewAttributes(entities.CustomerId(customerId)); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
c.Status(200)
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) RandomSvgInterfaceHandler(c *gin.Context) {
|
||||
h.Logger.Println("random svg interface")
|
||||
svgs, err := h.API.RandomSvgInterface()
|
||||
if err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
resp := models.RandomSvgInterfaceResp{Svgs: svgs}
|
||||
c.JSON(200, resp)
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) RefreshTokenHandler(c *gin.Context) {
|
||||
h.Logger.Println("refresh token")
|
||||
refreshToken, err := getBearerToken(c)
|
||||
if err != nil {
|
||||
c.String(403, "forbidden")
|
||||
return
|
||||
}
|
||||
refreshClaims, err := security.ParseRegisteredClaimToken(refreshToken)
|
||||
customerId, err := uuid.Parse(refreshClaims.Issuer)
|
||||
if err != nil {
|
||||
c.String(400, malformedCustomerId)
|
||||
return
|
||||
}
|
||||
userEmail, err := entities.ParseEmail(refreshClaims.Subject)
|
||||
if err != nil {
|
||||
c.String(400, malformedUserEmail)
|
||||
return
|
||||
}
|
||||
accessToken, err := h.API.RefreshToken(userEmail, entities.CustomerId(customerId), refreshToken)
|
||||
if err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"access_token": accessToken})
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) ResetNKodeHandler(c *gin.Context) {
|
||||
h.Logger.Println("reset nkode")
|
||||
var resetNKodePost models.ResetNKodePost
|
||||
if err := c.ShouldBind(&resetNKodePost); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
customerId, err := uuid.Parse(resetNKodePost.CustomerId)
|
||||
if err != nil {
|
||||
c.String(400, malformedCustomerId)
|
||||
return
|
||||
}
|
||||
userEmail, err := entities.ParseEmail(resetNKodePost.UserEmail)
|
||||
if err != nil {
|
||||
c.String(400, malformedUserEmail)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.API.ResetNKode(userEmail, entities.CustomerId(customerId)); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
c.Status(200)
|
||||
}
|
||||
|
||||
func (h *NkodeHandler) SignoutHandler(c *gin.Context) {
|
||||
h.Logger.Println("signout")
|
||||
token, err := getBearerToken(c)
|
||||
if err != nil {
|
||||
c.String(403, "forbidden")
|
||||
return
|
||||
}
|
||||
accessClaims, err := security.ParseRegisteredClaimToken(token)
|
||||
if err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
customerId, err := uuid.Parse(accessClaims.Issuer)
|
||||
if err != nil {
|
||||
c.String(400, malformedCustomerId)
|
||||
return
|
||||
}
|
||||
userEmail, err := entities.ParseEmail(accessClaims.Subject)
|
||||
if err != nil {
|
||||
c.String(400, malformedUserEmail)
|
||||
return
|
||||
}
|
||||
if err = h.API.Signout(userEmail, entities.CustomerId(customerId)); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
c.Status(200)
|
||||
}
|
||||
|
||||
func handleError(c *gin.Context, err error) {
|
||||
log.Print("handling error: ", err)
|
||||
statusCode, _ := config.HttpErrMap[err]
|
||||
switch statusCode {
|
||||
case 400:
|
||||
c.String(400, err.Error())
|
||||
case 403:
|
||||
c.String(403, err.Error())
|
||||
case 500:
|
||||
c.String(500, "Internal Server Error")
|
||||
default:
|
||||
log.Print("unknown error: ", err)
|
||||
c.String(500, "Internal Server Error")
|
||||
}
|
||||
}
|
||||
|
||||
func getBearerToken(c *gin.Context) (string, error) {
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
// Check if the Authorization header is present and starts with "Bearer "
|
||||
if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") {
|
||||
return "", errors.New("forbidden")
|
||||
}
|
||||
token := strings.TrimPrefix(authHeader, "Bearer ")
|
||||
return token, nil
|
||||
}
|
||||
60
models/models.go
Normal file
60
models/models.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package models
|
||||
|
||||
import "git.infra.nkode.tech/dkelly/nkode-core/entities"
|
||||
|
||||
type SetNKodeResp struct {
|
||||
UserInterface []int `json:"user_interface"`
|
||||
}
|
||||
|
||||
type RandomSvgInterfaceResp struct {
|
||||
Svgs []string `form:"svgs" binding:"required"`
|
||||
Colors []entities.RGBColor `form:"colors" binding:"required"`
|
||||
}
|
||||
|
||||
type RefreshTokenResp struct {
|
||||
AccessToken string `form:"access_token" binding:"required"`
|
||||
}
|
||||
|
||||
type SignupRestPostBody struct {
|
||||
CustomerId string `form:"customer_id" binding:"required"`
|
||||
AttrsPerKey int `form:"attrs_per_key" binding:"required"`
|
||||
NumbOfKeys int `form:"numb_of_keys" binding:"required"`
|
||||
UserEmail string `form:"email" binding:"required"`
|
||||
Reset bool `form:"reset" binding:"required"`
|
||||
}
|
||||
|
||||
type SetNKodePost struct {
|
||||
CustomerId string `form:"customer_id" binding:"required"`
|
||||
KeySelection []int `form:"key_selection" binding:"required"`
|
||||
SessionId string `form:"session_id" binding:"required"`
|
||||
}
|
||||
|
||||
type ConfirmNKodePost struct {
|
||||
CustomerId string `form:"customer_id" binding:"required"`
|
||||
KeySelection entities.KeySelection `form:"key_selection" binding:"required"`
|
||||
SessionId string `form:"session_id" binding:"required"`
|
||||
}
|
||||
|
||||
type LoginInterfacePost struct {
|
||||
UserEmail string `form:"email" binding:"required"`
|
||||
CustomerId string `form:"customer_id" binding:"required"`
|
||||
}
|
||||
|
||||
type LoginPost struct {
|
||||
CustomerId string `form:"customer_id" binding:"required"`
|
||||
UserEmail string `form:"email" binding:"required"`
|
||||
KeySelection entities.KeySelection `form:"key_selection" binding:"required"`
|
||||
}
|
||||
|
||||
type RenewAttributesPost struct {
|
||||
CustomerId string `form:"customer_id" binding:"required"`
|
||||
}
|
||||
|
||||
type ResetNKodePost struct {
|
||||
UserEmail string `form:"email" binding:"required"`
|
||||
CustomerId string `form:"customer_id" binding:"required"`
|
||||
}
|
||||
|
||||
type CreateNewCustomerResp struct {
|
||||
CustomerId string `form:"customer_id" binding:"required"`
|
||||
}
|
||||
Reference in New Issue
Block a user