-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathoidc_authentication.go
More file actions
200 lines (175 loc) · 5.98 KB
/
Copy pathoidc_authentication.go
File metadata and controls
200 lines (175 loc) · 5.98 KB
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
package feeds
import (
"encoding/json"
)
// OidcAuthentication represents a union type that can hold any of the three OIDC authentication types
// The properties are flattened at the top level for API compatibility
type OidcAuthentication struct {
// Type indicates which OIDC authentication type this represents
Type OidcAuthenticationType `json:"Type"`
// Common fields across all OIDC types
Audience string `json:"Audience,omitempty"`
SubjectKeys []string `json:"SubjectKeys,omitempty"`
// Azure-specific fields
ClientId string `json:"ClientId,omitempty"`
TenantId string `json:"TenantId,omitempty"`
// AWS-specific fields
SessionDuration string `json:"SessionDuration,omitempty"`
RoleArn string `json:"RoleArn,omitempty"`
}
// OidcAuthenticationType represents the type of OIDC authentication
type OidcAuthenticationType string
const (
OidcAuthenticationTypeAzure OidcAuthenticationType = "Azure"
OidcAuthenticationTypeAWS OidcAuthenticationType = "AWS"
OidcAuthenticationTypeGoogle OidcAuthenticationType = "Google"
)
// NewAzureOidcAuthentication creates a new OIDC authentication for Azure
func NewAzureOidcAuthentication(clientId, tenantId, audience string, subjectKeys []string) *OidcAuthentication {
return &OidcAuthentication{
Type: OidcAuthenticationTypeAzure,
ClientId: clientId,
TenantId: tenantId,
Audience: audience,
SubjectKeys: subjectKeys,
}
}
// NewAwsOidcAuthentication creates a new OIDC authentication for AWS
func NewAwsOidcAuthentication(sessionDuration, audience, roleArn string, subjectKeys []string) *OidcAuthentication {
return &OidcAuthentication{
Type: OidcAuthenticationTypeAWS,
SessionDuration: sessionDuration,
Audience: audience,
RoleArn: roleArn,
SubjectKeys: subjectKeys,
}
}
// NewGoogleOidcAuthentication creates a new OIDC authentication for Google
func NewGoogleOidcAuthentication(audience string, subjectKeys []string) *OidcAuthentication {
return &OidcAuthentication{
Type: OidcAuthenticationTypeGoogle,
Audience: audience,
SubjectKeys: subjectKeys,
}
}
// GetAzure returns the Azure OIDC authentication data if this is an Azure type
func (o *OidcAuthentication) GetAzure() (*AzureContainerRegistryOidcAuthentication, bool) {
if o.Type == OidcAuthenticationTypeAzure {
return &AzureContainerRegistryOidcAuthentication{
ClientId: o.ClientId,
TenantId: o.TenantId,
Audience: o.Audience,
SubjectKeys: o.SubjectKeys,
}, true
}
return nil, false
}
// GetAWS returns the AWS OIDC authentication data if this is an AWS type
func (o *OidcAuthentication) GetAWS() (*AwsElasticContainerRegistryOidcAuthentication, bool) {
if o.Type == OidcAuthenticationTypeAWS {
return &AwsElasticContainerRegistryOidcAuthentication{
SessionDuration: o.SessionDuration,
Audience: o.Audience,
SubjectKeys: o.SubjectKeys,
RoleArn: o.RoleArn,
}, true
}
return nil, false
}
// GetGoogle returns the Google OIDC authentication data if this is a Google type
func (o *OidcAuthentication) GetGoogle() (*GoogleContainerRegistryOidcAuthentication, bool) {
if o.Type == OidcAuthenticationTypeGoogle {
return &GoogleContainerRegistryOidcAuthentication{
Audience: o.Audience,
SubjectKeys: o.SubjectKeys,
}, true
}
return nil, false
}
// MarshalJSON implements custom JSON marshaling to handle the union type
func (o *OidcAuthentication) MarshalJSON() ([]byte, error) {
// Create a map to hold the fields we want to serialize
result := make(map[string]interface{})
// Always include the Type field
result["Type"] = o.Type
// Add common fields
if o.Audience != "" {
result["Audience"] = o.Audience
}
if len(o.SubjectKeys) > 0 {
result["SubjectKeys"] = o.SubjectKeys
}
// Add type-specific fields based on the type
switch o.Type {
case OidcAuthenticationTypeAzure:
if o.ClientId != "" {
result["ClientId"] = o.ClientId
}
if o.TenantId != "" {
result["TenantId"] = o.TenantId
}
case OidcAuthenticationTypeAWS:
if o.SessionDuration != "" {
result["SessionDuration"] = o.SessionDuration
}
if o.RoleArn != "" {
result["RoleArn"] = o.RoleArn
}
case OidcAuthenticationTypeGoogle:
// Google only has common fields, no additional ones
}
return json.Marshal(result)
}
// UnmarshalJSON implements custom JSON unmarshaling to handle the union type
func (o *OidcAuthentication) UnmarshalJSON(data []byte) error {
if len(data) == 0 || string(data) == "null" {
*o = OidcAuthentication{}
return nil
}
// First, unmarshal into a map to inspect the fields
var raw map[string]interface{}
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
// Discriminate based on properties. This is hacky, but we would have to add a "Type" property to the API
// To handle this properly
if _, hasClientId := raw["ClientId"]; hasClientId {
o.Type = OidcAuthenticationTypeAzure
} else if _, hasRoleArn := raw["RoleArn"]; hasRoleArn {
o.Type = OidcAuthenticationTypeAWS
} else {
o.Type = OidcAuthenticationTypeGoogle
}
// Now unmarshal into the appropriate struct to get all fields
switch o.Type {
case OidcAuthenticationTypeAzure:
var azure AzureContainerRegistryOidcAuthentication
if err := json.Unmarshal(data, &azure); err != nil {
return err
}
o.Type = OidcAuthenticationTypeAzure
o.ClientId = azure.ClientId
o.TenantId = azure.TenantId
o.Audience = azure.Audience
o.SubjectKeys = azure.SubjectKeys
case OidcAuthenticationTypeAWS:
var aws AwsElasticContainerRegistryOidcAuthentication
if err := json.Unmarshal(data, &aws); err != nil {
return err
}
o.Type = OidcAuthenticationTypeAWS
o.SessionDuration = aws.SessionDuration
o.Audience = aws.Audience
o.SubjectKeys = aws.SubjectKeys
o.RoleArn = aws.RoleArn
case OidcAuthenticationTypeGoogle:
var google GoogleContainerRegistryOidcAuthentication
if err := json.Unmarshal(data, &google); err != nil {
return err
}
o.Type = OidcAuthenticationTypeGoogle
o.Audience = google.Audience
o.SubjectKeys = google.SubjectKeys
}
return nil
}