Skip to content

Commit

Permalink
fix: Middleware logging
Browse files Browse the repository at this point in the history
Signed-off-by: jay-dee7 <[email protected]>
  • Loading branch information
jay-dee7 committed Nov 25, 2023
1 parent 99576d8 commit 53c8731
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 24 deletions.
12 changes: 10 additions & 2 deletions auth/basic_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,22 @@ func (a *auth) SkipBasicAuth(ctx echo.Context) bool {

// if Authorization header contains JWT, we skip basic auth and perform a JWT validation
if ok := a.checkJWT(authHeader, ctx.Request().Cookies()); ok {
a.logger.Debug().Bool("skip_basic_auth", true).Str("method", ctx.Request().Method).Str("path", ctx.Request().URL.RequestURI()).Send()
a.logger.Debug().
Bool("skip_basic_auth", true).
Str("method", ctx.Request().Method).
Str("path", ctx.Request().URL.RequestURI()).
Send()
return true
}

readOp := ctx.Request().Method == http.MethodHead || ctx.Request().Method == http.MethodGet
// if it's a read operation on a public repository, we skip auth requirement
if readOp && repo != nil && repo.Visibility == types.RepositoryVisibilityPublic {
a.logger.Debug().Bool("skip_basic_auth", true).Str("method", ctx.Request().Method).Str("path", ctx.Request().URL.RequestURI()).Send()
a.logger.Debug().
Bool("skip_basic_auth", true).
Str("method", ctx.Request().Method).
Str("path", ctx.Request().URL.RequestURI()).
Send()
return true
}

Expand Down
6 changes: 5 additions & 1 deletion auth/jwt_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ func (a *auth) JWT() echo.MiddlewareFunc {

skip := readOp && repo.Visibility == types.RepositoryVisibilityPublic
if skip {
a.logger.Debug().Bool("skip_jwt_middleware", true).Str("method", ctx.Request().Method).Str("path", ctx.Request().URL.RequestURI()).Send()
a.logger.Debug().
Bool("skip_jwt_middleware", true).
Str("method", ctx.Request().Method).
Str("path", ctx.Request().URL.RequestURI()).
Send()
}

return skip
Expand Down
39 changes: 29 additions & 10 deletions auth/oci_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ func (a *auth) Token(ctx echo.Context) error {

scopes, err := ParseOCITokenPermissionRequest(ctx.Request().URL)
if err != nil {
echoErr := ctx.JSON(http.StatusBadRequest, echo.Map{
"error": err.Error(),
"message": "invalid scope provided",
registryErr := common.RegistryErrorResponse(registry.RegistryErrorCodeUnknown, "invalid scope provided", echo.Map{
"error": err.Error(),
})
a.logger.Log(ctx, err).Send()
echoErr := ctx.JSONBlob(http.StatusBadRequest, registryErr.Bytes())
a.logger.Log(ctx, registryErr).Send()
return echoErr
}

Expand All @@ -141,9 +141,16 @@ func (a *auth) Token(ctx echo.Context) error {
if isPullRequest {
repo, repoErr := a.registryStore.GetRepositoryByNamespace(ctx.Request().Context(), scopes[0].Name)
if repoErr != nil {
common.RegistryErrorResponse(registry.RegistryErrorCodeNameInvalid, "requested resource does not exist on the registry", echo.Map{
"error": repoErr.Error(),
})
registryErr := common.RegistryErrorResponse(
registry.RegistryErrorCodeNameInvalid,
"requested resource does not exist on the registry",
echo.Map{
"error": repoErr.Error(),
},
)
echoErr := ctx.JSONBlob(http.StatusBadRequest, registryErr.Bytes())
a.logger.Log(ctx, registryErr).Send()
return echoErr
}

if repo.Visibility == types.RepositoryVisibilityPublic {
Expand All @@ -163,7 +170,14 @@ func (a *auth) Token(ctx echo.Context) error {
if authHeader != "" && len(scopes) != 0 {
token, authErr := a.tryBasicAuthFlow(ctx, scopes)
if authErr != nil {
echoErr := ctx.NoContent(http.StatusUnauthorized)
registryErr := common.RegistryErrorResponse(
registry.RegistryErrorCodeUnauthorized,
"authentication failed",
echo.Map{
"error": authErr.Error(),
},
)
echoErr := ctx.JSONBlob(http.StatusUnauthorized, registryErr.Bytes())
a.logger.Log(ctx, authErr).Send()
return echoErr
}
Expand All @@ -177,8 +191,13 @@ func (a *auth) Token(ctx echo.Context) error {
return echoErr
}

err = ctx.NoContent(http.StatusUnauthorized)
a.logger.Log(ctx, err).Send()
registryErr := common.RegistryErrorResponse(
registry.RegistryErrorCodeUnauthorized,
"authentication failed",
nil,
)
err = ctx.JSONBlob(http.StatusUnauthorized, registryErr.Bytes())
a.logger.Log(ctx, registryErr).Send()
return err
}

Expand Down
14 changes: 12 additions & 2 deletions auth/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,18 @@ func (a *auth) populateUserFromPermissionsCheck(ctx echo.Context) error {
func (a *auth) RepositoryPermissionsMiddleware() echo.MiddlewareFunc {
return func(handler echo.HandlerFunc) echo.HandlerFunc {
return func(ctx echo.Context) error {
a.populateUserFromPermissionsCheck(ctx)
a.populateUserFromPermissionsCheck(ctx)
if err := a.populateUserFromPermissionsCheck(ctx); err != nil {
registryErr := common.RegistryErrorResponse(
registry.RegistryErrorCodeDenied,
"invalid user credentials",
echo.Map{
"error": err.Error(),
},
)
echoErr := ctx.JSONBlob(http.StatusBadRequest, registryErr.Bytes())
a.logger.Log(ctx, err).Send()
return echoErr
}
// handle skipping scenarios
if ctx.QueryParam("offline_token") == "true" {
a.logger.Log(ctx, nil).Bool("skipping_middleware", true).Str("request_type", "offline_token").Send()
Expand Down
30 changes: 21 additions & 9 deletions router/middlewares.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ func registryNamespaceValidator(logger telemetry.Logger) echo.MiddlewareFunc {

namespace := username + "/" + imageName
if username == "" || imageName == "" || !nsRegex.MatchString(namespace) {
registryErr := common.RegistryErrorResponse(registry.RegistryErrorCodeNameInvalid, "invalid user namespace", echo.Map{
"error": "the required format for namespace is <username>/<imagename>",
})
registryErr := common.RegistryErrorResponse(
registry.RegistryErrorCodeNameInvalid,
"invalid user namespace",
echo.Map{
"error": "the required format for namespace is <username>/<imagename>",
},
)
echoErr := ctx.JSONBlob(http.StatusBadRequest, registryErr.Bytes())
logger.Log(ctx, echoErr).Send()
return echoErr
Expand All @@ -47,9 +51,13 @@ func registryReferenceOrTagValidator(logger telemetry.Logger) echo.MiddlewareFun
ref := ctx.Param("reference")

if ref != "" && !refRegex.MatchString(ref) {
registryErr := common.RegistryErrorResponse(registry.RegistryErrorCodeTagInvalid, "reference/tag does not match the required format", echo.Map{
"error": fmt.Sprintf("reference/tag must match the following regex: %s", refRegex.String()),
})
registryErr := common.RegistryErrorResponse(
registry.RegistryErrorCodeTagInvalid,
"reference/tag does not match the required format",
echo.Map{
"error": fmt.Sprintf("reference/tag must match the following regex: %s", refRegex.String()),
},
)

echoErr := ctx.JSONBlob(http.StatusBadRequest, registryErr.Bytes())
logger.Log(ctx, registryErr).Send()
Expand All @@ -68,9 +76,13 @@ func progagatRepository(store registry_store.RegistryStore, logger telemetry.Log

user, ok := ctx.Get(string(types.UserContextKey)).(*types.User)
if !ok {
registryErr := common.RegistryErrorResponse(registry.RegistryErrorCodeUnauthorized, "Unauthorized", echo.Map{
"error": "User is not found in request context",
})
registryErr := common.RegistryErrorResponse(
registry.RegistryErrorCodeUnauthorized,
"Unauthorized",
echo.Map{
"error": "User is not found in request context",
},
)
echoErr := ctx.JSONBlob(http.StatusBadRequest, registryErr.Bytes())
logger.Log(ctx, registryErr).Send()
return echoErr
Expand Down

0 comments on commit 53c8731

Please sign in to comment.