165 lines
3.6 KiB
Go
165 lines
3.6 KiB
Go
|
package handlers
|
||
|
|
||
|
import (
|
||
|
"bitbucket.org/skeris/bbfoundation/jwt_adapter"
|
||
|
"bitbucket.org/skeris/treasurer/dal"
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"github.com/danilsolovyov/validator"
|
||
|
"github.com/gorilla/schema"
|
||
|
"github.com/themakers/hlog"
|
||
|
"net/http"
|
||
|
)
|
||
|
|
||
|
//#region ======== Handler Struct ========
|
||
|
|
||
|
type Handler struct {
|
||
|
w http.ResponseWriter
|
||
|
r *http.Request
|
||
|
origins string
|
||
|
mongo *dal.MongoConnection
|
||
|
hl hlog.Logger
|
||
|
validator validator.Validator
|
||
|
}
|
||
|
|
||
|
type CommonOpts struct {
|
||
|
AllowedOrigins string
|
||
|
Mongo *dal.MongoConnection
|
||
|
Hl hlog.Logger
|
||
|
}
|
||
|
|
||
|
func NewHandler(
|
||
|
w http.ResponseWriter,
|
||
|
r *http.Request,
|
||
|
common CommonOpts,
|
||
|
validator validator.Validator) *Handler {
|
||
|
return &Handler{
|
||
|
w: w, r: r,
|
||
|
origins: common.AllowedOrigins,
|
||
|
mongo: common.Mongo,
|
||
|
hl: common.Hl,
|
||
|
validator: validator,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (h *Handler) Prepare(w http.ResponseWriter, r *http.Request, validator validator.Validator) {
|
||
|
h.w = w
|
||
|
h.r = r
|
||
|
h.validator = validator
|
||
|
}
|
||
|
|
||
|
func (h *Handler) getJwtUserId() (string, error) {
|
||
|
if jwtAdapter, ok := h.r.Context().Value("JWT").(*jwt_adapter.JwtAdapter); ok {
|
||
|
return jwtAdapter.GetUserID(), nil
|
||
|
}
|
||
|
return "", errors.New("no token in context")
|
||
|
}
|
||
|
|
||
|
// report Error - Send false Response with string error
|
||
|
func (h *Handler) reportError(status int, errClient string, errLog error) {
|
||
|
h.w.Header().Set("Access-Control-Allow-Origin", h.origins)
|
||
|
h.w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||
|
|
||
|
h.w.WriteHeader(status)
|
||
|
errEncode := json.NewEncoder(h.w).Encode(Response{false, errClient})
|
||
|
|
||
|
if errEncode != nil {
|
||
|
h.hl.Emit(ErrorReportCanNotSend{errEncode})
|
||
|
}
|
||
|
|
||
|
h.hl.Emit(ErrorHandler{h.r.URL.String(), errLog})
|
||
|
}
|
||
|
|
||
|
// send Response struct with http status 200
|
||
|
func (h *Handler) sendResponse(response Response) {
|
||
|
h.w.Header().Set("Access-Control-Allow-Origin", h.origins)
|
||
|
h.w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||
|
|
||
|
h.w.WriteHeader(http.StatusOK)
|
||
|
err := json.NewEncoder(h.w).Encode(response)
|
||
|
|
||
|
if err != nil {
|
||
|
h.reportError(http.StatusInternalServerError, "response failed", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// send response as sse
|
||
|
func (h *Handler) sendSseData(data interface{}, flusher http.Flusher) {
|
||
|
response, err := json.Marshal(data)
|
||
|
|
||
|
if err != nil {
|
||
|
h.reportError(http.StatusInternalServerError, "failed", err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
_, err = fmt.Fprintf(h.w, "data: %s\n\n", response)
|
||
|
flusher.Flush()
|
||
|
|
||
|
if err != nil {
|
||
|
h.reportError(http.StatusInternalServerError, "failed", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (h *Handler) handlePostRequest(request interface{}) error {
|
||
|
decoder := validator.Decoder{Decoder: json.NewDecoder(h.r.Body)}
|
||
|
err := decoder.DecodeAndValidate(request, h.validator)
|
||
|
if err != nil {
|
||
|
h.reportError(http.StatusBadRequest, err.Error(), err)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (h *Handler) handleGetRequest(request interface{}) error {
|
||
|
//query := query
|
||
|
err := h.r.ParseForm()
|
||
|
if err != nil {
|
||
|
h.reportError(http.StatusBadRequest, err.Error(), err)
|
||
|
return err
|
||
|
}
|
||
|
fmt.Println("DATAAAA",h.r.Form)
|
||
|
err = schema.NewDecoder().Decode(request, h.r.Form)
|
||
|
|
||
|
if err != nil {
|
||
|
h.reportError(http.StatusBadRequest, err.Error(), err)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
//#endregion
|
||
|
|
||
|
// MB Size constants
|
||
|
const (
|
||
|
MB = 1 << 20
|
||
|
)
|
||
|
|
||
|
//#region ======== Response Structs ========
|
||
|
|
||
|
type Response struct {
|
||
|
Success bool `json:"success"` // True if OK
|
||
|
Message interface{} `json:"message"` // Message Response body
|
||
|
}
|
||
|
|
||
|
//#endregion
|
||
|
|
||
|
//#region ======== Hl Handlers Errors ========
|
||
|
|
||
|
type ErrorReportCanNotSend struct {
|
||
|
Err error
|
||
|
}
|
||
|
|
||
|
type ErrorHandler struct {
|
||
|
URL string
|
||
|
Err error
|
||
|
}
|
||
|
|
||
|
//#endregion
|
||
|
|
||
|
//#region ======== Other functions ========
|
||
|
|
||
|
//#endregion
|