-
Notifications
You must be signed in to change notification settings - Fork 0
/
authorization.go
98 lines (87 loc) · 2.67 KB
/
authorization.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
package dygo
import (
"context"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
type output struct {
Results []map[string]types.AttributeValue
item *Item
ctx context.Context
bypassAuth bool
}
func newOutput(item *Item, ctx context.Context) *output {
return &output{
item: item,
ctx: ctx,
Results: make([]map[string]types.AttributeValue, 0),
}
}
func (o *output) Run() error {
if o == nil || o.item == nil {
return nil
}
return o.item.err
}
// Unmarshal unmarshals the DynamoDB query results into the provided 'out' object,
// It is only used for queries and batch get operations and 'out' must be a slice of structs that implement the 'Out' interface.
// It filters the results based on the specified 'entityTypes'.
// It also performs authorization by calling the 'Authorize' method on the 'out' object.
//
// Example :
//
// var data []dataItem
// err = item.BatchGetAuthorizedItem(context.Background(), 10).
// Unmarshal(&data, []string{"room"}).
// Run()
//
// And dataItem struct must implement the Out interface which has a Authorize method.
//
// func (d *dataSlice) Authorize(ctx context.Context) error {
// // write your own logic
// return nil
// }
//
// Here Unmarshal will unmarshal only the items with _entity_type = "room".
func (o *output) Unmarshal(out Out, entityTypes []string) *output {
if o == nil || o.item == nil || o.item.err != nil || o.Results == nil {
return o
}
targetAttVals := []map[string]types.AttributeValue{}
for _, result := range o.Results {
switch v := result[getPartitionKey(o.item)].(type) {
case *types.AttributeValueMemberS:
key := getSplittedKey(v.Value, o.item.c.keySeparator)
if stringExists(entityTypes, key) {
targetAttVals = append(targetAttVals, result)
}
}
}
if err := attributevalue.UnmarshalListOfMaps(targetAttVals, &out); err != nil {
o.item.err = err
}
if !o.bypassAuth {
err := out.Authorize(o.ctx)
if err != nil {
o.item.err = dynamoError().method("authorization").message(err.Error())
}
}
return o
}
// BypassAuthorization is used to bypass the authorization process inside Unmarshal function.
// Example :
//
// var data []dataItem
// err = item.BatchGetAuthorizedItem(context.Background(), 10).
// BypassAuth().
// Unmarshal(&data, []string{"room"}).
// Run()
func (o *output) BypassAuthorization() *output {
o.bypassAuth = true
return o
}
// Out is an interface that must be implemented by the struct that is used to unmarshal the DynamoDB results.
// It has a Authorize method that is used to perform authorization on the retrieved items.
type Out interface {
Authorize(context.Context) error
}