perf(oidc): optimize client verification (#6999)

* fix some spelling errors

* client credential auth

* implementation of client auth

* improve error handling

* unit test command package

* unit test database package

* unit test query package

* cleanup unused tracing func

* fix integration tests

* errz to zerrors

* fix linting and import issues

* fix another linting error

* integration test with client secret

* Revert "integration test with client secret"

This reverts commit 0814ba522f.

* add integration tests

* client credentials integration test

* resolve comments

* pin oidc v3.5.0
This commit is contained in:
Tim Möhlmann
2023-12-05 19:01:03 +02:00
committed by GitHub
parent 51cfb9564a
commit ec03340b67
46 changed files with 1666 additions and 781 deletions

View File

@@ -9,8 +9,11 @@ import (
"math/big"
"net/http"
"strconv"
"sync"
"time"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/api/authz"
api_http "github.com/zitadel/zitadel/internal/api/http"
"github.com/zitadel/zitadel/internal/command/preparation"
@@ -37,12 +40,15 @@ import (
usr_repo "github.com/zitadel/zitadel/internal/repository/user"
usr_grant_repo "github.com/zitadel/zitadel/internal/repository/usergrant"
"github.com/zitadel/zitadel/internal/static"
"github.com/zitadel/zitadel/internal/telemetry/tracing"
webauthn_helper "github.com/zitadel/zitadel/internal/webauthn"
)
type Commands struct {
httpClient *http.Client
jobs sync.WaitGroup
checkPermission domain.PermissionCheck
newCode cryptoCodeFunc
newCodeWithDefault cryptoCodeWithDefaultFunc
@@ -257,3 +263,54 @@ func samlCertificateAndKeyGenerator(keySize int) func(id string) ([]byte, []byte
return pem.EncodeToMemory(keyBlock), pem.EncodeToMemory(certBlock), nil
}
}
// Close blocks until all async jobs are finished,
// the context expires or after eventstore.PushTimeout.
func (c *Commands) Close(ctx context.Context) error {
if c.eventstore.PushTimeout != 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, c.eventstore.PushTimeout)
defer cancel()
}
done := make(chan struct{})
go func() {
c.jobs.Wait()
close(done)
}()
select {
case <-done:
return nil
case <-ctx.Done():
return ctx.Err()
}
}
// asyncPush attempts to push events to the eventstore in a separate Go routine.
// This can be used to speed up request times when the outcome of the push is
// not important for business logic but have a pure logging function.
// For example this can be used for Secret Check Success and Failed events.
// On push error, a log line describing the error will be emitted.
func (c *Commands) asyncPush(ctx context.Context, cmds ...eventstore.Command) {
// Create a new context, as the request scoped context might get
// canceled before we where able to push.
// The eventstore has its own PushTimeout setting,
// so we don't need to have a context with timeout here.
ctx = context.WithoutCancel(ctx)
c.jobs.Add(1)
go func() {
defer c.jobs.Done()
localCtx, span := tracing.NewSpan(ctx)
_, err := c.eventstore.Push(localCtx, cmds...)
if err != nil {
for _, cmd := range cmds {
logging.WithError(err).Errorf("could not push event %q", cmd.Type())
}
}
span.EndWithError(err)
}()
}