Skip to content

Commit

Permalink
Set propel log level
Browse files Browse the repository at this point in the history
Signed-off-by: AndreyM <[email protected]>
  • Loading branch information
AndreyM committed Jun 1, 2023
1 parent f66cf6c commit 2a8bcca
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 10 deletions.
3 changes: 2 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/mysteriumnetwork/discovery/health"
"github.com/mysteriumnetwork/discovery/listener"
"github.com/mysteriumnetwork/discovery/location"
"github.com/mysteriumnetwork/discovery/middleware"
"github.com/mysteriumnetwork/discovery/proposal"
"github.com/mysteriumnetwork/discovery/quality"
"github.com/mysteriumnetwork/discovery/quality/oracleapi"
Expand All @@ -46,7 +47,7 @@ func main() {

r := gin.New()
r.Use(gin.Recovery())
r.Use(mlog.GinLogFunc())
r.Use(middleware.Logger)
r.Use(apierror.ErrorHandler)

r.GET("/", func(c *gin.Context) {
Expand Down
6 changes: 3 additions & 3 deletions cmd/pricer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import (

"github.com/mysteriumnetwork/discovery/config"
_ "github.com/mysteriumnetwork/discovery/docs"
"github.com/mysteriumnetwork/discovery/middleware"
"github.com/mysteriumnetwork/discovery/price"
"github.com/mysteriumnetwork/discovery/price/pricing"
"github.com/mysteriumnetwork/discovery/price/pricingbyservice"
"github.com/mysteriumnetwork/discovery/token"
"github.com/mysteriumnetwork/go-rest/apierror"
mlog "github.com/mysteriumnetwork/logger"
)
Expand All @@ -41,7 +41,7 @@ func main() {

r := gin.New()
r.Use(gin.Recovery())
r.Use(mlog.GinLogFunc())
r.Use(middleware.Logger)
r.Use(apierror.ErrorHandler)

rdb := redis.NewUniversalClient(&redis.UniversalOptions{
Expand Down Expand Up @@ -82,7 +82,7 @@ func main() {
log.Fatal().Err(err).Msg("failed to initialize price getter by service")
}

ac := token.NewJWTChecker(cfg.SentinelURL, cfg.UniverseJWTSecret)
ac := middleware.NewJWTChecker(cfg.SentinelURL, cfg.UniverseJWTSecret)
price.NewAPI(getter, cfger, ac).RegisterRoutes(v3)
price.NewAPIByService(rdb, getterByService, cfgerByService, ac).RegisterRoutes(v4)

Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ require (
github.com/gin-contrib/pprof v1.4.0
github.com/gin-gonic/gin v1.9.0
github.com/go-redis/redis/v8 v8.11.5
github.com/golang-jwt/jwt/v4 v4.4.2
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/magefile/mage v1.15.0
github.com/mysteriumnetwork/go-ci v0.0.0-20220711082519-1245471bae0d
github.com/mysteriumnetwork/go-rest v0.3.1
github.com/mysteriumnetwork/logger v0.0.6
github.com/mysteriumnetwork/payments v1.0.1-0.20230504074308-b9ebd048323b
github.com/mysteriumnetwork/token v0.0.0-20220908135716-cb1018afc778
github.com/mysteriumnetwork/token v0.0.0-20230103110440-8c69bf40ce61
github.com/nats-io/nats.go v1.26.0
github.com/prometheus/client_golang v1.15.1
github.com/rs/zerolog v1.29.1
Expand Down Expand Up @@ -51,6 +51,7 @@ require (
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/jellydator/ttlcache/v2 v2.11.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
Expand All @@ -140,6 +142,7 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
Expand Down Expand Up @@ -218,6 +221,8 @@ github.com/mysteriumnetwork/payments v1.0.1-0.20230504074308-b9ebd048323b h1:Huo
github.com/mysteriumnetwork/payments v1.0.1-0.20230504074308-b9ebd048323b/go.mod h1:uItkmTtDf7PGDd49UHZAXFQANkggyd8IGfDk4vJGChg=
github.com/mysteriumnetwork/token v0.0.0-20220908135716-cb1018afc778 h1:WXnxa4DXW170tywQbdP1o8JOx+Jb/ZIVIslzZd8R/TM=
github.com/mysteriumnetwork/token v0.0.0-20220908135716-cb1018afc778/go.mod h1:vzr+hlS28JI9q0N3Dv5dEZJZQoExboUsCD0P6IdoCGo=
github.com/mysteriumnetwork/token v0.0.0-20230103110440-8c69bf40ce61 h1:vKdCjLKi4ZTh+NxDRnZLatqe9burYTPhyGIieMbBSeo=
github.com/mysteriumnetwork/token v0.0.0-20230103110440-8c69bf40ce61/go.mod h1:vzr+hlS28JI9q0N3Dv5dEZJZQoExboUsCD0P6IdoCGo=
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
github.com/nats-io/jwt v0.3.3-0.20200519195258-f2bf5ce574c7/go.mod h1:n3cvmLfBfnpV4JJRN7lRYCyZnw48ksGsbThGXEk4w9M=
github.com/nats-io/jwt v1.1.0/go.mod h1:n3cvmLfBfnpV4JJRN7lRYCyZnw48ksGsbThGXEk4w9M=
Expand Down
179 changes: 179 additions & 0 deletions middleware/jwt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package middleware

import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"strings"
"time"

"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v4"
"github.com/mysteriumnetwork/token"
"github.com/rs/zerolog/log"
"io"
)

const discoveryAudienceName = "discovery"

type JWTChecker struct {
SentinelURL string
Secret string

publicKey []byte
}

func NewJWTChecker(sentinelURL, oldjwtSecret string) *JWTChecker {
return &JWTChecker{
SentinelURL: sentinelURL,
Secret: oldjwtSecret,
}
}

// JWTAuthorized is a temporary hack to support BOTH new and old ways to authorize with a token.
// TODO: Eventually this should be fixed and only a single authorization method should be left
// which would be the sentinel auth. The struct could also then be removed and replaced with
// a simple middleware func.
func (j *JWTChecker) JWTAuthorized() func(*gin.Context) {
return func(c *gin.Context) {
authHeader := strings.Split(c.Request.Header.Get("Authorization"), "Bearer ")
if len(authHeader) != 2 {
c.AbortWithStatusJSON(
http.StatusUnauthorized,
map[string]string{
"error": "Malformed Token",
},
)
return
}

jwtToken := authHeader[1]
if err := j.newCheck(jwtToken); err != nil {
log.Warn().Err(err).Msg("new jwt check failed")
if err := j.oldCheck(jwtToken); err != nil {
c.AbortWithStatusJSON(
http.StatusUnauthorized,
map[string]string{
"error": err.Error(),
},
)
return
} else {
log.Warn().Msg("old jwt token used")
}
}

c.Next()
}
}

type PublicKey struct {
Key string `json:"key_base64"`
}

func (j *JWTChecker) getPublicKey() ([]byte, error) {
if len(j.publicKey) > 0 {
return j.publicKey, nil
}
c := http.Client{Timeout: time.Second * 30}
resp, err := c.Get(fmt.Sprintf("%s/api/v1/auth/public/key", strings.TrimSuffix(j.SentinelURL, "/")))
if err != nil {
return nil, err
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("could not read response body: %w", err)
}

var pb PublicKey
if err = json.Unmarshal(body, &pb); err != nil {
return nil, fmt.Errorf("could not unmarshal response body: %w", err)
}

got, err := base64.StdEncoding.DecodeString(pb.Key)
if err != nil {
return nil, err
}
j.publicKey = got

return j.publicKey, nil
}

type Token struct {
Token string `json:"token"`
}

func (j *JWTChecker) valid(jwtToken string) (bool, error) {
c := http.Client{Timeout: time.Second * 30}

tokenBody, err := json.Marshal(
Token{Token: jwtToken},
)
if err != nil {
return false, err
}
resp, err := c.Post(fmt.Sprintf("%s/api/v1/token/validate", strings.TrimSuffix(j.SentinelURL, "/")), "application/json", body(string(tokenBody)))
if err != nil {
return false, err
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
return true, nil
}
if resp.StatusCode < 500 {
return false, nil
}

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, nil
}
log.Error().Str("response", string(body)).Msg("failed to validate token: error response from validation server")
return false, errors.New("failed to validate token: error response from validation server")
}

func (j *JWTChecker) newCheck(jtoken string) error {
if valid, err := j.valid(jtoken); err != nil {
return err
} else if !valid {
return errors.New("token invalid")
}

key, err := j.getPublicKey()
if err != nil {
return err
}

return token.NewValidatorJWT(key).ValidateForAudience(jtoken, discoveryAudienceName)
}

func (j *JWTChecker) oldCheck(jtoken string) error {
token, err := jwt.Parse(jtoken, func(token *jwt.Token) (any, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return []byte(j.Secret), nil
})
if err != nil {
return errors.New("unauthorized")
}

if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
if !claims.VerifyExpiresAt(time.Now().Unix(), true) {
return errors.New("expired")
}
return nil

}

return errors.New("token invalid")
}

func body(in string) io.Reader {
return strings.NewReader(in)
}
38 changes: 38 additions & 0 deletions middleware/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package middleware

import (
"time"

"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
)

func Logger(c *gin.Context) {
t := time.Now().UTC()
// before request
path := c.Request.URL.Path
raw := c.Request.URL.RawQuery
if raw != "" {
path = path + "?" + raw
}
c.Next()

statusCode := c.Writer.Status()
f := map[string]any{
"status_code": statusCode,
"method": c.Request.Method,
"path": path,
"latency": time.Since(t).Seconds(),
"clientIP": c.ClientIP(),
}

msg := "API Request"
switch {
case statusCode >= 400 && statusCode < 500:
log.Debug().Fields(f).Msg(msg)
case statusCode >= 500:
log.Error().Fields(f).Msg(msg)
default:
log.Debug().Fields(f).Msg(msg)
}
}
2 changes: 1 addition & 1 deletion price/pricing/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (m *Market) fetchPricing() (float64, error) {
for _, v := range m.apis {
resp, err := v.GetRateCacheWithFallback([]exchange.Coin{exchange.CoinMYST}, []exchange.Currency{exchange.CurrencyUSD})
if err != nil {
log.Warn().Err(err).Msg("could not load pricing info")
log.Error().Err(err).Msg("could not load pricing info")
continue
}

Expand Down
2 changes: 1 addition & 1 deletion proposal/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (a *API) populateCountryMiddleware() func(c *gin.Context) {
}
if err != nil {
from = "NL"
log.Warn().Err(err).Msg("Failed to autodetect client country")
log.Error().Err(err).Msg("Failed to autodetect client country")
}
c.Request = c.Request.WithContext(
context.WithValue(c.Request.Context(), ctxCountryKey{}, from))
Expand Down
2 changes: 1 addition & 1 deletion proposal/metrics/enhancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type OracleResponses struct {
func (or *OracleResponses) Load(qualityService *quality.Service, fromCountry string) {
qRes, err := qualityService.Quality(fromCountry)
if err != nil {
log.Warn().Err(err).Msgf("Could not fetch quality for consumer (country=%s)", fromCountry)
log.Error().Err(err).Msgf("Could not fetch quality for consumer (country=%s)", fromCountry)
}
or.QualityResponse = qRes
}
Expand Down
2 changes: 1 addition & 1 deletion tags/tag_enhancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func NewEnhancer(tagAPI tagAPI) *Enhancer {
func (e *Enhancer) Enhance(proposal *v3.Proposal) {
tags, err := e.tagAPI.GetTags(proposal.ProviderID)
if err != nil {
log.Warn().Err(err).Str("providerID", proposal.ProviderID).Msg("could not get tags")
log.Error().Err(err).Str("providerID", proposal.ProviderID).Msg("could not get tags")
return
}

Expand Down

0 comments on commit 2a8bcca

Please sign in to comment.