github.com/mundipagg/boleto-api@v0.0.0-20230620145841-3f9ec742599f/api/middlewares.go (about) 1 package api 2 3 import ( 4 "net/http" 5 "strconv" 6 "time" 7 8 "github.com/gin-gonic/gin" 9 "github.com/mundipagg/boleto-api/bank" 10 "github.com/mundipagg/boleto-api/log" 11 "github.com/mundipagg/boleto-api/metrics" 12 "github.com/mundipagg/boleto-api/models" 13 "github.com/mundipagg/boleto-api/usermanagement" 14 ) 15 16 const ( 17 boletoKey = "boleto" 18 bankKey = "bank" 19 serviceUserKey = "serviceuser" 20 responseKey = "boletoResponse" 21 ) 22 23 func returnHeaders() gin.HandlerFunc { 24 return func(c *gin.Context) { 25 c.Header("Content-Type", "application/json") 26 c.Next() 27 } 28 } 29 30 //parseBoleto Middleware de tratamento do request de registro de boleto 31 func parseBoleto(c *gin.Context) { 32 var ok bool 33 var boleto models.BoletoRequest 34 var bank bank.Bank 35 36 if boleto, ok = getBoletoRequest(c); !ok { 37 return 38 } 39 40 if bank, ok = getBank(c, boleto); !ok { 41 return 42 } 43 44 if !parseExpirationDate(c, &boleto, bank) { 45 return 46 } 47 48 c.Set(boletoKey, boleto) 49 c.Set(bankKey, bank) 50 } 51 52 //authentication Middleware de autenticação para registro de boleto 53 func authentication(c *gin.Context) { 54 55 cred := getHeaderCredentials(c) 56 57 if cred == nil { 58 c.AbortWithStatusJSON(401, models.GetBoletoResponseError("MP401", "Unauthorized")) 59 return 60 } 61 62 if !hasValidCredentials(cred) { 63 c.AbortWithStatusJSON(401, models.GetBoletoResponseError("MP401", "Unauthorized")) 64 return 65 } 66 67 c.Set(serviceUserKey, cred.Username) 68 } 69 70 //checkError Middleware de verificação de erros 71 func checkError(c *gin.Context, err error, l *log.Log) bool { 72 73 if err != nil { 74 errResp := models.BoletoResponse{ 75 Errors: models.NewErrors(), 76 } 77 78 switch v := err.(type) { 79 80 case models.ErrorResponse: 81 errResp.Errors.Append(v.ErrorCode(), v.Error()) 82 c.JSON(http.StatusBadRequest, errResp) 83 84 case models.HttpNotFound: 85 errResp.Errors.Append("MP404", v.Error()) 86 l.Warn(errResp, v.Error()) 87 c.JSON(http.StatusNotFound, errResp) 88 89 case models.InternalServerError: 90 errResp.Errors.Append("MP500", v.Error()) 91 l.Warn(errResp, v.Error()) 92 c.JSON(http.StatusInternalServerError, errResp) 93 94 case models.BadGatewayError: 95 errResp.Errors.Append("MP502", v.Error()) 96 l.Warn(errResp, v.Error()) 97 c.JSON(http.StatusBadGateway, errResp) 98 99 case models.FormatError: 100 errResp.Errors.Append("MP400", v.Error()) 101 l.Warn(errResp, v.Error()) 102 c.JSON(http.StatusBadRequest, errResp) 103 104 default: 105 errResp.Errors.Append("MP500", "Internal Error") 106 l.Fatal(errResp, v.Error()) 107 c.JSON(http.StatusInternalServerError, errResp) 108 } 109 110 c.Set("boletoResponse", errResp) 111 return true 112 } 113 return false 114 } 115 116 func hasValidCredentials(c *models.Credentials) bool { 117 u, hasUser := usermanagement.GetUser(c.UserKey) 118 119 if !hasUser { 120 return false 121 } 122 123 user := u.(models.Credentials) 124 125 if user.UserKey == c.UserKey && user.Password == c.Password { 126 c.Username = user.Username 127 return true 128 } 129 130 return false 131 } 132 133 func getHeaderCredentials(c *gin.Context) *models.Credentials { 134 userkey, pass, hasAuth := c.Request.BasicAuth() 135 if userkey == "" || pass == "" || !hasAuth { 136 return nil 137 } 138 return models.NewCredentials(userkey, pass) 139 } 140 141 func getBoletoRequest(c *gin.Context) (models.BoletoRequest, bool) { 142 boleto := models.BoletoRequest{} 143 errBind := c.BindJSON(&boleto) 144 if errBind != nil { 145 e := models.NewFormatError(errBind.Error()) 146 checkError(c, e, log.CreateLog()) 147 return boleto, false 148 } 149 return boleto, true 150 } 151 152 func getBank(c *gin.Context, boleto models.BoletoRequest) (bank.Bank, bool) { 153 bank, err := bank.Get(boleto) 154 if checkError(c, err, log.CreateLog()) { 155 c.Set("error", err) 156 return bank, false 157 } 158 return bank, true 159 } 160 161 func parseExpirationDate(c *gin.Context, boleto *models.BoletoRequest, bank bank.Bank) bool { 162 d, errFmt := time.Parse("2006-01-02", boleto.Title.ExpireDate) 163 boleto.Title.ExpireDateTime = d 164 if errFmt != nil { 165 e := models.NewFormatError(errFmt.Error()) 166 checkError(c, e, log.CreateLog()) 167 metrics.PushBusinessMetric(bank.GetBankNameIntegration()+"-bad-request", 1) 168 return false 169 } 170 return true 171 } 172 173 func getBoletoFromContext(c *gin.Context) models.BoletoRequest { 174 if boleto, exists := c.Get(boletoKey); exists { 175 return boleto.(models.BoletoRequest) 176 } 177 return models.BoletoRequest{} 178 } 179 180 func getBankFromContext(c *gin.Context) bank.Bank { 181 if banking, exists := c.Get(bankKey); exists { 182 return banking.(bank.Bank) 183 } 184 return nil 185 } 186 187 func getUserFromContext(c *gin.Context) string { 188 if user, exists := c.Get(serviceUserKey); exists { 189 return user.(string) 190 } 191 return "" 192 } 193 194 func getResponseFromContext(c *gin.Context) models.BoletoResponse { 195 if response, exists := c.Get(responseKey); exists { 196 return response.(models.BoletoResponse) 197 } 198 return models.BoletoResponse{} 199 } 200 201 func getNossoNumeroFromContext(c *gin.Context) string { 202 if respOurNumber := getResponseFromContext(c).OurNumber; respOurNumber != "" { 203 return respOurNumber 204 } 205 206 return strconv.FormatUint(uint64(getBoletoFromContext(c).Title.OurNumber), 10) 207 }