package core import ( "encoding/json" "errors" "github.com/google/uuid" "log" "net/http" ) type NKodeHandler struct { Api NKodeAPI } const ( CreateNewCustomer = "/create-new-customer" GenerateSignupInterface = "/generate-signup-interface" SetNKode = "/set-nkode" ConfirmNKode = "/confirm-nkode" GetLoginInterface = "/get-login-interface" Login = "/login" RenewAttributes = "/renew-attributes" RandomSvgInterface = "/random-svg-interface" RefreshToken = "/refresh-token" ) func (h *NKodeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case CreateNewCustomer: h.CreateNewCustomerHandler(w, r) 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) case RandomSvgInterface: h.RandomSvgInterfaceHandler(w, r) case RefreshToken: h.RefreshTokenHandler(w, r) default: w.WriteHeader(http.StatusNotFound) _, err := w.Write([]byte("404 not found")) log.Println(err) } } func (h *NKodeHandler) CreateNewCustomerHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { methodNotAllowed(w) return } var customerPost NewCustomerPost err := decodeJson(w, r, &customerPost) if err != nil { internalServerErrorHandler(w) log.Println(err) return } customerId, err := h.Api.CreateNewCustomer(customerPost.NKodePolicy, nil) if err != nil { internalServerErrorHandler(w) log.Println(err) return } respBody := CreateNewCustomerResp{ CustomerId: uuid.UUID(*customerId).String(), } respBytes, err := json.Marshal(respBody) if err != nil { internalServerErrorHandler(w) log.Println(err) return } _, err = w.Write(respBytes) if err != nil { internalServerErrorHandler(w) log.Println(err) return } w.WriteHeader(http.StatusOK) } func (h *NKodeHandler) GenerateSignupInterfaceHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { methodNotAllowed(w) return } log.Print("signup interface") var signupPost GenerateSignupInterfacePost err := decodeJson(w, r, &signupPost) if err != nil { internalServerErrorHandler(w) log.Println(err) return } kp := KeypadDimension{ AttrsPerKey: signupPost.AttrsPerKey, NumbOfKeys: signupPost.NumbOfKeys, } err = kp.IsValidKeypadDimension() if err != nil { keypadSizeOutOfRange(w) log.Println(err) return } customerId, err := uuid.Parse(signupPost.CustomerId) if err != nil { internalServerErrorHandler(w) log.Println(err) return } resp, err := h.Api.GenerateSignupInterface(signupPost.Username, CustomerId(customerId), kp) if err != nil { internalServerErrorHandler(w) log.Println(err) return } respBytes, err := json.Marshal(resp) if err != nil { internalServerErrorHandler(w) log.Println(err) return } _, err = w.Write(respBytes) if err != nil { internalServerErrorHandler(w) log.Println(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 SetNKodePost err := decodeJson(w, r, &setNKodePost) if err != nil { internalServerErrorHandler(w) log.Println(err) return } customerId, err := uuid.Parse(setNKodePost.CustomerId) if err != nil { internalServerErrorHandler(w) log.Println(err) return } sessionId, err := uuid.Parse(setNKodePost.SessionId) if err != nil { internalServerErrorHandler(w) log.Println(err) return } confirmInterface, err := h.Api.SetNKode(CustomerId(customerId), SessionId(sessionId), setNKodePost.KeySelection) if err != nil { internalServerErrorHandler(w) log.Println(err) return } respBody := SetNKodeResp{UserInterface: confirmInterface} respBytes, err := json.Marshal(respBody) if err != nil { internalServerErrorHandler(w) log.Println(err) return } _, err = w.Write(respBytes) if err != nil { internalServerErrorHandler(w) log.Println(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 ConfirmNKodePost err := decodeJson(w, r, &confirmNKodePost) if err != nil { internalServerErrorHandler(w) log.Println(err) return } customerId, err := uuid.Parse(confirmNKodePost.CustomerId) if err != nil { internalServerErrorHandler(w) log.Println(err) return } sessionId, err := uuid.Parse(confirmNKodePost.SessionId) if err != nil { internalServerErrorHandler(w) log.Println(err) return } err = h.Api.ConfirmNKode(CustomerId(customerId), SessionId(sessionId), confirmNKodePost.KeySelection) if err != nil { internalServerErrorHandler(w) log.Println(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 GetLoginInterfacePost err := decodeJson(w, r, &loginInterfacePost) if err != nil { internalServerErrorHandler(w) log.Println(err) return } customerId, err := uuid.Parse(loginInterfacePost.CustomerId) if err != nil { internalServerErrorHandler(w) log.Println(err) return } loginInterface, err := h.Api.GetLoginInterface(loginInterfacePost.Username, CustomerId(customerId)) if err != nil { internalServerErrorHandler(w) log.Println(err) return } respBytes, err := json.Marshal(loginInterface) if err != nil { internalServerErrorHandler(w) log.Println(err) return } _, err = w.Write(respBytes) if err != nil { internalServerErrorHandler(w) log.Println(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 LoginPost err := decodeJson(w, r, &loginPost) if err != nil { internalServerErrorHandler(w) log.Println(err) return } customerId, err := uuid.Parse(loginPost.CustomerId) if err != nil { internalServerErrorHandler(w) log.Println(err) return } jwtTokens, err := h.Api.Login(CustomerId(customerId), loginPost.Username, loginPost.KeySelection) if err != nil { internalServerErrorHandler(w) log.Println(err) return } respBytes, err := json.Marshal(jwtTokens) if err != nil { internalServerErrorHandler(w) log.Println(err) return } _, err = w.Write(respBytes) if err != nil { internalServerErrorHandler(w) log.Println(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 RenewAttributesPost err := decodeJson(w, r, &renewAttributesPost) if err != nil { internalServerErrorHandler(w) log.Println(err) return } customerId, err := uuid.Parse(renewAttributesPost.CustomerId) if err != nil { internalServerErrorHandler(w) log.Println(err) return } err = h.Api.RenewAttributes(CustomerId(customerId)) if err != nil { internalServerErrorHandler(w) log.Println(err) return } w.WriteHeader(http.StatusOK) } func (h *NKodeHandler) RandomSvgInterfaceHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { methodNotAllowed(w) } svgs, err := h.Api.RandomSvgInterface() if err != nil { internalServerErrorHandler(w) log.Println(err) return } respBody := RandomSvgInterfaceResp{Svgs: svgs} respBytes, err := json.Marshal(respBody) if err != nil { internalServerErrorHandler(w) log.Println(err) return } _, err = w.Write(respBytes) if err != nil { internalServerErrorHandler(w) log.Println(err) return } w.WriteHeader(http.StatusOK) } func (h *NKodeHandler) RefreshTokenHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { methodNotAllowed(w) } var refreshTokenPost RefreshTokenPost err := decodeJson(w, r, &refreshTokenPost) if err != nil { internalServerErrorHandler(w) log.Println(err) return } customerId, err := uuid.Parse(refreshTokenPost.CustomerId) if err != nil { internalServerErrorHandler(w) log.Println(err) return } accessToken, err := h.Api.RefreshToken(Username(refreshTokenPost.Username), CustomerId(customerId), refreshTokenPost.RefreshToken) if err != nil { internalServerErrorHandler(w) log.Println(err) return } respBytes, err := json.Marshal(RefreshTokenResp{AccessToken: accessToken}) if err != nil { internalServerErrorHandler(w) log.Println(err) return } _, err = w.Write(respBytes) if err != nil { internalServerErrorHandler(w) log.Println(err) return } w.WriteHeader(http.StatusOK) } func decodeJson(w http.ResponseWriter, r *http.Request, post any) error { if r.Body == nil { invalidJson(w) return errors.New("invalid json") } err := json.NewDecoder(r.Body).Decode(&post) if err != nil { internalServerErrorHandler(w) return err } return nil } func internalServerErrorHandler(w http.ResponseWriter) { 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 keypadSizeOutOfRange(w http.ResponseWriter) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("invalid keypad dimensions")) } func invalidJson(w http.ResponseWriter) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("invalid json")) }