Introduce modules.ValidateResource for Cloud-specific validation (#7092)

This commit is contained in:
Andrej Tokarčík 2021-06-07 19:31:55 +02:00 committed by GitHub
parent ca1c512e43
commit a92dcc3df4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 115 additions and 3 deletions

View file

@ -27,6 +27,10 @@ import (
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/trace"
)
// Features provides supported and unsupported features
@ -97,6 +101,31 @@ func GetModules() Modules {
return modules
}
// ValidateResource performs additional resource checks.
func ValidateResource(res types.Resource) error {
// All checks below are Cloud-specific.
if !GetModules().Features().Cloud {
return nil
}
switch r := res.(type) {
case types.AuthPreference:
switch r.GetSecondFactor() {
case constants.SecondFactorOff, constants.SecondFactorOptional:
return trace.BadParameter("cannot disable two-factor authentication on Cloud")
}
case types.SessionRecordingConfig:
switch r.GetMode() {
case types.RecordAtProxy, types.RecordAtProxySync:
return trace.BadParameter("cannot set proxy recording mode on Cloud")
}
if !r.GetProxyChecksHostKeys() {
return trace.BadParameter("cannot disable strict host key checking on Cloud")
}
}
return nil
}
type defaultModules struct{}
// BuildType returns build type (OSS or Enterprise)

View file

@ -14,15 +14,82 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package modules
package modules_test
import (
"context"
"fmt"
"testing"
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth"
"github.com/gravitational/teleport/lib/modules"
"github.com/stretchr/testify/require"
)
func TestOSSModules(t *testing.T) {
require.False(t, GetModules().IsBoringBinary())
require.Equal(t, BuildOSS, GetModules().BuildType())
require.False(t, modules.GetModules().IsBoringBinary())
require.Equal(t, modules.BuildOSS, modules.GetModules().BuildType())
}
func TestValidateAuthPreferenceOnCloud(t *testing.T) {
testServer, err := auth.NewTestAuthServer(auth.TestAuthServerConfig{
Dir: t.TempDir(),
})
require.NoError(t, err)
setCloudFeatureFlag(t)
authPref := types.DefaultAuthPreference()
err = testServer.AuthServer.SetAuthPreference(authPref)
require.NoError(t, err)
authPref.SetSecondFactor(constants.SecondFactorOff)
err = testServer.AuthServer.SetAuthPreference(authPref)
require.EqualError(t, err, "cannot disable two-factor authentication on Cloud")
}
func TestValidateSessionRecordingConfigOnCloud(t *testing.T) {
ctx := context.Background()
testServer, err := auth.NewTestAuthServer(auth.TestAuthServerConfig{
Dir: t.TempDir(),
})
require.NoError(t, err)
setCloudFeatureFlag(t)
recConfig := types.DefaultSessionRecordingConfig()
err = testServer.AuthServer.SetSessionRecordingConfig(ctx, recConfig)
require.NoError(t, err)
recConfig.SetMode(types.RecordAtProxy)
err = testServer.AuthServer.SetSessionRecordingConfig(ctx, recConfig)
require.EqualError(t, err, "cannot set proxy recording mode on Cloud")
}
func setCloudFeatureFlag(t *testing.T) {
oldModules := modules.GetModules()
t.Cleanup(func() { modules.SetModules(oldModules) })
modules.SetModules(&cloudModules{})
}
type cloudModules struct{}
func (m cloudModules) Features() modules.Features {
return modules.Features{Cloud: true}
}
func (m *cloudModules) BuildType() string {
return modules.BuildEnterprise
}
func (m *cloudModules) PrintVersion() {
fmt.Println("Teleport Cloud")
}
func (m *cloudModules) IsBoringBinary() bool {
return false
}

View file

@ -24,6 +24,7 @@ import (
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/utils"
@ -181,6 +182,11 @@ func (s *ClusterConfigurationService) GetAuthPreference() (types.AuthPreference,
// SetAuthPreference sets the cluster authentication preferences
// on the backend.
func (s *ClusterConfigurationService) SetAuthPreference(preferences types.AuthPreference) error {
// Perform the modules-provided checks.
if err := modules.ValidateResource(preferences); err != nil {
return trace.Wrap(err)
}
value, err := services.MarshalAuthPreference(preferences)
if err != nil {
return trace.Wrap(err)
@ -307,6 +313,11 @@ func (s *ClusterConfigurationService) GetClusterNetworkingConfig(ctx context.Con
// SetClusterNetworkingConfig sets the cluster networking config
// on the backend.
func (s *ClusterConfigurationService) SetClusterNetworkingConfig(ctx context.Context, netConfig types.ClusterNetworkingConfig) error {
// Perform the modules-provided checks.
if err := modules.ValidateResource(netConfig); err != nil {
return trace.Wrap(err)
}
value, err := services.MarshalClusterNetworkingConfig(netConfig)
if err != nil {
return trace.Wrap(err)
@ -351,6 +362,11 @@ func (s *ClusterConfigurationService) GetSessionRecordingConfig(ctx context.Cont
// SetSessionRecordingConfig sets session recording config on the backend.
func (s *ClusterConfigurationService) SetSessionRecordingConfig(ctx context.Context, recConfig types.SessionRecordingConfig) error {
// Perform the modules-provided checks.
if err := modules.ValidateResource(recConfig); err != nil {
return trace.Wrap(err)
}
value, err := services.MarshalSessionRecordingConfig(recConfig)
if err != nil {
return trace.Wrap(err)