Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v15] add preset field to SAMLIdPServiceProviderV1 spec #39277

Merged
merged 3 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5953,12 +5953,15 @@ message SAMLIdPServiceProviderSpecV1 {
string EntityID = 2 [(gogoproto.jsontag) = "entity_id"];
// ACSURL is the endpoint where SAML authentication response will be redirected.
string ACSURL = 3 [(gogoproto.jsontag) = "acs_url"];
// AttributeMapping is used to map Service Provider requested attributes to
// AttributeMapping is used to map service provider requested attributes to
// username, role and traits in Teleport.
repeated SAMLAttributeMapping AttributeMapping = 4 [(gogoproto.jsontag) = "attribute_mapping"];
// Preset is used to define service provider profile that will have a custom behavior
// processed by Teleport.
string Preset = 5 [(gogoproto.jsontag) = "preset"];
}

// SAMLAttributeMapping represents SAML Service Provider requested attribute
// SAMLAttributeMapping represents SAML service provider requested attribute
// name, format and its values.
message SAMLAttributeMapping {
// name is an attribute name.
Expand Down
18 changes: 18 additions & 0 deletions api/types/saml_idp_service_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/gravitational/trace"

"github.com/gravitational/teleport/api/types/samlsp"
"github.com/gravitational/teleport/api/utils"
)

Expand Down Expand Up @@ -105,6 +106,8 @@ var (
// ErrDuplicateAttributeName is returned when attribute mapping declares two or more
// attributes with the same name.
ErrDuplicateAttributeName = &trace.BadParameterError{Message: "duplicate attribute name not allowed"}
// ErrUnsupportedPresetName is returned when preset name is not supported.
ErrUnsupportedPresetName = &trace.BadParameterError{Message: "unsupported preset name"}
)

// SAMLIdPServiceProvider specifies configuration for service providers for Teleport's built in SAML IdP.
Expand Down Expand Up @@ -262,6 +265,10 @@ func (s *SAMLIdPServiceProviderV1) CheckAndSetDefaults() error {
attrNames[attributeMap.Name] = struct{}{}
}

if ok := validatePreset(s.Spec.Preset); !ok {
return trace.Wrap(ErrUnsupportedPresetName)
}

return nil
}

Expand Down Expand Up @@ -309,3 +316,14 @@ func (am *SAMLAttributeMapping) CheckAndSetDefaults() error {
}
return nil
}

// validatePreset validates SAMLIdPServiceProviderV1 preset field.
// preset can be either empty or one of the supported type.
func validatePreset(preset string) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is not the place to change this, but if you happen to touch this part of the codebase in the future it might be cleaner to move validatePreset to the samlsp package IMO.

switch preset {
case "", samlsp.GCPWorkforce:
return true
default:
return false
}
}
24 changes: 24 additions & 0 deletions api/types/saml_idp_service_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"testing"

"github.com/stretchr/testify/require"

"github.com/gravitational/teleport/api/types/samlsp"
)

// TestNewSAMLIdPServiceProvider ensures a valid SAML IdP service provider.
Expand All @@ -32,6 +34,7 @@ func TestNewSAMLIdPServiceProvider(t *testing.T) {
errAssertion require.ErrorAssertionFunc
expectedEntityID string
attributeMapping []*SAMLAttributeMapping
preset string
}{
{
name: "valid entity descriptor",
Expand Down Expand Up @@ -171,6 +174,26 @@ func TestNewSAMLIdPServiceProvider(t *testing.T) {
require.ErrorContains(t, err, "invalid name format")
},
},
{
name: "supported preset value",
entityDescriptor: "",
entityID: "IAMShowcase",
acsURL: "https:/test.com/acs",
expectedEntityID: "IAMShowcase",
errAssertion: require.NoError,
preset: samlsp.GCPWorkforce,
},
{
name: "unsupported preset value",
entityDescriptor: "",
entityID: "IAMShowcase",
acsURL: "https:/test.com/acs",
expectedEntityID: "IAMShowcase",
errAssertion: func(t require.TestingT, err error, i ...interface{}) {
require.ErrorContains(t, err, "unsupported preset")
},
preset: "notsupported",
},
}

for _, test := range tests {
Expand All @@ -182,6 +205,7 @@ func TestNewSAMLIdPServiceProvider(t *testing.T) {
EntityID: test.entityID,
ACSURL: test.acsURL,
AttributeMapping: test.attributeMapping,
Preset: test.preset,
})

test.errAssertion(t, err)
Expand Down
23 changes: 23 additions & 0 deletions api/types/samlsp/samlsp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Copyright 2024 Gravitational, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package samlsp

const (
// GCPWorkforce is a SAML service provider preset name for Google Cloud Platform
// Workforce Identity Federation.
GCPWorkforce = "gcp-workforce"
)
Loading
Loading