Skip to content

Commit 1d6682d

Browse files
authored
Added OIDCProviderConfig API (#282)
1 parent cf03d0b commit 1d6682d

File tree

2 files changed

+184
-1
lines changed

2 files changed

+184
-1
lines changed

auth/provider_config.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ func buildMask(data map[string]interface{}) []string {
109109
return mask
110110
}
111111

112+
// OIDCProviderConfig is the OIDC auth provider configuration.
113+
// See https://openid.net/specs/openid-connect-core-1_0-final.html.
114+
type OIDCProviderConfig struct {
115+
ID string
116+
DisplayName string
117+
Enabled bool
118+
ClientID string
119+
Issuer string
120+
}
121+
112122
// SAMLProviderConfig is the SAML auth provider configuration.
113123
// See http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html.
114124
type SAMLProviderConfig struct {
@@ -422,6 +432,38 @@ func newProviderConfigClient(hc *http.Client, conf *internal.AuthConfig) *provid
422432
}
423433
}
424434

435+
// OIDCProviderConfig returns the OIDCProviderConfig with the given ID.
436+
func (c *providerConfigClient) OIDCProviderConfig(ctx context.Context, id string) (*OIDCProviderConfig, error) {
437+
if err := validateOIDCConfigID(id); err != nil {
438+
return nil, err
439+
}
440+
441+
req := &internal.Request{
442+
Method: http.MethodGet,
443+
URL: fmt.Sprintf("/oauthIdpConfigs/%s", id),
444+
}
445+
var result oidcProviderConfigDAO
446+
if _, err := c.makeRequest(ctx, req, &result); err != nil {
447+
return nil, err
448+
}
449+
450+
return result.toOIDCProviderConfig(), nil
451+
}
452+
453+
// DeleteOIDCProviderConfig deletes the OIDCProviderConfig with the given ID.
454+
func (c *providerConfigClient) DeleteOIDCProviderConfig(ctx context.Context, id string) error {
455+
if err := validateOIDCConfigID(id); err != nil {
456+
return err
457+
}
458+
459+
req := &internal.Request{
460+
Method: http.MethodDelete,
461+
URL: fmt.Sprintf("/oauthIdpConfigs/%s", id),
462+
}
463+
_, err := c.makeRequest(ctx, req, nil)
464+
return err
465+
}
466+
425467
// SAMLProviderConfig returns the SAMLProviderConfig with the given ID.
426468
func (c *providerConfigClient) SAMLProviderConfig(ctx context.Context, id string) (*SAMLProviderConfig, error) {
427469
if err := validateSAMLConfigID(id); err != nil {
@@ -543,6 +585,24 @@ func (c *providerConfigClient) makeRequest(ctx context.Context, req *internal.Re
543585
return c.httpClient.DoAndUnmarshal(ctx, req, v)
544586
}
545587

588+
type oidcProviderConfigDAO struct {
589+
Name string `json:"name"`
590+
ClientID string `json:"clientId"`
591+
Issuer string `json:"issuer"`
592+
DisplayName string `json:"displayName"`
593+
Enabled bool `json:"enabled"`
594+
}
595+
596+
func (dao *oidcProviderConfigDAO) toOIDCProviderConfig() *OIDCProviderConfig {
597+
return &OIDCProviderConfig{
598+
ID: extractResourceID(dao.Name),
599+
DisplayName: dao.DisplayName,
600+
Enabled: dao.Enabled,
601+
ClientID: dao.ClientID,
602+
Issuer: dao.Issuer,
603+
}
604+
}
605+
546606
type idpCertificate struct {
547607
X509Certificate string `json:"x509Certificate"`
548608
}
@@ -582,6 +642,14 @@ func (dao *samlProviderConfigDAO) toSAMLProviderConfig() *SAMLProviderConfig {
582642
}
583643
}
584644

645+
func validateOIDCConfigID(id string) error {
646+
if !strings.HasPrefix(id, "oidc.") {
647+
return fmt.Errorf("invalid OIDC provider id: %q", id)
648+
}
649+
650+
return nil
651+
}
652+
585653
func validateSAMLConfigID(id string) error {
586654
if !strings.HasPrefix(id, "saml.") {
587655
return fmt.Errorf("invalid SAML provider id: %q", id)

auth/provider_config_test.go

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,16 @@ import (
2727
"google.golang.org/api/iterator"
2828
)
2929

30+
const oidcConfigResponse = `{
31+
"name":"projects/mock-project-id/oauthIdpConfigs/oidc.provider",
32+
"clientId": "CLIENT_ID",
33+
"issuer": "https://oidc.com/issuer",
34+
"displayName": "oidcProviderName",
35+
"enabled": true
36+
}`
37+
3038
const samlConfigResponse = `{
31-
"name":"projects/mock-project-id/inboundSamlConfigs/saml.provider",
39+
"name": "projects/mock-project-id/inboundSamlConfigs/saml.provider",
3240
"idpConfig": {
3341
"idpEntityId": "IDP_ENTITY_ID",
3442
"ssoUrl": "https://example.com/login",
@@ -57,6 +65,14 @@ var idpCertsMap = []interface{}{
5765
map[string]interface{}{"x509Certificate": "CERT2"},
5866
}
5967

68+
var oidcProviderConfig = &OIDCProviderConfig{
69+
ID: "oidc.provider",
70+
DisplayName: "oidcProviderName",
71+
Enabled: true,
72+
ClientID: "CLIENT_ID",
73+
Issuer: "https://oidc.com/issuer",
74+
}
75+
6076
var samlProviderConfig = &SAMLProviderConfig{
6177
ID: "saml.provider",
6278
DisplayName: "samlProviderName",
@@ -69,12 +85,111 @@ var samlProviderConfig = &SAMLProviderConfig{
6985
CallbackURL: "https://projectId.firebaseapp.com/__/auth/handler",
7086
}
7187

88+
var invalidOIDCConfigIDs = []string{
89+
"",
90+
"invalid.id",
91+
"saml.config",
92+
}
93+
7294
var invalidSAMLConfigIDs = []string{
7395
"",
7496
"invalid.id",
7597
"oidc.config",
7698
}
7799

100+
func TestOIDCProviderConfig(t *testing.T) {
101+
s := echoServer([]byte(oidcConfigResponse), t)
102+
defer s.Close()
103+
104+
client := s.Client.pcc
105+
oidc, err := client.OIDCProviderConfig(context.Background(), "oidc.provider")
106+
if err != nil {
107+
t.Fatal(err)
108+
}
109+
110+
if !reflect.DeepEqual(oidc, oidcProviderConfig) {
111+
t.Errorf("OIDCProviderConfig() = %#v; want = %#v", oidc, oidcProviderConfig)
112+
}
113+
114+
req := s.Req[0]
115+
if req.Method != http.MethodGet {
116+
t.Errorf("OIDCProviderConfig() Method = %q; want = %q", req.Method, http.MethodGet)
117+
}
118+
119+
wantURL := "/projects/mock-project-id/oauthIdpConfigs/oidc.provider"
120+
if req.URL.Path != wantURL {
121+
t.Errorf("OIDCProviderConfig() URL = %q; want = %q", req.URL.Path, wantURL)
122+
}
123+
}
124+
125+
func TestOIDCProviderConfigInvalidID(t *testing.T) {
126+
client := &providerConfigClient{}
127+
wantErr := "invalid OIDC provider id: "
128+
129+
for _, id := range invalidOIDCConfigIDs {
130+
saml, err := client.OIDCProviderConfig(context.Background(), id)
131+
if saml != nil || err == nil || !strings.HasPrefix(err.Error(), wantErr) {
132+
t.Errorf("OIDCProviderConfig(%q) = (%v, %v); want = (nil, %q)", id, saml, err, wantErr)
133+
}
134+
}
135+
}
136+
137+
func TestOIDCProviderConfigError(t *testing.T) {
138+
s := echoServer([]byte(notFoundResponse), t)
139+
defer s.Close()
140+
s.Status = http.StatusNotFound
141+
142+
client := s.Client.pcc
143+
saml, err := client.OIDCProviderConfig(context.Background(), "oidc.provider")
144+
if saml != nil || err == nil || !IsConfigurationNotFound(err) {
145+
t.Errorf("OIDCProviderConfig() = (%v, %v); want = (nil, ConfigurationNotFound)", saml, err)
146+
}
147+
}
148+
149+
func TestDeleteOIDCProviderConfig(t *testing.T) {
150+
s := echoServer([]byte("{}"), t)
151+
defer s.Close()
152+
153+
client := s.Client.pcc
154+
if err := client.DeleteOIDCProviderConfig(context.Background(), "oidc.provider"); err != nil {
155+
t.Fatal(err)
156+
}
157+
158+
req := s.Req[0]
159+
if req.Method != http.MethodDelete {
160+
t.Errorf("DeleteOIDCProviderConfig() Method = %q; want = %q", req.Method, http.MethodDelete)
161+
}
162+
163+
wantURL := "/projects/mock-project-id/oauthIdpConfigs/oidc.provider"
164+
if req.URL.Path != wantURL {
165+
t.Errorf("DeleteOIDCProviderConfig() URL = %q; want = %q", req.URL.Path, wantURL)
166+
}
167+
}
168+
169+
func TestDeleteOIDCProviderConfigInvalidID(t *testing.T) {
170+
client := &providerConfigClient{}
171+
wantErr := "invalid OIDC provider id: "
172+
173+
for _, id := range invalidOIDCConfigIDs {
174+
err := client.DeleteOIDCProviderConfig(context.Background(), id)
175+
if err == nil || !strings.HasPrefix(err.Error(), wantErr) {
176+
t.Errorf("DeleteOIDCProviderConfig(%q) = %v; want = %q", id, err, wantErr)
177+
}
178+
}
179+
}
180+
181+
func TestDeleteOIDCProviderConfigError(t *testing.T) {
182+
s := echoServer([]byte(notFoundResponse), t)
183+
defer s.Close()
184+
s.Status = http.StatusNotFound
185+
186+
client := s.Client.pcc
187+
err := client.DeleteOIDCProviderConfig(context.Background(), "oidc.provider")
188+
if err == nil || !IsConfigurationNotFound(err) {
189+
t.Errorf("DeleteOIDCProviderConfig() = %v; want = ConfigurationNotFound", err)
190+
}
191+
}
192+
78193
func TestSAMLProviderConfig(t *testing.T) {
79194
s := echoServer([]byte(samlConfigResponse), t)
80195
defer s.Close()

0 commit comments

Comments
 (0)