Beispiel #1
0
func ValidateLDAPIdentityProvider(provider *api.LDAPPasswordIdentityProvider, fldPath *field.Path) ValidationResults {
	validationResults := ValidationResults{}

	validationResults.Append(ValidateStringSource(provider.BindPassword, fldPath.Child("bindPassword")))
	bindPassword, _ := api.ResolveStringValue(provider.BindPassword)
	validationResults.Append(ValidateLDAPClientConfig(provider.URL, provider.BindDN, bindPassword, provider.CA, provider.Insecure, fldPath))

	// At least one attribute to use as the user id is required
	if len(provider.Attributes.ID) == 0 {
		validationResults.AddErrors(field.Invalid(fldPath.Child("attributes", "id"), "[]", "at least one id attribute is required (LDAP standard identity attribute is 'dn')"))
	}

	return validationResults
}
Beispiel #2
0
func ValidateOAuthIdentityProvider(clientID string, clientSecret api.StringSource, fieldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}

	if len(clientID) == 0 {
		allErrs = append(allErrs, field.Required(fieldPath.Child("provider", "clientID"), ""))
	}
	clientSecretResults := ValidateStringSource(clientSecret, fieldPath.Child("provider", "clientSecret"))
	allErrs = append(allErrs, clientSecretResults.Errors...)
	if len(clientSecretResults.Errors) == 0 {
		clientSecret, err := api.ResolveStringValue(clientSecret)
		if err != nil {
			allErrs = append(allErrs, field.Invalid(fieldPath.Child("provider", "clientSecret"), "", err.Error()))
		} else if len(clientSecret) == 0 {
			allErrs = append(allErrs, field.Required(fieldPath.Child("provider", "clientSecret"), ""))
		}
	}

	return allErrs
}
Beispiel #3
0
// Run creates the GroupSyncer specified and runs it to sync groups
// the arguments are only here because its the only way to get the printer we need
func (o *PruneOptions) Run(cmd *cobra.Command, f *clientcmd.Factory) error {
	bindPassword, err := api.ResolveStringValue(o.Config.BindPassword)
	if err != nil {
		return err
	}
	clientConfig, err := ldaputil.NewLDAPClientConfig(o.Config.URL, o.Config.BindDN, bindPassword, o.Config.CA, o.Config.Insecure)
	if err != nil {
		return fmt.Errorf("could not determine LDAP client configuration: %v", err)
	}

	pruneBuilder, err := buildPruneBuilder(clientConfig, o.Config)
	if err != nil {
		return err
	}

	// populate schema-independent pruner fields
	pruner := &syncgroups.LDAPGroupPruner{
		Host:        clientConfig.Host(),
		GroupClient: o.GroupInterface,
		DryRun:      !o.Confirm,

		Out: o.Out,
		Err: os.Stderr,
	}

	listerMapper, err := getOpenShiftGroupListerMapper(clientConfig.Host(), o)
	if err != nil {
		return err
	}
	pruner.GroupLister = listerMapper
	pruner.GroupNameMapper = listerMapper

	pruner.GroupDetector, err = pruneBuilder.GetGroupDetector()
	if err != nil {
		return err
	}

	// Now we run the pruner and report any errors
	pruneErrors := pruner.Prune()
	return kerrs.NewAggregate(pruneErrors)

}
Beispiel #4
0
func ValidateLDAPSyncConfig(config *api.LDAPSyncConfig) ValidationResults {
	validationResults := ValidationResults{}

	validationResults.Append(ValidateStringSource(config.BindPassword, field.NewPath("bindPassword")))
	bindPassword, _ := api.ResolveStringValue(config.BindPassword)
	validationResults.Append(ValidateLDAPClientConfig(config.URL, config.BindDN, bindPassword, config.CA, config.Insecure, nil))

	schemaConfigsFound := []string{}

	if config.RFC2307Config != nil {
		configResults := ValidateRFC2307Config(config.RFC2307Config)
		validationResults.AddErrors(configResults.Errors...)
		validationResults.AddWarnings(configResults.Warnings...)
		schemaConfigsFound = append(schemaConfigsFound, "rfc2307")
	}
	if config.ActiveDirectoryConfig != nil {
		configResults := ValidateActiveDirectoryConfig(config.ActiveDirectoryConfig)
		validationResults.AddErrors(configResults.Errors...)
		validationResults.AddWarnings(configResults.Warnings...)
		schemaConfigsFound = append(schemaConfigsFound, "activeDirectory")
	}
	if config.AugmentedActiveDirectoryConfig != nil {
		configResults := ValidateAugmentedActiveDirectoryConfig(config.AugmentedActiveDirectoryConfig)
		validationResults.AddErrors(configResults.Errors...)
		validationResults.AddWarnings(configResults.Warnings...)
		schemaConfigsFound = append(schemaConfigsFound, "augmentedActiveDirectory")
	}

	if len(schemaConfigsFound) > 1 {
		validationResults.AddErrors(field.Invalid(field.NewPath("schema"), config, fmt.Sprintf("only one schema-specific config is allowed; found %v", schemaConfigsFound)))
	}
	if len(schemaConfigsFound) == 0 {
		validationResults.AddErrors(field.Required(field.NewPath("schema"), fmt.Sprintf("exactly one schema-specific config is required;  one of %v", []string{"rfc2307", "activeDirectory", "augmentedActiveDirectory"})))
	}

	return validationResults
}
Beispiel #5
0
func (c *AuthConfig) getPasswordAuthenticator(identityProvider configapi.IdentityProvider) (authenticator.Password, error) {
	identityMapper, err := identitymapper.NewIdentityUserMapper(c.IdentityRegistry, c.UserRegistry, identitymapper.MappingMethodType(identityProvider.MappingMethod))
	if err != nil {
		return nil, err
	}

	switch provider := identityProvider.Provider.(type) {
	case (*configapi.AllowAllPasswordIdentityProvider):
		return allowanypassword.New(identityProvider.Name, identityMapper), nil

	case (*configapi.DenyAllPasswordIdentityProvider):
		return denypassword.New(), nil

	case (*configapi.LDAPPasswordIdentityProvider):
		url, err := ldaputil.ParseURL(provider.URL)
		if err != nil {
			return nil, fmt.Errorf("Error parsing LDAPPasswordIdentityProvider URL: %v", err)
		}

		bindPassword, err := configapi.ResolveStringValue(provider.BindPassword)
		if err != nil {
			return nil, err
		}
		clientConfig, err := ldaputil.NewLDAPClientConfig(provider.URL,
			provider.BindDN,
			bindPassword,
			provider.CA,
			provider.Insecure)
		if err != nil {
			return nil, err
		}

		opts := ldappassword.Options{
			URL:                  url,
			ClientConfig:         clientConfig,
			UserAttributeDefiner: ldaputil.NewLDAPUserAttributeDefiner(provider.Attributes),
		}
		return ldappassword.New(identityProvider.Name, opts, identityMapper)

	case (*configapi.HTPasswdPasswordIdentityProvider):
		htpasswdFile := provider.File
		if len(htpasswdFile) == 0 {
			return nil, fmt.Errorf("HTPasswdFile is required to support htpasswd auth")
		}
		if htpasswordAuth, err := htpasswd.New(identityProvider.Name, htpasswdFile, identityMapper); err != nil {
			return nil, fmt.Errorf("Error loading htpasswd file %s: %v", htpasswdFile, err)
		} else {
			return htpasswordAuth, nil
		}

	case (*configapi.BasicAuthPasswordIdentityProvider):
		connectionInfo := provider.RemoteConnectionInfo
		if len(connectionInfo.URL) == 0 {
			return nil, fmt.Errorf("URL is required for BasicAuthPasswordIdentityProvider")
		}
		transport, err := cmdutil.TransportFor(connectionInfo.CA, connectionInfo.ClientCert.CertFile, connectionInfo.ClientCert.KeyFile)
		if err != nil {
			return nil, fmt.Errorf("Error building BasicAuthPasswordIdentityProvider client: %v", err)
		}
		return basicauthpassword.New(identityProvider.Name, connectionInfo.URL, transport, identityMapper), nil

	case (*configapi.KeystonePasswordIdentityProvider):
		connectionInfo := provider.RemoteConnectionInfo
		if len(connectionInfo.URL) == 0 {
			return nil, fmt.Errorf("URL is required for KeystonePasswordIdentityProvider")
		}
		transport, err := cmdutil.TransportFor(connectionInfo.CA, connectionInfo.ClientCert.CertFile, connectionInfo.ClientCert.KeyFile)
		if err != nil {
			return nil, fmt.Errorf("Error building KeystonePasswordIdentityProvider client: %v", err)
		}

		return keystonepassword.New(identityProvider.Name, connectionInfo.URL, transport, provider.DomainName, identityMapper), nil

	default:
		return nil, fmt.Errorf("No password auth found that matches %v.  The OAuth server cannot start!", identityProvider)
	}

}
Beispiel #6
0
func (c *AuthConfig) getOAuthProvider(identityProvider configapi.IdentityProvider) (external.Provider, error) {
	switch provider := identityProvider.Provider.(type) {
	case (*configapi.GitHubIdentityProvider):
		clientSecret, err := configapi.ResolveStringValue(provider.ClientSecret)
		if err != nil {
			return nil, err
		}
		return github.NewProvider(identityProvider.Name, provider.ClientID, clientSecret, provider.Organizations), nil

	case (*configapi.GitLabIdentityProvider):
		transport, err := cmdutil.TransportFor(provider.CA, "", "")
		if err != nil {
			return nil, err
		}
		clientSecret, err := configapi.ResolveStringValue(provider.ClientSecret)
		if err != nil {
			return nil, err
		}
		return gitlab.NewProvider(identityProvider.Name, transport, provider.URL, provider.ClientID, clientSecret)

	case (*configapi.GoogleIdentityProvider):
		clientSecret, err := configapi.ResolveStringValue(provider.ClientSecret)
		if err != nil {
			return nil, err
		}
		return google.NewProvider(identityProvider.Name, provider.ClientID, clientSecret, provider.HostedDomain)

	case (*configapi.OpenIDIdentityProvider):
		transport, err := cmdutil.TransportFor(provider.CA, "", "")
		if err != nil {
			return nil, err
		}
		clientSecret, err := configapi.ResolveStringValue(provider.ClientSecret)
		if err != nil {
			return nil, err
		}

		// OpenID Connect requests MUST contain the openid scope value
		// http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
		scopes := sets.NewString("openid")
		scopes.Insert(provider.ExtraScopes...)

		config := openid.Config{
			ClientID:     provider.ClientID,
			ClientSecret: clientSecret,

			Scopes: scopes.List(),

			ExtraAuthorizeParameters: provider.ExtraAuthorizeParameters,

			AuthorizeURL: provider.URLs.Authorize,
			TokenURL:     provider.URLs.Token,
			UserInfoURL:  provider.URLs.UserInfo,

			IDClaims:                provider.Claims.ID,
			PreferredUsernameClaims: provider.Claims.PreferredUsername,
			EmailClaims:             provider.Claims.Email,
			NameClaims:              provider.Claims.Name,
		}

		return openid.NewProvider(identityProvider.Name, transport, config)

	default:
		return nil, fmt.Errorf("No OAuth provider found that matches %v.  The OAuth server cannot start!", identityProvider)
	}

}
Beispiel #7
0
// Run creates the GroupSyncer specified and runs it to sync groups
// the arguments are only here because its the only way to get the printer we need
func (o *SyncOptions) Run(cmd *cobra.Command, f *clientcmd.Factory) error {
	bindPassword, err := api.ResolveStringValue(o.Config.BindPassword)
	if err != nil {
		return err
	}
	clientConfig, err := ldaputil.NewLDAPClientConfig(o.Config.URL, o.Config.BindDN, bindPassword, o.Config.CA, o.Config.Insecure)
	if err != nil {
		return fmt.Errorf("could not determine LDAP client configuration: %v", err)
	}

	errorHandler := o.CreateErrorHandler()

	syncBuilder, err := buildSyncBuilder(clientConfig, o.Config, errorHandler)
	if err != nil {
		return err
	}

	// populate schema-independent syncer fields
	syncer := &syncgroups.LDAPGroupSyncer{
		Host:        clientConfig.Host(),
		GroupClient: o.GroupInterface,
		DryRun:      !o.Confirm,

		Out: o.Out,
		Err: os.Stderr,
	}

	switch o.Source {
	case GroupSyncSourceOpenShift:
		// when your source of ldapGroupUIDs is from an openshift group, the mapping of ldapGroupUID to openshift group name is logically
		// pinned by the existing mapping.
		listerMapper, err := getOpenShiftGroupListerMapper(clientConfig.Host(), o)
		if err != nil {
			return err
		}
		syncer.GroupLister = listerMapper
		syncer.GroupNameMapper = listerMapper

	case GroupSyncSourceLDAP:
		syncer.GroupLister, err = getLDAPGroupLister(syncBuilder, o)
		if err != nil {
			return err
		}
		syncer.GroupNameMapper, err = getGroupNameMapper(syncBuilder, o)
		if err != nil {
			return err
		}

	default:
		return fmt.Errorf("invalid group source: %v", o.Source)
	}

	syncer.GroupMemberExtractor, err = syncBuilder.GetGroupMemberExtractor()
	if err != nil {
		return err
	}

	syncer.UserNameMapper, err = syncBuilder.GetUserNameMapper()
	if err != nil {
		return err
	}

	// Now we run the Syncer and report any errors
	openshiftGroups, syncErrors := syncer.Sync()
	if o.Confirm {
		return kerrs.NewAggregate(syncErrors)
	}

	list := &kapi.List{}
	for _, item := range openshiftGroups {
		list.Items = append(list.Items, item)
	}
	mapper, _ := f.Object()
	fn := cmdutil.VersionedPrintObject(f.PrintObject, cmd, mapper, o.Out)
	if err := fn(list); err != nil {
		return err
	}

	return kerrs.NewAggregate(syncErrors)
}