feat(op): user slog for logging

integrate with golang.org/x/exp/slog for logging.
provide a middleware for request scoped logging.

BREAKING CHANGES:

1. OpenIDProvider and sub-interfaces get a Logger()
method to return the configured logger;
2. AuthRequestError now takes the complete Authorizer,
instead of only the encoder. So that it may use its Logger() method.
3. RequestError now takes a Logger as argument.
This commit is contained in:
Tim Möhlmann 2023-08-21 19:55:24 +02:00
parent 6708ef4c24
commit f30f0d3ead
22 changed files with 297 additions and 61 deletions

View file

@ -1,5 +1,11 @@
package oidc
import (
"fmt"
"golang.org/x/exp/slog"
)
const (
// ScopeOpenID defines the scope `openid`
// OpenID Connect requests MUST contain the `openid` scope value
@ -86,6 +92,15 @@ type AuthRequest struct {
RequestParam string `schema:"request"`
}
func (a *AuthRequest) LogValue() slog.Value {
return slog.GroupValue(
slog.Any("scopes", fmt.Stringer(a.Scopes)),
slog.String("response_type", string(a.ResponseType)),
slog.String("client_id", a.ClientID),
slog.String("redirect_uri", a.RedirectURI),
)
}
// GetRedirectURI returns the redirect_uri value for the ErrAuthRequest interface
func (a *AuthRequest) GetRedirectURI() string {
return a.RedirectURI

View file

@ -3,6 +3,8 @@ package oidc
import (
"errors"
"fmt"
"golang.org/x/exp/slog"
)
type errorType string
@ -171,3 +173,31 @@ func DefaultToServerError(err error, description string) *Error {
}
return oauth
}
func (e *Error) LogLevel() slog.Level {
level := slog.LevelWarn
if e.ErrorType == ServerError {
level = slog.LevelError
}
if e.ErrorType == AuthorizationPending {
level = slog.LevelInfo
}
return level
}
func (e *Error) LogValue() slog.Value {
attrs := make([]slog.Attr, 0, 4)
if e.Parent != nil {
attrs = append(attrs, slog.Any("parent", e.Parent))
}
if e.Description != "" {
attrs = append(attrs, slog.String("description", e.Description))
}
if e.ErrorType != "" {
attrs = append(attrs, slog.String("type", string(e.ErrorType)))
}
if e.State != "" {
attrs = append(attrs, slog.String("state", e.State))
}
return slog.GroupValue(attrs...)
}

View file

@ -106,7 +106,7 @@ type ResponseType string
type ResponseMode string
func (s SpaceDelimitedArray) Encode() string {
func (s SpaceDelimitedArray) String() string {
return strings.Join(s, " ")
}
@ -116,11 +116,11 @@ func (s *SpaceDelimitedArray) UnmarshalText(text []byte) error {
}
func (s SpaceDelimitedArray) MarshalText() ([]byte, error) {
return []byte(s.Encode()), nil
return []byte(s.String()), nil
}
func (s SpaceDelimitedArray) MarshalJSON() ([]byte, error) {
return json.Marshal((s).Encode())
return json.Marshal((s).String())
}
func (s *SpaceDelimitedArray) UnmarshalJSON(data []byte) error {
@ -165,7 +165,7 @@ func (s SpaceDelimitedArray) Value() (driver.Value, error) {
func NewEncoder() *schema.Encoder {
e := schema.NewEncoder()
e.RegisterEncoder(SpaceDelimitedArray{}, func(value reflect.Value) string {
return value.Interface().(SpaceDelimitedArray).Encode()
return value.Interface().(SpaceDelimitedArray).String()
})
return e
}