Bootstrap copied BFF and local accounts with public Sendico contracts (#34)
This commit is contained in:
1 parent
67dc5b5b1e
commit
7062672a87
556 files changed
+42291
-777
No files matched your search
@@ -0,0 +1,84 @@
|
||||
package verification
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"git.sendico.io/tech/sxchnge/bff/pkg/db/repository"
|
||||
"git.sendico.io/tech/sxchnge/bff/pkg/db/repository/builder"
|
||||
"git.sendico.io/tech/sxchnge/bff/pkg/merrors"
|
||||
"git.sendico.io/tech/sxchnge/bff/pkg/model"
|
||||
mutil "git.sendico.io/tech/sxchnge/bff/pkg/mutil/db"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
func normalizedIdempotencyKey(value *string) (string, bool) {
|
||||
if value == nil {
|
||||
return "", false
|
||||
}
|
||||
key := strings.TrimSpace(*value)
|
||||
if key == "" {
|
||||
return "", false
|
||||
}
|
||||
return key, true
|
||||
}
|
||||
|
||||
func syntheticIdempotencyKey() string {
|
||||
return "auto:" + bson.NewObjectID().Hex()
|
||||
}
|
||||
|
||||
func idempotencyContextFilter(
|
||||
request *Request,
|
||||
idempotencyKey string,
|
||||
) builder.Query {
|
||||
return repository.Query().And(
|
||||
repository.Filter("accountRef", request.AccountRef),
|
||||
repository.Filter("purpose", request.Purpose),
|
||||
repository.Filter("target", request.Target),
|
||||
repository.Filter("idempotencyKey", idempotencyKey),
|
||||
)
|
||||
}
|
||||
|
||||
func idempotencySeed(request *Request, idempotencyKey string) string {
|
||||
return strings.Join([]string{
|
||||
request.AccountRef.Hex(),
|
||||
string(request.Purpose),
|
||||
request.Target,
|
||||
request.ContextRef,
|
||||
request.Kind,
|
||||
idempotencyKey,
|
||||
}, "|")
|
||||
}
|
||||
|
||||
func (db *verificationDB) lookupIdempotencyReplay(ctx context.Context, request *Request, idempotencyKey string) (*model.VerificationToken, bool, error) {
|
||||
tokens, err := mutil.GetObjects[model.VerificationToken](
|
||||
ctx,
|
||||
db.Logger,
|
||||
idempotencyContextFilter(request, idempotencyKey),
|
||||
nil,
|
||||
db.Repository,
|
||||
)
|
||||
switch {
|
||||
case err == nil:
|
||||
case errors.Is(err, merrors.ErrNoData):
|
||||
return nil, false, nil
|
||||
default:
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
var replayed *model.VerificationToken
|
||||
for i := range tokens {
|
||||
existingContextRef := strings.TrimSpace(tokens[i].ContextRef)
|
||||
// The lookup intentionally ignores contextRef. A reused idempotency key
|
||||
// in another context is a client conflict, not a replay.
|
||||
if existingContextRef != request.ContextRef {
|
||||
return nil, false, ErrorIdempotencyConflict()
|
||||
}
|
||||
if replayed == nil {
|
||||
token := tokens[i]
|
||||
replayed = &token
|
||||
}
|
||||
}
|
||||
return replayed, replayed != nil, nil
|
||||
}
|
||||
Reference in new issue
Block a user