carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package release
2
3import (
4 "context"
5 "crypto/rand"
6 "encoding/hex"
7 "encoding/json"
8 "errors"
9 "time"
10)
11
12type ClaimPurgeRequest struct {
13 V int `json:"v"`
14 ID string `json:"id"`
15 AppID string `json:"app_id"`
16 Account string `json:"account"`
17 App string `json:"app"`
18 TombstoneKey string `json:"tombstone_key"`
19 TombstoneETag string `json:"tombstone_etag"`
20 Tombstone json.RawMessage `json:"tombstone"`
21}
22
23func RequestClaimAutoPurge(ctx context.Context, s Store, account, app string, now time.Time) error {
24 if !ValidAccount(account) || !ValidApp(app) {
25 return ErrNotTrashed
26 }
27 tomb, err := ReadAppTombstone(ctx, s, account, app)
28 if err != nil {
29 return err
30 }
31 if tomb == nil || now.Before(tomb.DeletedAt.Add(TrashCooloff)) {
32 return ErrNotTrashed
33 }
34 key := AppTombstoneKey(account, app)
35 body, tag, err := s.Get(ctx, key)
36 if err != nil {
37 return err
38 }
39 prefix := "apps/" + account + "/" + app + "/"
40 admission, _, err := s.Get(ctx, prefix+"admission.json")
41 if err != nil {
42 return err
43 }
44 var identity struct {
45 V int `json:"v"`
46 AppID string `json:"app_id"`
47 State string `json:"state"`
48 Op json.RawMessage `json:"op"`
49 }
50 if err = json.Unmarshal(admission, &identity); err != nil {
51 return err
52 }
53 if identity.V != 1 || identity.AppID == "" || tag == "" {
54 return ErrNotTrashed
55 }
56 if identity.State != "open" || (len(identity.Op) > 0 && string(identity.Op) != "null") {
57 return nil
58 }
59 var nonce [16]byte
60 if _, err = rand.Read(nonce[:]); err != nil {
61 return err
62 }
63 request := ClaimPurgeRequest{V: 1, ID: hex.EncodeToString(nonce[:]), AppID: identity.AppID, Account: account, App: app, TombstoneKey: key, TombstoneETag: tag, Tombstone: body}
64 raw, err := json.Marshal(request)
65 if err != nil {
66 return err
67 }
68 _, err = s.Put(ctx, prefix+"purge-request.json", raw, "")
69 if errors.Is(err, ErrCASConflict) {
70 return nil
71 }
72 return err
73}
74