-
Notifications
You must be signed in to change notification settings - Fork 2
/
document_store.go
152 lines (124 loc) · 4.14 KB
/
document_store.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package app
import (
"context"
"errors"
"time"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"github.com/ministryofjustice/opg-modernising-lpa/internal/actor"
"github.com/ministryofjustice/opg-modernising-lpa/internal/dynamo"
"github.com/ministryofjustice/opg-modernising-lpa/internal/event"
"github.com/ministryofjustice/opg-modernising-lpa/internal/page"
)
type documentStore struct {
dynamoClient DynamoClient
s3Client S3Client
eventClient EventClient
randomUUID func() string
now func() time.Time
}
func NewDocumentStore(dynamoClient DynamoClient, s3Client S3Client, eventClient EventClient, randomUUID func() string, now func() time.Time) *documentStore {
return &documentStore{
dynamoClient: dynamoClient,
s3Client: s3Client,
eventClient: eventClient,
randomUUID: randomUUID,
now: now,
}
}
func (s *documentStore) Create(ctx context.Context, donor *actor.DonorProvidedDetails, filename string, data []byte) (page.Document, error) {
key := donor.LpaUID + "/evidence/" + s.randomUUID()
document := page.Document{
PK: dynamo.LpaKey(donor.LpaID),
SK: dynamo.DocumentKey(key),
Filename: filename,
Key: key,
Uploaded: s.now(),
}
if err := s.s3Client.PutObject(ctx, document.Key, data); err != nil {
return page.Document{}, err
}
if err := s.dynamoClient.Create(ctx, document); err != nil {
return page.Document{}, err
}
return document, nil
}
func (s *documentStore) GetAll(ctx context.Context) (page.Documents, error) {
data, err := page.SessionDataFromContext(ctx)
if err != nil {
return nil, err
}
if data.LpaID == "" {
return nil, errors.New("documentStore.GetAll requires LpaID")
}
var ds []page.Document
if err := s.dynamoClient.AllByPartialSK(ctx, dynamo.LpaKey(data.LpaID), dynamo.DocumentKey(""), &ds); err != nil && !errors.Is(err, dynamo.NotFoundError{}) {
return nil, err
}
return ds, nil
}
func (s *documentStore) UpdateScanResults(ctx context.Context, lpaID, s3ObjectKey string, virusDetected bool) error {
return s.dynamoClient.Update(ctx,
dynamo.LpaKey(lpaID),
dynamo.DocumentKey(s3ObjectKey),
map[string]types.AttributeValue{
":virusDetected": &types.AttributeValueMemberBOOL{Value: virusDetected},
":scanned": &types.AttributeValueMemberBOOL{Value: true},
},
"set VirusDetected = :virusDetected, Scanned = :scanned")
}
func (s *documentStore) Put(ctx context.Context, document page.Document) error {
return s.dynamoClient.Put(ctx, document)
}
func (s *documentStore) DeleteInfectedDocuments(ctx context.Context, documents page.Documents) error {
var dynamoKeys []dynamo.Keys
for _, d := range documents {
if d.VirusDetected {
dynamoKeys = append(dynamoKeys, dynamo.Keys{PK: d.PK, SK: d.SK})
}
}
if len(dynamoKeys) == 0 {
return nil
}
return s.dynamoClient.DeleteKeys(ctx, dynamoKeys)
}
func (s *documentStore) Delete(ctx context.Context, document page.Document) error {
if err := s.s3Client.DeleteObject(ctx, document.Key); err != nil {
return err
}
return s.dynamoClient.DeleteOne(ctx, document.PK, document.SK)
}
func (s *documentStore) Submit(ctx context.Context, donor *actor.DonorProvidedDetails, documents page.Documents) error {
var unsentDocuments []any
var unsentEvidence []event.Evidence
tags := map[string]string{
"replicate": "true",
"virus-scan-status": "ok",
}
for _, document := range documents {
if document.Sent.IsZero() && !document.VirusDetected {
document.Sent = s.now()
unsentDocuments = append(unsentDocuments, document)
unsentEvidence = append(unsentEvidence, event.Evidence{
Path: document.Key,
Filename: document.Filename,
})
if err := s.s3Client.PutObjectTagging(ctx, document.Key, tags); err != nil {
return err
}
}
}
if len(unsentDocuments) > 0 {
if err := s.eventClient.SendReducedFeeRequested(ctx, event.ReducedFeeRequested{
UID: donor.LpaUID,
RequestType: donor.FeeType.String(),
Evidence: unsentEvidence,
EvidenceDelivery: donor.EvidenceDelivery.String(),
}); err != nil {
return err
}
if err := s.dynamoClient.BatchPut(ctx, unsentDocuments); err != nil {
return err
}
}
return nil
}