Skip to content

Commit

Permalink
Update authentication webhook implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sgayangi committed Jul 24, 2024
1 parent 29d7542 commit 3603592
Show file tree
Hide file tree
Showing 31 changed files with 86 additions and 1,502 deletions.
62 changes: 20 additions & 42 deletions common-go-libs/apis/dp/v1alpha2/authentication_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,60 +69,38 @@ func (r *Authentication) ValidateAuthentication() error {
if r.Spec.TargetRef.Name == "" {
allErrs = append(allErrs, field.Required(field.NewPath("spec").Child("targetRef").Child("name"), "Name is required"))
}

if !(r.Spec.TargetRef.Kind == constants.KindAPI || r.Spec.TargetRef.Kind == constants.KindResource) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("targetRef").Child("kind"), r.Spec.TargetRef.Kind,
"Invalid Kind is provided"))
}

var mutualSSL *MutualSSLConfig
var authTypes *APIAuth

isOAuthEnabled := true
isOAuthMandatory := true

isMTLSEnabled := false
isMTLSMandatory := false

isAPIKeyEnabled := false
isAPIKeyMandatory := false
if r.Spec.Default != nil && r.Spec.Default.AuthTypes != nil {
authTypes = r.Spec.Default.AuthTypes

isOAuthEnabled = !authTypes.OAuth2.Disabled
isOAuthMandatory = authTypes.OAuth2.Required == "mandatory"
if authTypes.MutualSSL != nil {
mutualSSL = authTypes.MutualSSL
isMTLSEnabled = !authTypes.MutualSSL.Disabled
isMTLSMandatory = authTypes.MutualSSL.Required == "mandatory"
if r.Spec.Default != nil && r.Spec.Default.AuthTypes != nil && r.Spec.Default.AuthTypes.MutualSSL != nil {
if r.Spec.TargetRef.Kind != constants.KindAPI {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("default").Child("authTypes").Child("mtls"), r.Spec.Default.AuthTypes.MutualSSL,
"invalid authentication - mTLS can only be added for APIs"))
}
mutualSSL := r.Spec.Default.AuthTypes.MutualSSL

if authTypes.APIKey != nil {
isAPIKeyEnabled = true
isAPIKeyMandatory = authTypes.APIKey.Required == "mandatory"
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"))
}
}

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

isMTLSMandatory = isMTLSEnabled && isMTLSMandatory
isOAuthMandatory = isOAuthEnabled && isOAuthMandatory
isAPIKeyMandatory = isAPIKeyEnabled && isAPIKeyMandatory

isMTLSOptional := isMTLSEnabled && !isMTLSMandatory
isOAuthOptional := isOAuthEnabled && !isOAuthMandatory
isAPIKeyOptional := isAPIKeyEnabled && !isAPIKeyMandatory

// valid security combinations
// at least one must be enabled and mandatory
// OR mTLS is enabled and one of OAuth2 or APIKey is optional
mutualSSL := r.Spec.Override.AuthTypes.MutualSSL

if !((isMTLSMandatory || isOAuthMandatory || isAPIKeyMandatory) || (isMTLSOptional && (isOAuthOptional || isAPIKeyOptional))) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("default").Child("authTypes"), authTypes,
"invalid authtypes provided: one of mTLS, APIKey, OAuth2 has to be enabled and mandatory "+
"OR mTLS and one of OAuth2 or APIKey need to be optional "+
"OR all three can be optional"))
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"))
}
}

Expand Down
33 changes: 1 addition & 32 deletions runtime/config-deployer-service/ballerina/APIClient.bal
Original file line number Diff line number Diff line change
Expand Up @@ -348,17 +348,9 @@ public class APIClient {
map<model:Endpoint|()> createdEndpointMap, commons:Organization organization) returns error? {
map<model:Authentication> authenticationMap = {};
model:AuthenticationExtensionType authTypes = {};
boolean isOAuthEnabled = true;
boolean isOAuthMandatory = true;
boolean isMTLSEnabled = false;
boolean isMTLSMandatory = false;
boolean isAPIKeyEnabled = false;
boolean isAPIKeyMandatory = false;
foreach AuthenticationRequest authentication in authentications {
if authentication.authType == "OAuth2" {
OAuth2Authentication oauth2Authentication = check authentication.cloneWithType(OAuth2Authentication);
isOAuthEnabled = oauth2Authentication.enabled;
isOAuthMandatory = oauth2Authentication.required == "mandatory";
authTypes.oauth2 = {header: <string>oauth2Authentication.headerName, sendTokenToUpstream: <boolean>oauth2Authentication.sendTokenToUpstream, disabled: !oauth2Authentication.enabled, required: oauth2Authentication.required};
} else if authentication.authType == "JWT" {
JWTAuthentication jwtAuthentication = check authentication.cloneWithType(JWTAuthentication);
Expand All @@ -376,10 +368,8 @@ public class APIClient {
} else {
apiKeyAuthentication = check authentication.cloneWithType(APIKeyAuthentication);
}
isAPIKeyEnabled = apiKeyAuthentication.enabled;
isAPIKeyMandatory = apiKeyAuthentication.required == "mandatory";
model:APIKey[] apiKeys = [];
if isAPIKeyEnabled {
if apiKeyAuthentication.enabled {
if apiKeyAuthentication.headerEnable {
apiKeys.push({'in: "Header", name: <string>apiKeyAuthentication.headerName, sendTokenToUpstream: apiKeyAuthentication.sendTokenToUpstream});
}
Expand All @@ -393,31 +383,10 @@ public class APIClient {
}
} else if authentication.authType == "mTLS" {
MTLSAuthentication mtlsAuthentication = check authentication.cloneWithType(MTLSAuthentication);
isMTLSMandatory = mtlsAuthentication.required == "mandatory";
isMTLSEnabled = mtlsAuthentication.enabled;
authTypes.mtls = {disabled: !mtlsAuthentication.enabled, configMapRefs: mtlsAuthentication.certificates, required: mtlsAuthentication.required};
}
}

isOAuthMandatory = isOAuthEnabled && isOAuthMandatory;
boolean isOAuthOptional = isOAuthEnabled && !isOAuthMandatory;

isMTLSMandatory = isMTLSEnabled && isMTLSMandatory;
boolean isMTLSOptional = isMTLSEnabled && !isMTLSMandatory;

isAPIKeyMandatory = isAPIKeyEnabled && isAPIKeyMandatory;
boolean isAPIKeyOptional = isAPIKeyEnabled && !isAPIKeyMandatory;

if !(
// at least one must be enabled and mandatory
(isMTLSMandatory || isOAuthMandatory || isAPIKeyMandatory) ||
// mTLS is enabled and one of OAuth2 or APIKey is optional
(isMTLSOptional && (isOAuthOptional || isAPIKeyOptional))) {
log:printError("Invalid authtypes provided: one of mTLS, APIKey, OAuth2 has to be enabled and mandatory " +
"OR mTLS and one of OAuth2 or APIKey need to be optional ");
return e909019();
}

log:printDebug("Auth Types:" + authTypes.toString());
string[] keys = createdEndpointMap.keys();
log:printDebug("createdEndpointMap.keys:" + createdEndpointMap.keys().toString());
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 3603592

Please sign in to comment.