Download this file
| 1 | package host |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "crypto/rand" |
| 6 | "encoding/hex" |
| 7 | "encoding/json" |
| 8 | "errors" |
| 9 | "github.com/carlosframework/platform/internal/rootparticipation" |
| 10 | "os" |
| 11 | ) |
| 12 | |
| 13 | type rootFloorAuthorization struct { |
| 14 | Identity rootFloorIdentity |
| 15 | Generation uint64 |
| 16 | Nonce string |
| 17 | } |
| 18 | |
| 19 | // Only an offline root caller with the checked private store may issue this |
| 20 | // capability. No production caller is installed until migration has full history. |
| 21 | func (f rootMovesFloors) authorizeReconstruction(ctx context.Context) (*rootFloorAuthorization, error) { |
| 22 | unlock, err := f.private.Lock(ctx, "floor.lock") |
| 23 | if err != nil { |
| 24 | return nil, err |
| 25 | } |
| 26 | defer unlock() |
| 27 | generation := uint64(1) |
| 28 | old, err := f.record(rootFloorAccepted) |
| 29 | if err == nil { |
| 30 | generation = old.Generation + 1 |
| 31 | } else if !errors.Is(err, os.ErrNotExist) { |
| 32 | return nil, err |
| 33 | } |
| 34 | var nonce [32]byte |
| 35 | if _, err := rand.Read(nonce[:]); err != nil { |
| 36 | return nil, err |
| 37 | } |
| 38 | token := rootFloorAuthorization{Identity: f.identity, Generation: generation, Nonce: hex.EncodeToString(nonce[:])} |
| 39 | raw, _ := json.Marshal(token) |
| 40 | if err := f.private.Write("reconstruction-token.json", raw); err != nil { |
| 41 | return nil, err |
| 42 | } |
| 43 | return &token, nil |
| 44 | } |
| 45 | func (f rootMovesFloors) authorizedReconstruction(token *rootFloorAuthorization, generation uint64) bool { |
| 46 | if token == nil || token.Identity != f.identity || token.Generation != generation || len(token.Nonce) != 64 { |
| 47 | return false |
| 48 | } |
| 49 | raw, err := f.private.Read("reconstruction-token.json") |
| 50 | if err != nil { |
| 51 | return false |
| 52 | } |
| 53 | var retained rootFloorAuthorization |
| 54 | return rootparticipation.Decode(raw, &retained) == nil && retained == *token |
| 55 | } |
| 56 | |