Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.8k views
in Technique[技术] by (71.8m points)

go - Parsing ARN from IAM Policy using Regex - Golang

I have the following IAM Policy:

{"Version":"2012-10-17","Statement":[{"Sid":"","Effect":"Allow","Principal":{"AWS":"arn:aws:sts::<account>:assumed-role/custom_role/<role>"},"Action":"sts:AssumeRole","Condition":{"StringEquals":{"sts:ExternalId":"<account>"}}}]}

but the "AWS" portion can also be an array:

"AWS": [
      "arn:aws:sts::<account>:assumed-role/custom_role/<role_1>",
      "arn:aws:sts::<account>:assumed-role/custom_role/<role_2>"
]

What I need is a regex that can parse both structures and return the list of arn:aws:sts as a list of strings... how can I accomplish that using regex in Golang? I tried to use json.Unmarshal but the object structure is different between []string and string

Edit:

I have the following snippet:

re := regexp.MustCompile(`arn:aws:sts::[a-z0-9]*:assumed-role/custom_role/[a-z0-9]-*`)
result := re.FindAll([]byte(arn), 10)
for _, res := range result {
    fmt.Println(string(res))
}


>>> `arn:aws:sts::<account_id>:assumed-role/custom_role/`

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can decode the AWS key directly into a slice of strings, the standard JSON decoder will parse both inputs correctly.

Demo

type AWSPolicy struct {
    Statement []struct {
        Principal struct {
            AWSRoles []string `json:"AWSRoles"`
        } `json:"Principal"`
    } `json:"Statement"`
}

Here's a test for it

var testsAWSPolicyParsing = []struct {
    name      string
    input     []byte
    wantRoles []string
}{
    {
        name:      "unique role",
        input:     []byte(`{"Version":"2012-10-17","Statement":[{"Sid":"","Effect":"Allow","Principal":{"AWSRoles":"arn:aws:sts::<account>:assumed-role/custom_role/<role>"},"Action":"sts:AssumeRole","Condition":{"StringEquals":{"sts:ExternalId":"<account>"}}}]}`),
        wantRoles: []string{"arn:aws:sts::<account>:assumed-role/custom_role/<role>"},
    },
    {
        name:  "multiple roles",
        input: []byte(`{"Version":"2012-10-17","Statement":[{"Sid":"","Effect":"Allow","Principal":{"AWSRoles":["arn:aws:sts::<account>:assumed-role/custom_role/<role_1>","arn:aws:sts::<account>:assumed-role/custom_role/<role_2>"]},"Action":"sts:AssumeRole","Condition":{"StringEquals":{"sts:ExternalId":"<account>"}}}]}`),
        wantRoles: []string{
            "arn:aws:sts::<account>:assumed-role/custom_role/<role_1>",
            "arn:aws:sts::<account>:assumed-role/custom_role/<role_2>",
        },
    },
}

func TestParseAWSPolicy(t *testing.T) {
    for _, tc := range testsAWSPolicyParsing {
        t.Run(tc.name, func(t *testing.T) {
            t.Parallel()
            var p AWSPolicy
            err := json.Unmarshal(tc.input, &p)
            if err != nil {
                t.Fatal("unexpected error parsing AWSRoles policy", err)
            }
            if l := len(p.Statement); l != 1 {
                t.Fatalf("unexpected Statement length. want 1, got %d", l)
            }
            if got := p.Statement[0].Principal.AWSRoles; !reflect.DeepEqual(got, tc.wantRoles) {
                t.Fatalf("roles are not the same, got %v, want %v", got, tc.wantRoles)
            }
        })
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...