Skip to content

Commit

Permalink
Add required field to OAuth2
Browse files Browse the repository at this point in the history
  • Loading branch information
sgayangi committed Jan 14, 2024
1 parent b767dfc commit d3f834b
Show file tree
Hide file tree
Showing 24 changed files with 586 additions and 121 deletions.
10 changes: 9 additions & 1 deletion adapter/internal/oasparser/model/adapter_internal_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ func (adapterInternalAPI *AdapterInternalAPI) SetXWSO2ApplicationSecurity(applic
adapterInternalAPI.xWso2ApplicationSecurity = applicationSecurity
}

// GetXWSO2ApplicationSecurity returns the optional or mandatory application security
// GetXWSO2ApplicationSecurity returns true if application security is mandatory, and false if optional
func (adapterInternalAPI *AdapterInternalAPI) GetXWSO2ApplicationSecurity() bool {
return adapterInternalAPI.xWso2ApplicationSecurity
}
Expand Down Expand Up @@ -776,6 +776,14 @@ func (adapterInternalAPI *AdapterInternalAPI) SetInfoHTTPRouteCR(httpRoute *gwap
if authScheme.Spec.Override != nil && authScheme.Spec.Override.Disabled != nil {
adapterInternalAPI.disableAuthentications = *authScheme.Spec.Override.Disabled
}

authSpec := utils.SelectPolicy(&authScheme.Spec.Override, &authScheme.Spec.Default, nil, nil)
if authSpec != nil && authSpec.AuthTypes != nil && authSpec.AuthTypes.Oauth2.Required != "" {
adapterInternalAPI.SetXWSO2ApplicationSecurity(authSpec.AuthTypes.Oauth2.Required == "mandatory")
} else {
adapterInternalAPI.SetXWSO2ApplicationSecurity(true)
}

adapterInternalAPI.disableScopes = disableScopes

// Check whether the API has a backend JWT token
Expand Down
17 changes: 10 additions & 7 deletions adapter/internal/operator/synchronizer/rest_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,7 @@ func GenerateAdapterInternalAPI(apiState APIState, httpRoute *HTTPRouteState, en
adapterInternalAPI.SetAPIDefinitionFile(apiState.APIDefinitionFile)
adapterInternalAPI.SetAPIDefinitionEndpoint(apiState.APIDefinition.Spec.DefinitionPath)
adapterInternalAPI.SetSubscriptionValidation(apiState.SubscriptionValidation)
if apiState.MutualSSL != nil && apiState.MutualSSL.Required != "" && !adapterInternalAPI.GetDisableAuthentications() {
adapterInternalAPI.SetDisableMtls(apiState.MutualSSL.Disabled)
adapterInternalAPI.SetMutualSSL(apiState.MutualSSL.Required)
adapterInternalAPI.SetClientCerts(apiState.APIDefinition.Name, apiState.MutualSSL.ClientCertificates)
} else {
adapterInternalAPI.SetDisableMtls(true)
}

adapterInternalAPI.EnvType = envType

environment := apiState.APIDefinition.Spec.Environment
Expand All @@ -90,6 +84,15 @@ func GenerateAdapterInternalAPI(apiState APIState, httpRoute *HTTPRouteState, en
loggers.LoggerAPKOperator.ErrorC(logging.PrintError(logging.Error2631, logging.MAJOR, "Error setting HttpRoute CR info to adapterInternalAPI. %v", err))
return nil, nil, err
}

if apiState.MutualSSL != nil && apiState.MutualSSL.Required != "" && !adapterInternalAPI.GetDisableAuthentications() {
adapterInternalAPI.SetDisableMtls(apiState.MutualSSL.Disabled)
adapterInternalAPI.SetMutualSSL(apiState.MutualSSL.Required)
adapterInternalAPI.SetClientCerts(apiState.APIDefinition.Name, apiState.MutualSSL.ClientCertificates)
} else {
adapterInternalAPI.SetDisableMtls(true)
}

if err := adapterInternalAPI.Validate(); err != nil {
loggers.LoggerAPKOperator.ErrorC(logging.PrintError(logging.Error2632, logging.MAJOR, "Error validating adapterInternalAPI intermediate representation. %v", err))
return nil, nil, err
Expand Down
56 changes: 47 additions & 9 deletions common-go-libs/apis/dp/v1alpha1/authentication_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,39 @@ func (src *Authentication) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.Default.Disabled = src.Spec.Default.Disabled
dst.Spec.Override.Disabled = src.Spec.Override.Disabled

// Convert Oauth2Auth to v1alpha2.Oauth2Auth
dst.Spec.Default.AuthTypes.Oauth2 = v1alpha2.Oauth2Auth(src.Spec.Default.AuthTypes.Oauth2)
dst.Spec.Override.AuthTypes.Oauth2 = v1alpha2.Oauth2Auth(src.Spec.Override.AuthTypes.Oauth2)
// Convert Oauth2Auth default to v1alpha2.Oauth2Auth : Required field added as mandatory for OAuth2
dst.Spec.Default.AuthTypes.Oauth2 = v1alpha2.Oauth2Auth{
Required: "mandatory",
Disabled: src.Spec.Default.AuthTypes.Oauth2.Disabled,
Header: src.Spec.Default.AuthTypes.Oauth2.Header,
SendTokenToUpstream: src.Spec.Default.AuthTypes.Oauth2.SendTokenToUpstream,
}

// Convert Oauth2Auth override to v1alpha2.Oauth2Auth : Required field added as mandatory for OAuth2
dst.Spec.Override.AuthTypes.Oauth2 = v1alpha2.Oauth2Auth{
Required: "mandatory",
Disabled: src.Spec.Default.AuthTypes.Oauth2.Disabled,
Header: src.Spec.Default.AuthTypes.Oauth2.Header,
SendTokenToUpstream: src.Spec.Default.AuthTypes.Oauth2.SendTokenToUpstream,
}

// Convert Oauth2Auth Default to v1alpha2.APIKey : Required field added as optional for APIKey
for _, apiKeyAuth := range src.Spec.Default.AuthTypes.APIKey {
convertedAPIKeyAuth := v1alpha2.APIKeyAuth(apiKeyAuth)
convertedAPIKeyAuth := v1alpha2.APIKeyAuth{
In: apiKeyAuth.In,
Name: apiKeyAuth.Name,
SendTokenToUpstream: apiKeyAuth.SendTokenToUpstream,
}
dst.Spec.Default.AuthTypes.APIKey = append(dst.Spec.Default.AuthTypes.APIKey, convertedAPIKeyAuth)
}

// Convert Oauth2Auth Override to v1alpha2.APIKey : Required field added as optional for APIKey
for _, apiKeyAuth := range src.Spec.Override.AuthTypes.APIKey {
convertedAPIKeyAuth := v1alpha2.APIKeyAuth(apiKeyAuth)
convertedAPIKeyAuth := v1alpha2.APIKeyAuth{
In: apiKeyAuth.In,
Name: apiKeyAuth.Name,
SendTokenToUpstream: apiKeyAuth.SendTokenToUpstream,
}
dst.Spec.Override.AuthTypes.APIKey = append(dst.Spec.Override.AuthTypes.APIKey, convertedAPIKeyAuth)
}

Expand All @@ -67,16 +89,32 @@ func (src *Authentication) ConvertFrom(srcRaw conversion.Hub) error {

src.Spec.Default.Disabled = dst.Spec.Default.Disabled
src.Spec.Override.Disabled = dst.Spec.Override.Disabled
src.Spec.Default.AuthTypes.Oauth2 = Oauth2Auth(dst.Spec.Default.AuthTypes.Oauth2)
src.Spec.Override.AuthTypes.Oauth2 = Oauth2Auth(dst.Spec.Override.AuthTypes.Oauth2)
src.Spec.Default.AuthTypes.Oauth2 = Oauth2Auth{
Disabled: src.Spec.Default.AuthTypes.Oauth2.Disabled,
Header: src.Spec.Default.AuthTypes.Oauth2.Header,
SendTokenToUpstream: src.Spec.Default.AuthTypes.Oauth2.SendTokenToUpstream,
}
src.Spec.Override.AuthTypes.Oauth2 = Oauth2Auth{
Disabled: src.Spec.Override.AuthTypes.Oauth2.Disabled,
Header: src.Spec.Override.AuthTypes.Oauth2.Header,
SendTokenToUpstream: src.Spec.Override.AuthTypes.Oauth2.SendTokenToUpstream,
}

for _, apiKeyAuth := range dst.Spec.Default.AuthTypes.APIKey {
convertedAPIKeyAuth := APIKeyAuth(apiKeyAuth)
convertedAPIKeyAuth := APIKeyAuth{
In: apiKeyAuth.In,
Name: apiKeyAuth.Name,
SendTokenToUpstream: apiKeyAuth.SendTokenToUpstream,
}
src.Spec.Default.AuthTypes.APIKey = append(src.Spec.Default.AuthTypes.APIKey, convertedAPIKeyAuth)
}

for _, apiKeyAuth := range dst.Spec.Override.AuthTypes.APIKey {
convertedAPIKeyAuth := APIKeyAuth(apiKeyAuth)
convertedAPIKeyAuth := APIKeyAuth{
In: apiKeyAuth.In,
Name: apiKeyAuth.Name,
SendTokenToUpstream: apiKeyAuth.SendTokenToUpstream,
}
src.Spec.Override.AuthTypes.APIKey = append(src.Spec.Override.AuthTypes.APIKey, convertedAPIKeyAuth)
}

Expand Down
8 changes: 8 additions & 0 deletions common-go-libs/apis/dp/v1alpha2/authentication_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type AuthSpec struct {

// APIAuth Authentication scheme type and details
type APIAuth struct {

// Oauth2 is to specify the Oauth2 authentication scheme details
//
// +optional
Expand Down Expand Up @@ -108,6 +109,12 @@ type TestConsoleKeyAuth struct {
// Oauth2Auth OAuth2 Authentication scheme details
type Oauth2Auth struct {

// Required indicates whether OAuth2 is mandatory or optional
// +kubebuilder:validation:Enum=mandatory;optional
// +kubebuilder:default=mandatory
// +optional
Required string `json:"required,omitempty"`

// Disabled is to disable OAuth2 authentication
//
// +kubebuilder:default=false
Expand All @@ -128,6 +135,7 @@ type Oauth2Auth struct {

// APIKeyAuth APIKey Authentication scheme details
type APIKeyAuth struct {

// In is to specify how the APIKey is passed to the request
//
// +kubebuilder:validation:Enum=Header;Query
Expand Down
57 changes: 45 additions & 12 deletions common-go-libs/apis/dp/v1alpha2/authentication_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ func (r *Authentication) ValidateUpdate(old runtime.Object) (admission.Warnings,
// ValidateAuthentication validates the Authentication
func (r *Authentication) ValidateAuthentication() error {
var allErrs field.ErrorList
isOAuthDisabled := false
isMTLSMandatory := false
isMTLSDisabled := false

if r.Spec.TargetRef.Name == "" {
allErrs = append(allErrs, field.Required(field.NewPath("spec").Child("targetRef").Child("name"), "Name is required"))
Expand All @@ -77,35 +74,71 @@ func (r *Authentication) ValidateAuthentication() error {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("targetRef").Child("kind"), r.Spec.TargetRef.Kind,
"Invalid Kind is provided"))
}

var mutualSSL *MutualSSLConfig
var oauth2Auth Oauth2Auth

isOAuthDisabled := false
isOAuthOptional := false

isMTLSDisabled := false
isMTLSMandatory := false

if r.Spec.Default != nil && r.Spec.Default.AuthTypes != nil && r.Spec.Default.AuthTypes.MutualSSL != nil {
isOAuthDisabled = r.Spec.Default.AuthTypes.Oauth2.Disabled
oauth2Auth = r.Spec.Default.AuthTypes.Oauth2
mutualSSL = r.Spec.Default.AuthTypes.MutualSSL

isOAuthDisabled = oauth2Auth.Disabled
isOAuthOptional = oauth2Auth.Required == "optional"

isMTLSMandatory = strings.ToLower(mutualSSL.Required) == "mandatory"
isMTLSDisabled = mutualSSL.Disabled
if isOAuthDisabled && (!isMTLSMandatory || isMTLSDisabled) {

if mutualSSL != nil && r.Spec.TargetRef.Kind != constants.KindAPI {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("default").Child("authTypes").Child("oauth2"), r.Spec.Default.AuthTypes.MutualSSL,
"invalid authentication - mTLS can currently only be added for APIs"))
}

if (mutualSSL == nil || !isMTLSMandatory) && isOAuthDisabled {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("default").Child("authTypes").Child("mtls"), r.Spec.Default.AuthTypes,
"invalid authentication configuration - one of mTLS or OAuth2 must be enabled and mandatory"))
"invalid authentication configuration - security not enforced for API"))
}
if len(mutualSSL.CertificatesInline) == 0 && len(mutualSSL.ConfigMapRefs) == 0 && len(mutualSSL.SecretRefs) == 0 {

if isMTLSDisabled && isOAuthOptional {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("default").Child("authTypes").Child("mtls"), r.Spec.Default.AuthTypes,
"invalid authentication configuration - security not enforced for API"))
}

if mutualSSL != nil && len(mutualSSL.CertificatesInline) == 0 && len(mutualSSL.ConfigMapRefs) == 0 && len(mutualSSL.SecretRefs) == 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("default").Child("authTypes").Child("mtls"), r.Spec.Default.AuthTypes.MutualSSL,
"invalid mTLS configuration - certificates not provided"))
}

} else if r.Spec.Override != nil && r.Spec.Override.AuthTypes != nil && r.Spec.Override.AuthTypes.MutualSSL != nil {
isOAuthDisabled = r.Spec.Override.AuthTypes.Oauth2.Disabled
oauth2Auth := r.Spec.Override.AuthTypes.Oauth2
mutualSSL = r.Spec.Override.AuthTypes.MutualSSL

isOAuthDisabled = r.Spec.Override.AuthTypes.Oauth2.Disabled
isOAuthOptional = oauth2Auth.Required == "optional"

isMTLSMandatory = strings.ToLower(mutualSSL.Required) == "mandatory"
isMTLSDisabled = mutualSSL.Disabled
if isOAuthDisabled && (!isMTLSMandatory || isMTLSDisabled) {

if mutualSSL != nil && r.Spec.TargetRef.Kind != constants.KindAPI {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("override").Child("authTypes").Child("oauth2"), r.Spec.Override.AuthTypes.MutualSSL,
"invalid authentication - mTLS can currently only be added for APIs"))
}

if (mutualSSL == nil || !isMTLSMandatory) && isOAuthDisabled {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("override").Child("authTypes").Child("mtls"), r.Spec.Override.AuthTypes,
"invalid authentication configuration - security not enforced for API"))
}

if isMTLSDisabled && isOAuthOptional {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("override").Child("authTypes").Child("mtls"), r.Spec.Override.AuthTypes,
"invalid authentication configuration - one of mTLS or OAuth2 must be enabled and mandatory"))
"invalid authentication configuration - security not enforced for API"))
}

if len(mutualSSL.CertificatesInline) == 0 && len(mutualSSL.ConfigMapRefs) == 0 && len(mutualSSL.SecretRefs) == 0 {
if mutualSSL != nil && len(mutualSSL.CertificatesInline) == 0 && len(mutualSSL.ConfigMapRefs) == 0 && len(mutualSSL.SecretRefs) == 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("override").Child("authTypes").Child("mtls"), r.Spec.Override.AuthTypes.MutualSSL,
"invalid mTLS configuration - certificates not provided"))
}
Expand Down
16 changes: 16 additions & 0 deletions common-go-libs/config/crd/bases/dp.wso2.com_authentications.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,14 @@ spec:
description: Header is the header name used to pass the
OAuth2 token
type: string
required:
default: mandatory
description: Required indicates whether OAuth2 is mandatory
or optional
enum:
- mandatory
- optional
type: string
sendTokenToUpstream:
description: SendTokenToUpstream is to specify whether
the OAuth2 token should be sent to the upstream
Expand Down Expand Up @@ -485,6 +493,14 @@ spec:
description: Header is the header name used to pass the
OAuth2 token
type: string
required:
default: mandatory
description: Required indicates whether OAuth2 is mandatory
or optional
enum:
- mandatory
- optional
type: string
sendTokenToUpstream:
description: SendTokenToUpstream is to specify whether
the OAuth2 token should be sent to the upstream
Expand Down
Loading

0 comments on commit d3f834b

Please sign in to comment.