fix(authz): retry search memberships if no memberships found (#2869)

This commit is contained in:
Silvan 2021-12-17 16:28:41 +01:00 committed by GitHub
parent 57368d151b
commit 278a278a5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 120 additions and 9 deletions

View File

@ -2,7 +2,6 @@ package authz
import (
"context"
"time"
"github.com/caos/zitadel/internal/api/grpc"
http_util "github.com/caos/zitadel/internal/api/http"
@ -84,13 +83,9 @@ func VerifyTokenAndCreateCtxData(ctx context.Context, token, orgID string, t *To
err = t.ExistsOrg(ctx, orgID)
if err != nil {
for i := 0; i < 3; i++ { //TODO: workaround if org projection is not yet up-to-date
time.Sleep(500 * time.Millisecond)
err := t.ExistsOrg(ctx, orgID)
if err == nil {
break
}
}
err = retry(func() error {
return t.ExistsOrg(ctx, orgID)
})
if err != nil {
return CtxData{}, errors.ThrowPermissionDenied(nil, "AUTH-Bs7Ds", "Organisation doesn't exist")
}

View File

@ -2,6 +2,7 @@ package authz
import (
"context"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/telemetry/tracing"
)
@ -20,7 +21,19 @@ func getUserMethodPermissions(ctx context.Context, t *TokenVerifier, requiredPer
return nil, nil, err
}
if len(memberships) == 0 {
return requestedPermissions, nil, nil
err = retry(func() error {
memberships, err = t.SearchMyMemberships(ctx)
if err != nil {
return err
}
if len(memberships) == 0 {
return errors.ThrowNotFound(nil, "AUTHZ-cdgFk", "membership not found")
}
return nil
})
if err != nil {
return nil, nil, nil
}
}
requestedPermissions, allPermissions = mapMembershipsToPermissions(requiredPerm, memberships, authConfig)
return requestedPermissions, allPermissions, nil

View File

@ -0,0 +1,15 @@
package authz
import "time"
//TODO: workaround if org projection is not yet up-to-date
func retry(retriable func() error) (err error) {
for i := 0; i < 3; i++ {
time.Sleep(500 * time.Millisecond)
err = retriable()
if err == nil {
return nil
}
}
return err
}

View File

@ -0,0 +1,88 @@
package authz
import (
"errors"
"testing"
)
func Test_retry(t *testing.T) {
type args struct {
retriable func(*int) func() error
}
type want struct {
executions int
err bool
}
tests := []struct {
name string
args args
want want
}{
{
name: "1 execution",
args: args{
retriable: func(execs *int) func() error {
return func() error {
if *execs < 1 {
*execs++
return errors.New("not 1")
}
return nil
}
},
},
want: want{
err: false,
executions: 1,
},
},
{
name: "2 execution",
args: args{
retriable: func(execs *int) func() error {
return func() error {
if *execs < 2 {
*execs++
return errors.New("not 2")
}
return nil
}
},
},
want: want{
err: false,
executions: 2,
},
},
{
name: "too many execution",
args: args{
retriable: func(execs *int) func() error {
return func() error {
if *execs < 3 {
*execs++
return errors.New("not 3")
}
return nil
}
},
},
want: want{
err: true,
executions: 3,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var execs int
if err := retry(tt.args.retriable(&execs)); (err != nil) != tt.want.err {
t.Errorf("retry() error = %v, want.err %v", err, tt.want.err)
}
if execs != tt.want.executions {
t.Errorf("retry() executions: want: %d got: %d", tt.want.executions, execs)
}
})
}
}