package host import ( "context" "crypto/rand" "encoding/hex" "encoding/json" "errors" "github.com/carlosframework/platform/internal/rootparticipation" "os" ) type rootFloorAuthorization struct { Identity rootFloorIdentity Generation uint64 Nonce string } // Only an offline root caller with the checked private store may issue this // capability. No production caller is installed until migration has full history. func (f rootMovesFloors) authorizeReconstruction(ctx context.Context) (*rootFloorAuthorization, error) { unlock, err := f.private.Lock(ctx, "floor.lock") if err != nil { return nil, err } defer unlock() generation := uint64(1) old, err := f.record(rootFloorAccepted) if err == nil { generation = old.Generation + 1 } else if !errors.Is(err, os.ErrNotExist) { return nil, err } var nonce [32]byte if _, err := rand.Read(nonce[:]); err != nil { return nil, err } token := rootFloorAuthorization{Identity: f.identity, Generation: generation, Nonce: hex.EncodeToString(nonce[:])} raw, _ := json.Marshal(token) if err := f.private.Write("reconstruction-token.json", raw); err != nil { return nil, err } return &token, nil } func (f rootMovesFloors) authorizedReconstruction(token *rootFloorAuthorization, generation uint64) bool { if token == nil || token.Identity != f.identity || token.Generation != generation || len(token.Nonce) != 64 { return false } raw, err := f.private.Read("reconstruction-token.json") if err != nil { return false } var retained rootFloorAuthorization return rootparticipation.Decode(raw, &retained) == nil && retained == *token }