繁体   English   中英

使用正则表达式从 IAM 策略解析 ARN

[英]Parsing ARN from IAM Policy using Regex

我有以下 IAM 政策:

{"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>"}}}]}

"AWS"部分也可以是一个数组:

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

我需要的是一个正则表达式,它可以解析这两个结构并将arn:aws:sts列表作为字符串列表返回......我如何在 Golang 中使用正则表达式来实现这一点? 我尝试使用json.Unmarshal[]stringstring之间的 object 结构不同

编辑:

我有以下片段:

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/`

使用JSON解码器

您可以将AWS密钥直接解码为实现“json.Unmarshaler”接口的自定义类型,并正确解码两个输入。

演示

type AWSRoles []string

func (r *AWSRoles) UnmarshalJSON(b []byte) error {
    var s string
    if err := json.Unmarshal(b, &s); err == nil {
        *r = append(*r, s)
        return nil
    }
    var ss []string
    if err := json.Unmarshal(b, &ss); err == nil {
        *r = ss
        return nil
    }
    return errors.New("cannot unmarshal neither to a string nor a slice of strings")
}

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

这是一个测试

var testsAWSPolicyParsing = []struct {
    name      string
    input     []byte
    wantRoles []string
}{
    {
        name:      "unique role",
        input:     []byte(`{"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>"}}}]}`),
        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":{"AWS":["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)
            }
        })
    }
}

使用正则表达式

如果您仍想使用正则表达式,只要:

  • AWS 账户只有数字 [0-9]
  • 自定义角色名称只有字母数字字符和下划线

var awsRolesRegex = regexp.MustCompile("arn:aws:sts::[a-z0-9]+:assumed-role/custom_role/[a-zA-Z0-9_]+")

演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM