/
iam_policy.go
93 lines (83 loc) · 2.12 KB
/
iam_policy.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
package main
import (
"encoding/json"
"fmt"
"net/url"
"reflect"
)
type policyDocumentRaw struct {
Version string
Statement []statementEntryRaw
}
type policyDocumentRawWithSingleStatement struct {
Version string
Statement statementEntryRaw
}
type statementEntryRaw struct {
Effect string
Action interface{}
Resource interface{}
}
type policyDocument struct {
Version string
Statement []statementEntry
}
type statementEntry struct {
Effect string
Action []string
Resource []string
// Conditions map[string]interface{}
}
func convertPolicyDocument(doc *string) (*policyDocument, error) {
var pd policyDocument
decodedDoc, err := url.QueryUnescape(*doc)
if err != nil {
return nil, err
}
appLogger.Debugf("Got a policy document decoded: %s", decodedDoc)
var pdRaw policyDocumentRaw
if err := json.Unmarshal([]byte(decodedDoc), &pdRaw); err != nil {
var pdSingle policyDocumentRawWithSingleStatement
if errSingle := json.Unmarshal([]byte(decodedDoc), &pdSingle); errSingle != nil {
return nil, errSingle
}
pdRaw.Statement = append(pdRaw.Statement, pdSingle.Statement)
}
pd.Version = pdRaw.Version
for _, stmtRaw := range pdRaw.Statement {
if stmtRaw.Effect == "" || stmtRaw.Action == nil || stmtRaw.Resource == nil {
continue
}
var stmt statementEntry
stmt.Effect = stmtRaw.Effect
// convert action interface
if err := setStringSlice(&stmt.Action, stmtRaw.Action); err != nil {
return nil, err
}
// convert resource interface
if err := setStringSlice(&stmt.Resource, stmtRaw.Resource); err != nil {
return nil, err
}
pd.Statement = append(pd.Statement, stmt)
}
return &pd, nil
}
func setStringSlice(slice *[]string, target interface{}) error {
if reflect.TypeOf(target).Name() == "string" {
*slice = append(*slice, target.(string))
return nil
}
if values, ok := target.([]string); ok {
*slice = append(*slice, values...)
return nil
}
if values, ok := target.([]interface{}); ok {
for _, v := range values {
if str, ok := v.(string); ok {
*slice = append(*slice, str)
}
}
return nil
}
return fmt.Errorf("Not spported types, target=%+v", target)
}