docxTemplater/middleware/middleware.go

210 lines
5.0 KiB
Go
Raw Normal View History

2022-07-28 15:00:43 +00:00
package middleware
import (
2022-08-10 13:53:34 +00:00
"amocrm_templategen_back/amo"
2022-07-28 15:00:43 +00:00
"amocrm_templategen_back/dal"
"context"
2022-08-10 13:53:34 +00:00
"encoding/json"
"errors"
2022-07-28 15:00:43 +00:00
"github.com/dgrijalva/jwt-go"
"go.uber.org/zap"
"net/http"
2022-08-10 13:53:34 +00:00
"strconv"
2022-07-28 15:00:43 +00:00
"strings"
)
var (
JwtSecret = []byte("my-secret-123")
)
type Middleware struct {
dal *dal.MongoDAL
2022-08-10 13:53:34 +00:00
amo *amo.ClientApp
2022-07-28 15:00:43 +00:00
logger *zap.Logger
}
type UserClaims struct {
2022-08-10 13:53:34 +00:00
UserID string
FullName string
Email string
IsActivated bool
2022-07-28 15:00:43 +00:00
jwt.StandardClaims
}
2022-08-10 13:53:34 +00:00
func InitMiddleware(dal *dal.MongoDAL, amo *amo.ClientApp, logger *zap.Logger) *Middleware {
return &Middleware{dal: dal, amo: amo, logger: logger}
}
func (mw *Middleware) MiddlewareCors(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
} else {
next.ServeHTTP(w, r)
}
})
2022-07-28 15:00:43 +00:00
}
func (mw *Middleware) Logger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.Contains(r.URL.String(), "/assets/") {
next.ServeHTTP(w, r)
return
}
userId := ""
user := getJwtUser(r)
if user != nil {
userId = user.UserID
}
mw.logger.Info("HttpRequest",
zap.String("URL", r.URL.String()),
zap.String("UserID", userId),
)
next.ServeHTTP(w, r)
})
}
func (mw *Middleware) MiddlewareJwt(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.Contains(r.URL.String(), "/assets/") {
next.ServeHTTP(w, r)
return
}
authMap := map[string]interface{}{
//"/amo": nil,
}
required := false
_, ok := authMap[r.URL.String()]
if ok {
required = true
}
// Check token in headers
tokenHeader := r.Header.Get("Authorization")
if tokenHeader == "" && required {
w.WriteHeader(http.StatusUnauthorized)
return
}
tokenHeader = strings.Replace(tokenHeader, "Bearer ", "", -1)
if tokenHeader != "" {
token, err := jwt.ParseWithClaims(tokenHeader, &UserClaims{}, func(tk *jwt.Token) (interface{}, error) {
return JwtSecret, nil
})
if err != nil {
mw.logger.Error("ErrJwtAccess", zap.Error(err))
}
if claims, ok := token.Claims.(*UserClaims); ok && token.Valid {
ctx := context.WithValue(r.Context(), "JWT", claims)
next.ServeHTTP(w, r.WithContext(ctx))
return
}
}
// Check token in cookies
c, err := r.Cookie("Authorization")
if err != nil {
if !required {
next.ServeHTTP(w, r)
} else {
2022-08-10 13:53:34 +00:00
mw.logger.Error("ErrJwtAccess", zap.Error(err))
2022-07-28 15:00:43 +00:00
w.WriteHeader(http.StatusUnauthorized)
}
return
}
tokenCookie := strings.Replace(c.Value, "Bearer ", "", -1)
token, err := jwt.ParseWithClaims(tokenCookie, &UserClaims{}, func(tk *jwt.Token) (interface{}, error) {
return JwtSecret, nil
})
if err != nil {
mw.logger.Error("ErrJwtAccess", zap.Error(err))
if !required {
next.ServeHTTP(w, r)
} else {
w.WriteHeader(http.StatusUnauthorized)
}
return
}
claims, ok := token.Claims.(*UserClaims)
if !ok || !token.Valid {
mw.logger.Error("ErrJwtAccess", zap.Error(err))
if !required {
next.ServeHTTP(w, r)
} else {
w.WriteHeader(http.StatusUnauthorized)
}
return
}
ctx := context.WithValue(r.Context(), "JWT", claims)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
2022-08-10 13:53:34 +00:00
func (mw *Middleware) MiddlewareHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, X-Auth-Token")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Expose-Headers", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE")
//w.Header().Add()
next.ServeHTTP(w, r)
})
}
func (mw *Middleware) MiddlewareAmoJwt(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.URL.String(), "/amo/") {
next.ServeHTTP(w, r)
return
}
token, err := mw.amo.DecodeJwt(r)
if err != nil {
mw.logger.Error("ErrAmoJwtAccess", zap.Error(err))
return
}
data, err := mw.dal.Amo.GetByAccountID(r.Context(), strconv.FormatInt(token.AccountId, 10))
if err != nil {
mw.reportError(w, err, http.StatusInternalServerError)
return
}
if data == nil {
mw.reportError(w, errors.New("amo account not found"), http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), "amoData", data)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
2022-07-28 15:00:43 +00:00
func getJwtUser(r *http.Request) *UserClaims {
user, ok := r.Context().Value("JWT").(*UserClaims)
if ok {
return user
}
return nil
}
2022-08-10 13:53:34 +00:00
func (mw *Middleware) reportError(w http.ResponseWriter, err error, status int) error {
mw.logger.Error("ErrorMiddleware", zap.Error(err))
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(status)
return json.NewEncoder(w).Encode(err)
}