From eca4c84939da83240b705f89ce6d47a7528903bb Mon Sep 17 00:00:00 2001 From: senthalan Date: Wed, 27 Sep 2023 15:10:08 +0530 Subject: [PATCH 1/8] Add environment wise key support --- adapter/internal/discovery/xds/marshaller.go | 1 + .../messaging/notification_listener.go | 9 +- .../application_key_mapping.pb.go | 35 +++-- adapter/pkg/eventhub/types/types.go | 1 + adapter/pkg/messaging/event_types.go | 1 + .../application_key_mapping.proto | 1 + .../subscription/ApplicationKeyMapping.java | 138 ++++++++++++++++++ .../ApplicationKeyMappingOrBuilder.java | 12 ++ .../ApplicationKeyMappingProto.java | 16 +- .../constants/APISecurityConstants.java | 5 + .../enforcer/dto/APIKeyValidationInfoDTO.java | 11 ++ .../models/ApplicationKeyMapping.java | 12 ++ .../enforcer/security/KeyValidator.java | 1 + .../security/jwt/JWTAuthenticator.java | 28 +++- .../SubscriptionDataStoreImpl.java | 1 + .../security/jwt/JWTAuthenticatorTest.java | 50 ++++++- 16 files changed, 298 insertions(+), 24 deletions(-) diff --git a/adapter/internal/discovery/xds/marshaller.go b/adapter/internal/discovery/xds/marshaller.go index dad24ecaad..b0c7b639de 100644 --- a/adapter/internal/discovery/xds/marshaller.go +++ b/adapter/internal/discovery/xds/marshaller.go @@ -629,6 +629,7 @@ func marshalKeyMapping(keyMappingInternal *types.ApplicationKeyMapping) *subscri TenantId: keyMappingInternal.TenantID, TenantDomain: keyMappingInternal.TenantDomain, Timestamp: keyMappingInternal.TimeStamp, + EnvId: keyMappingInternal.EnvID, } } diff --git a/adapter/internal/messaging/notification_listener.go b/adapter/internal/messaging/notification_listener.go index 41250c5173..42cb421e36 100644 --- a/adapter/internal/messaging/notification_listener.go +++ b/adapter/internal/messaging/notification_listener.go @@ -287,6 +287,8 @@ func handleLifeCycleEvents(data []byte) { // handleApplicationEvents to process application related events func handleApplicationEvents(data []byte, eventType string) { + //todo Need to check this event handling. + logger.LoggerInternalMsg.Infof("Application event type : %s", eventType) if strings.EqualFold(applicationRegistration, eventType) || strings.EqualFold(removeApplicationKeyMapping, eventType) { var applicationRegistrationEvent msg.ApplicationRegistrationEvent @@ -302,10 +304,13 @@ func handleApplicationEvents(data []byte, eventType string) { return } + logger.LoggerInternalMsg.Infof("Application Key Mapping event for the Consumer Key : %+v", applicationRegistrationEvent) + applicationKeyMapping := types.ApplicationKeyMapping{ApplicationID: applicationRegistrationEvent.ApplicationID, ConsumerKey: applicationRegistrationEvent.ConsumerKey, KeyType: applicationRegistrationEvent.KeyType, KeyManager: applicationRegistrationEvent.KeyManager, TenantID: -1, TenantDomain: applicationRegistrationEvent.TenantDomain, - TimeStamp: applicationRegistrationEvent.TimeStamp, ApplicationUUID: applicationRegistrationEvent.ApplicationUUID} + TimeStamp: applicationRegistrationEvent.TimeStamp, ApplicationUUID: applicationRegistrationEvent.ApplicationUUID, + EnvID: applicationRegistrationEvent.EnvID} applicationKeyMappingReference := xds.GetApplicationKeyMappingReference(&applicationKeyMapping) @@ -335,6 +340,8 @@ func handleApplicationEvents(data []byte, eventType string) { return } + logger.LoggerInternalMsg.Infof("Application Key Mapping event for the Consumer Key : %+v", applicationEvent) + app := types.Application{UUID: applicationEvent.UUID, ID: applicationEvent.ApplicationID, Name: applicationEvent.ApplicationName, SubName: applicationEvent.Subscriber, Policy: applicationEvent.ApplicationPolicy, TokenType: applicationEvent.TokenType, diff --git a/adapter/pkg/discovery/api/wso2/discovery/subscription/application_key_mapping.pb.go b/adapter/pkg/discovery/api/wso2/discovery/subscription/application_key_mapping.pb.go index aa77510265..9a186c8baa 100644 --- a/adapter/pkg/discovery/api/wso2/discovery/subscription/application_key_mapping.pb.go +++ b/adapter/pkg/discovery/api/wso2/discovery/subscription/application_key_mapping.pb.go @@ -34,6 +34,7 @@ type ApplicationKeyMapping struct { TenantDomain string `protobuf:"bytes,6,opt,name=tenantDomain,proto3" json:"tenantDomain,omitempty"` Timestamp int64 `protobuf:"varint,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` ApplicationUUID string `protobuf:"bytes,8,opt,name=applicationUUID,proto3" json:"applicationUUID,omitempty"` + EnvId string `protobuf:"bytes,9,opt,name=envId,proto3" json:"envId,omitempty"` } func (x *ApplicationKeyMapping) Reset() { @@ -124,6 +125,13 @@ func (x *ApplicationKeyMapping) GetApplicationUUID() string { return "" } +func (x *ApplicationKeyMapping) GetEnvId() string { + if x != nil { + return x.EnvId + } + return "" +} + var File_wso2_discovery_subscription_application_key_mapping_proto protoreflect.FileDescriptor var file_wso2_discovery_subscription_application_key_mapping_proto_rawDesc = []byte{ @@ -132,7 +140,7 @@ var file_wso2_discovery_subscription_application_key_mapping_proto_rawDesc = []b 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x77, 0x73, 0x6f, 0x32, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa1, 0x02, 0x0a, 0x15, 0x41, 0x70, 0x70, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb7, 0x02, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, @@ -150,18 +158,19 @@ var file_wso2_discovery_subscription_application_key_mapping_proto_rawDesc = []b 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x28, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x55, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x70, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x55, 0x49, 0x44, 0x42, 0x9f, 0x01, 0x0a, - 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x73, 0x6f, 0x32, 0x2e, 0x63, 0x68, 0x6f, 0x72, 0x65, 0x6f, - 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, - 0x1a, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x77, 0x73, 0x6f, 0x32, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x79, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x3b, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x55, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x6e, 0x76, 0x49, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, + 0x49, 0x64, 0x42, 0x9f, 0x01, 0x0a, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x73, 0x6f, 0x32, 0x2e, + 0x63, 0x68, 0x6f, 0x72, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2e, 0x64, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x1a, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x77, 0x73, 0x6f, 0x32, + 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/adapter/pkg/eventhub/types/types.go b/adapter/pkg/eventhub/types/types.go index da6effb681..cac88f848b 100644 --- a/adapter/pkg/eventhub/types/types.go +++ b/adapter/pkg/eventhub/types/types.go @@ -66,6 +66,7 @@ type ApplicationKeyMapping struct { ConsumerKey string `json:"consumerKey"` KeyType string `json:"keyType"` KeyManager string `json:"keyManager"` + EnvID string `json:"EnvId"` TenantID int32 `json:"tenanId,omitempty"` TenantDomain string `json:"tenanDomain,omitempty"` TimeStamp int64 `json:"timeStamp,omitempty"` diff --git a/adapter/pkg/messaging/event_types.go b/adapter/pkg/messaging/event_types.go index 6cf2a1097f..bbbff6ce1e 100644 --- a/adapter/pkg/messaging/event_types.go +++ b/adapter/pkg/messaging/event_types.go @@ -138,6 +138,7 @@ type ApplicationRegistrationEvent struct { ConsumerKey string `json:"consumerKey"` KeyType string `json:"keyType"` KeyManager string `json:"keyManager"` + EnvID string `json:"EnvId"` Event } diff --git a/api/proto/wso2/discovery/subscription/application_key_mapping.proto b/api/proto/wso2/discovery/subscription/application_key_mapping.proto index 6f4d02e0e4..d97a48d633 100644 --- a/api/proto/wso2/discovery/subscription/application_key_mapping.proto +++ b/api/proto/wso2/discovery/subscription/application_key_mapping.proto @@ -19,4 +19,5 @@ message ApplicationKeyMapping { string tenantDomain = 6; int64 timestamp = 7; string applicationUUID = 8; + string envId = 9; } diff --git a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMapping.java b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMapping.java index f8ea05694a..eb83cbb5c9 100644 --- a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMapping.java +++ b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMapping.java @@ -25,6 +25,7 @@ private ApplicationKeyMapping() { keyManager_ = ""; tenantDomain_ = ""; applicationUUID_ = ""; + envId_ = ""; } @java.lang.Override @@ -102,6 +103,12 @@ private ApplicationKeyMapping( applicationUUID_ = s; break; } + case 74: { + java.lang.String s = input.readStringRequireUtf8(); + + envId_ = s; + break; + } default: { if (!parseUnknownField( input, unknownFields, extensionRegistry, tag)) { @@ -357,6 +364,44 @@ public java.lang.String getApplicationUUID() { } } + public static final int ENVID_FIELD_NUMBER = 9; + private volatile java.lang.Object envId_; + /** + * string envId = 9; + * @return The envId. + */ + @java.lang.Override + public java.lang.String getEnvId() { + java.lang.Object ref = envId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + envId_ = s; + return s; + } + } + /** + * string envId = 9; + * @return The bytes for envId. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getEnvIdBytes() { + java.lang.Object ref = envId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + envId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -395,6 +440,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (!getApplicationUUIDBytes().isEmpty()) { com.google.protobuf.GeneratedMessageV3.writeString(output, 8, applicationUUID_); } + if (!getEnvIdBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 9, envId_); + } unknownFields.writeTo(output); } @@ -431,6 +479,9 @@ public int getSerializedSize() { if (!getApplicationUUIDBytes().isEmpty()) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, applicationUUID_); } + if (!getEnvIdBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(9, envId_); + } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; @@ -462,6 +513,8 @@ public boolean equals(final java.lang.Object obj) { != other.getTimestamp()) return false; if (!getApplicationUUID() .equals(other.getApplicationUUID())) return false; + if (!getEnvId() + .equals(other.getEnvId())) return false; if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -490,6 +543,8 @@ public int hashCode() { getTimestamp()); hash = (37 * hash) + APPLICATIONUUID_FIELD_NUMBER; hash = (53 * hash) + getApplicationUUID().hashCode(); + hash = (37 * hash) + ENVID_FIELD_NUMBER; + hash = (53 * hash) + getEnvId().hashCode(); hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; @@ -643,6 +698,8 @@ public Builder clear() { applicationUUID_ = ""; + envId_ = ""; + return this; } @@ -677,6 +734,7 @@ public org.wso2.choreo.connect.discovery.subscription.ApplicationKeyMapping buil result.tenantDomain_ = tenantDomain_; result.timestamp_ = timestamp_; result.applicationUUID_ = applicationUUID_; + result.envId_ = envId_; onBuilt(); return result; } @@ -754,6 +812,10 @@ public Builder mergeFrom(org.wso2.choreo.connect.discovery.subscription.Applicat applicationUUID_ = other.applicationUUID_; onChanged(); } + if (!other.getEnvId().isEmpty()) { + envId_ = other.envId_; + onChanged(); + } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; @@ -1255,6 +1317,82 @@ public Builder setApplicationUUIDBytes( onChanged(); return this; } + + private java.lang.Object envId_ = ""; + /** + * string envId = 9; + * @return The envId. + */ + public java.lang.String getEnvId() { + java.lang.Object ref = envId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + envId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string envId = 9; + * @return The bytes for envId. + */ + public com.google.protobuf.ByteString + getEnvIdBytes() { + java.lang.Object ref = envId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + envId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string envId = 9; + * @param value The envId to set. + * @return This builder for chaining. + */ + public Builder setEnvId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + envId_ = value; + onChanged(); + return this; + } + /** + * string envId = 9; + * @return This builder for chaining. + */ + public Builder clearEnvId() { + + envId_ = getDefaultInstance().getEnvId(); + onChanged(); + return this; + } + /** + * string envId = 9; + * @param value The bytes for envId to set. + * @return This builder for chaining. + */ + public Builder setEnvIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + envId_ = value; + onChanged(); + return this; + } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { diff --git a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMappingOrBuilder.java b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMappingOrBuilder.java index 4e389552be..030db358ab 100644 --- a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMappingOrBuilder.java +++ b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMappingOrBuilder.java @@ -84,4 +84,16 @@ public interface ApplicationKeyMappingOrBuilder extends */ com.google.protobuf.ByteString getApplicationUUIDBytes(); + + /** + * string envId = 9; + * @return The envId. + */ + java.lang.String getEnvId(); + /** + * string envId = 9; + * @return The bytes for envId. + */ + com.google.protobuf.ByteString + getEnvIdBytes(); } diff --git a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMappingProto.java b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMappingProto.java index 030ff6349f..02979ba795 100644 --- a/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMappingProto.java +++ b/enforcer-parent/enforcer/src/main/gen/org/wso2/choreo/connect/discovery/subscription/ApplicationKeyMappingProto.java @@ -30,16 +30,16 @@ public static void registerAllExtensions( java.lang.String[] descriptorData = { "\n9wso2/discovery/subscription/applicatio" + "n_key_mapping.proto\022\033wso2.discovery.subs" + - "cription\"\274\001\n\025ApplicationKeyMapping\022\023\n\013co" + + "cription\"\313\001\n\025ApplicationKeyMapping\022\023\n\013co" + "nsumerKey\030\001 \001(\t\022\017\n\007keyType\030\002 \001(\t\022\022\n\nkeyM" + "anager\030\003 \001(\t\022\025\n\rapplicationId\030\004 \001(\005\022\020\n\010t" + "enantId\030\005 \001(\005\022\024\n\014tenantDomain\030\006 \001(\t\022\021\n\tt" + - "imestamp\030\007 \001(\003\022\027\n\017applicationUUID\030\010 \001(\tB" + - "\237\001\n.org.wso2.choreo.connect.discovery.su" + - "bscriptionB\032ApplicationKeyMappingProtoP\001" + - "ZOgithub.com/envoyproxy/go-control-plane" + - "/wso2/discovery/subscription;subscriptio" + - "nb\006proto3" + "imestamp\030\007 \001(\003\022\027\n\017applicationUUID\030\010 \001(\t\022" + + "\r\n\005envId\030\t \001(\tB\237\001\n.org.wso2.choreo.conne" + + "ct.discovery.subscriptionB\032ApplicationKe" + + "yMappingProtoP\001ZOgithub.com/envoyproxy/g" + + "o-control-plane/wso2/discovery/subscript" + + "ion;subscriptionb\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -50,7 +50,7 @@ public static void registerAllExtensions( internal_static_wso2_discovery_subscription_ApplicationKeyMapping_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_wso2_discovery_subscription_ApplicationKeyMapping_descriptor, - new java.lang.String[] { "ConsumerKey", "KeyType", "KeyManager", "ApplicationId", "TenantId", "TenantDomain", "Timestamp", "ApplicationUUID", }); + new java.lang.String[] { "ConsumerKey", "KeyType", "KeyManager", "ApplicationId", "TenantId", "TenantDomain", "Timestamp", "ApplicationUUID", "EnvId", }); } // @@protoc_insertion_point(outer_class_scope) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APISecurityConstants.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APISecurityConstants.java index 5157f4185e..664f9d018d 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APISecurityConstants.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APISecurityConstants.java @@ -73,6 +73,11 @@ public class APISecurityConstants { public static final String API_AUTH_INVALID_ENVIRONMENT_ERROR_MESSAGE = "The access token is not authorized " + "to access the environment."; + + public static final int API_AUTH_KEY_ENVIRONMENT_MISMATCH = 900913; + public static final String API_AUTH_KEY_ENVIRONMENT_MISMATCH_ERROR_MESSAGE = "The access token is not authorized " + + "to access the application environment."; + // We have added this because we need to add an additional description to the original one and we need to // separate the 2 messages public static final String DESCRIPTION_SEPARATOR = ". "; diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/dto/APIKeyValidationInfoDTO.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/dto/APIKeyValidationInfoDTO.java index 455b29b3ec..a3d49c7432 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/dto/APIKeyValidationInfoDTO.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/dto/APIKeyValidationInfoDTO.java @@ -67,6 +67,7 @@ public class APIKeyValidationInfoDTO implements Serializable { private String apiUUID; private String applicationUUID; private Map appAttributes; + private String envId; public List getThrottlingDataList() { return throttlingDataList; @@ -396,5 +397,15 @@ public String getApiUUID() { public void setApiUUID(String apiUUID) { this.apiUUID = apiUUID; } + + public void setEnvId(String envId) { + + this.envId = envId; + } + + public String getEnvId() { + + return envId; + } } diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/models/ApplicationKeyMapping.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/models/ApplicationKeyMapping.java index cd6a4ed438..74ffc5fffa 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/models/ApplicationKeyMapping.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/models/ApplicationKeyMapping.java @@ -31,6 +31,7 @@ public class ApplicationKeyMapping implements CacheableEntity Date: Wed, 27 Sep 2023 17:42:26 +0530 Subject: [PATCH 2/8] Improve comments --- .../connect/enforcer/security/jwt/JWTAuthenticator.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java index 16bb468621..44ea6ed2ce 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java @@ -354,9 +354,10 @@ protected void checkTokenEnvAgainstDeploymentEnv(String keyEnvId, APIConfig matc } } else { log.debug("The key is not mapped to any specific environment."); - // Check whether the application is internal. If so the environment is a mandatory parameter. - // If the application is external and key's environment is not defined, - // Allow only critical environment access. + // Check whether the application is internal. If so the environment is a mandatory parameter, + // then need to fail the access. + // If the application is external and key's environment is not defined or DEFAULT_ENV, + // then allow access only if the environment is critical. } } From b2bdbe9eb1fe88af56e71c72c78d0c42df34901f Mon Sep 17 00:00:00 2001 From: senthalan Date: Mon, 2 Oct 2023 10:03:15 +0530 Subject: [PATCH 3/8] Fix integration failure --- .../choreo/connect/enforcer/security/jwt/JWTAuthenticator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java index 44ea6ed2ce..c4ee890302 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java @@ -343,7 +343,7 @@ protected void checkTokenEnvAgainstDeploymentEnv(String keyEnvId, APIConfig matc // TODO: This needs to be changed to Choreo env. String apiEnvName = matchedAPI.getEnvironmentName(); - if (StringUtils.isNotEmpty(keyEnvId) || !StringUtils.equals(keyEnvId, "DEFAULT_ENV")) { + if (StringUtils.isNotEmpty(keyEnvId) && !StringUtils.equals(keyEnvId, "DEFAULT_ENV")) { if (StringUtils.equals(keyEnvId, apiEnvName)) { log.debug("The access token has access to the API environment {}.", apiEnvName); } else { From fa230a26f24b90db05f94b3b146a943fa75eb6c1 Mon Sep 17 00:00:00 2001 From: senthalan Date: Mon, 2 Oct 2023 11:09:08 +0530 Subject: [PATCH 4/8] Improve unit test --- .../connect/enforcer/constants/APIConstants.java | 2 +- .../enforcer/security/jwt/JWTAuthenticator.java | 3 ++- .../security/jwt/JWTAuthenticatorTest.java | 16 ++++++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APIConstants.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APIConstants.java index 1f1dc4a75f..15c0e593f4 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APIConstants.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APIConstants.java @@ -182,7 +182,7 @@ public static class JwtTokenConstants { public static final String ENV_NAME_PREFIX = "choreo:environment:"; public static final String PRODUCTION_KEY_TYPE = "PRODUCTION"; public static final String SANDBOX_KEY_TYPE = "SANDBOX"; - + public static final String DEFAULT_CHOREO_ENV_ID = "DEFAULT_ENV"; } /** diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java index c4ee890302..b73e4c32cd 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java @@ -69,6 +69,7 @@ import java.util.Set; import java.util.UUID; +import static org.wso2.choreo.connect.enforcer.constants.APIConstants.JwtTokenConstants.DEFAULT_CHOREO_ENV_ID; /** * Implements the authenticator interface to authenticate request using a JWT token. @@ -343,7 +344,7 @@ protected void checkTokenEnvAgainstDeploymentEnv(String keyEnvId, APIConfig matc // TODO: This needs to be changed to Choreo env. String apiEnvName = matchedAPI.getEnvironmentName(); - if (StringUtils.isNotEmpty(keyEnvId) && !StringUtils.equals(keyEnvId, "DEFAULT_ENV")) { + if (StringUtils.isNotEmpty(keyEnvId) && !StringUtils.equals(keyEnvId, DEFAULT_CHOREO_ENV_ID)) { if (StringUtils.equals(keyEnvId, apiEnvName)) { log.debug("The access token has access to the API environment {}.", apiEnvName); } else { diff --git a/enforcer-parent/enforcer/src/test/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticatorTest.java b/enforcer-parent/enforcer/src/test/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticatorTest.java index 6a403c5644..69c879c35c 100644 --- a/enforcer-parent/enforcer/src/test/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticatorTest.java +++ b/enforcer-parent/enforcer/src/test/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticatorTest.java @@ -40,6 +40,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import static org.wso2.choreo.connect.enforcer.constants.APIConstants.JwtTokenConstants.DEFAULT_CHOREO_ENV_ID; @RunWith(PowerMockRunner.class) @PrepareForTest({ConfigHolder.class}) @@ -114,24 +115,27 @@ public void checkTokenEnvAgainstDeploymentTypeTest() { APIConfig apiConfig = new APIConfig.Builder("testAPI") .environmentName("env-1") .build(); - validate(jwtAuthenticator, "env-1", apiConfig, false); - validate(jwtAuthenticator, "env-2", apiConfig, true); + validate(jwtAuthenticator, "env-1", apiConfig, true); + validate(jwtAuthenticator, "env-2", apiConfig, false); + validate(jwtAuthenticator, "", apiConfig, true); + validate(jwtAuthenticator, null, apiConfig, true); + validate(jwtAuthenticator, DEFAULT_CHOREO_ENV_ID, apiConfig, true); } private static void validate(JWTAuthenticator jwtAuthenticator, String keyEnv, - APIConfig apiConfig, boolean isNotValid) { + APIConfig apiConfig, boolean isValid) { try { jwtAuthenticator.checkTokenEnvAgainstDeploymentEnv(keyEnv, apiConfig); - if (isNotValid) { + if (!isValid) { fail("JWT authenticator passed the test when it should have failed"); } } catch (APISecurityException exception) { - if (isNotValid) { + if (!isValid) { assertEquals(APIConstants.StatusCodes.UNAUTHORIZED.getCode(), exception.getStatusCode()); assertEquals(APISecurityConstants.API_AUTH_KEY_ENVIRONMENT_MISMATCH, exception.getErrorCode()); } else { - fail("Expected status code and error code are not thrown"); + fail("Throwing exception when it should have passed"); } } } From e31496f9477c66af97a7efcbb6e5afb5103936f0 Mon Sep 17 00:00:00 2001 From: senthalan Date: Thu, 5 Oct 2023 19:38:54 +0530 Subject: [PATCH 5/8] Add feature flag to engage key env validation --- .../enforcer/security/jwt/JWTAuthenticator.java | 7 +++++++ .../enforcer/security/jwt/JWTAuthenticatorTest.java | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java index b73e4c32cd..ead9558e1b 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java @@ -80,6 +80,7 @@ public class JWTAuthenticator implements Authenticator { private final JWTValidator jwtValidator = new JWTValidator(); private final boolean isGatewayTokenCacheEnabled; private AbstractAPIMgtGatewayJWTGenerator jwtGenerator; + protected static final String ENABLE_KEY_ENV_VALIDATION = "enableKeyEnvValidation"; public JWTAuthenticator() { EnforcerConfig enforcerConfig = ConfigHolder.getInstance().getConfig(); @@ -342,6 +343,12 @@ public AuthenticationContext authenticate(RequestContext requestContext) throws protected void checkTokenEnvAgainstDeploymentEnv(String keyEnvId, APIConfig matchedAPI) throws APISecurityException { + // Enable Key Env validation only if system property is set. + String disableRoleValidation = System.getProperty(ENABLE_KEY_ENV_VALIDATION); + if (!Boolean.parseBoolean(disableRoleValidation)) { + return; + } + // TODO: This needs to be changed to Choreo env. String apiEnvName = matchedAPI.getEnvironmentName(); if (StringUtils.isNotEmpty(keyEnvId) && !StringUtils.equals(keyEnvId, DEFAULT_CHOREO_ENV_ID)) { diff --git a/enforcer-parent/enforcer/src/test/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticatorTest.java b/enforcer-parent/enforcer/src/test/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticatorTest.java index 69c879c35c..debc45ae48 100644 --- a/enforcer-parent/enforcer/src/test/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticatorTest.java +++ b/enforcer-parent/enforcer/src/test/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticatorTest.java @@ -18,6 +18,7 @@ package org.wso2.choreo.connect.enforcer.security.jwt; +import org.junit.After; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -41,6 +42,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.wso2.choreo.connect.enforcer.constants.APIConstants.JwtTokenConstants.DEFAULT_CHOREO_ENV_ID; +import static org.wso2.choreo.connect.enforcer.security.jwt.JWTAuthenticator.ENABLE_KEY_ENV_VALIDATION; @RunWith(PowerMockRunner.class) @PrepareForTest({ConfigHolder.class}) @@ -115,6 +117,11 @@ public void checkTokenEnvAgainstDeploymentTypeTest() { APIConfig apiConfig = new APIConfig.Builder("testAPI") .environmentName("env-1") .build(); + + // Cross environment access will be allowed when the System property is not set. + validate(jwtAuthenticator, "env-2", apiConfig, true); + + System.setProperty(ENABLE_KEY_ENV_VALIDATION, "true"); validate(jwtAuthenticator, "env-1", apiConfig, true); validate(jwtAuthenticator, "env-2", apiConfig, false); validate(jwtAuthenticator, "", apiConfig, true); @@ -122,6 +129,11 @@ public void checkTokenEnvAgainstDeploymentTypeTest() { validate(jwtAuthenticator, DEFAULT_CHOREO_ENV_ID, apiConfig, true); } + @After + public void tearDown() { + System.clearProperty(ENABLE_KEY_ENV_VALIDATION); + } + private static void validate(JWTAuthenticator jwtAuthenticator, String keyEnv, APIConfig apiConfig, boolean isValid) { From afa46ecfc4b2bad9310cdb463e0559231b07c015 Mon Sep 17 00:00:00 2001 From: senthalan Date: Fri, 13 Oct 2023 09:30:00 +0530 Subject: [PATCH 6/8] Update default env name to 'ALL' --- .../wso2/choreo/connect/enforcer/constants/APIConstants.java | 2 +- .../choreo/connect/enforcer/security/jwt/JWTAuthenticator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APIConstants.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APIConstants.java index 15c0e593f4..0499248ec6 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APIConstants.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APIConstants.java @@ -182,7 +182,7 @@ public static class JwtTokenConstants { public static final String ENV_NAME_PREFIX = "choreo:environment:"; public static final String PRODUCTION_KEY_TYPE = "PRODUCTION"; public static final String SANDBOX_KEY_TYPE = "SANDBOX"; - public static final String DEFAULT_CHOREO_ENV_ID = "DEFAULT_ENV"; + public static final String DEFAULT_CHOREO_ENV_ID = "ALL"; } /** diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java index ead9558e1b..18c91a9725 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java @@ -364,7 +364,7 @@ protected void checkTokenEnvAgainstDeploymentEnv(String keyEnvId, APIConfig matc log.debug("The key is not mapped to any specific environment."); // Check whether the application is internal. If so the environment is a mandatory parameter, // then need to fail the access. - // If the application is external and key's environment is not defined or DEFAULT_ENV, + // If the application is external and key's environment is not defined or ALL, // then allow access only if the environment is critical. } } From 50ce3f5bc6db436c243102600a0a1305a786b195 Mon Sep 17 00:00:00 2001 From: senthalan Date: Fri, 13 Oct 2023 17:13:47 +0530 Subject: [PATCH 7/8] Fix variable name --- .../connect/enforcer/security/jwt/JWTAuthenticator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java index 18c91a9725..836126839c 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java @@ -344,12 +344,12 @@ protected void checkTokenEnvAgainstDeploymentEnv(String keyEnvId, APIConfig matc throws APISecurityException { // Enable Key Env validation only if system property is set. - String disableRoleValidation = System.getProperty(ENABLE_KEY_ENV_VALIDATION); - if (!Boolean.parseBoolean(disableRoleValidation)) { + String disableKeyEnvValidation = System.getProperty(ENABLE_KEY_ENV_VALIDATION); + if (!Boolean.parseBoolean(disableKeyEnvValidation)) { return; } - // TODO: This needs to be changed to Choreo env. + // TODO(senthalan): This needs to be changed to Choreo env id when the migration is done. String apiEnvName = matchedAPI.getEnvironmentName(); if (StringUtils.isNotEmpty(keyEnvId) && !StringUtils.equals(keyEnvId, DEFAULT_CHOREO_ENV_ID)) { if (StringUtils.equals(keyEnvId, apiEnvName)) { From 9b4a6ec0148b5c82f3929d7c6b7c300fc12a19af Mon Sep 17 00:00:00 2001 From: senthalan Date: Mon, 20 Nov 2023 16:31:17 +0530 Subject: [PATCH 8/8] Enforce validation only if system flag enabled --- .../security/jwt/JWTAuthenticator.java | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java index 836126839c..a956b9c6d8 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java @@ -343,29 +343,28 @@ public AuthenticationContext authenticate(RequestContext requestContext) throws protected void checkTokenEnvAgainstDeploymentEnv(String keyEnvId, APIConfig matchedAPI) throws APISecurityException { - // Enable Key Env validation only if system property is set. - String disableKeyEnvValidation = System.getProperty(ENABLE_KEY_ENV_VALIDATION); - if (!Boolean.parseBoolean(disableKeyEnvValidation)) { - return; - } - - // TODO(senthalan): This needs to be changed to Choreo env id when the migration is done. - String apiEnvName = matchedAPI.getEnvironmentName(); - if (StringUtils.isNotEmpty(keyEnvId) && !StringUtils.equals(keyEnvId, DEFAULT_CHOREO_ENV_ID)) { - if (StringUtils.equals(keyEnvId, apiEnvName)) { - log.debug("The access token has access to the API environment {}.", apiEnvName); - } else { - log.debug("The access token does not have access to the app environment {}.", apiEnvName); - throw new APISecurityException(APIConstants.StatusCodes.UNAUTHORIZED.getCode(), - APISecurityConstants.API_AUTH_KEY_ENVIRONMENT_MISMATCH, - APISecurityConstants.API_AUTH_KEY_ENVIRONMENT_MISMATCH_ERROR_MESSAGE); - } - } else { + String apiEnvId = matchedAPI.getEnvironmentId(); + if (StringUtils.isEmpty(keyEnvId) || StringUtils.equals(keyEnvId, DEFAULT_CHOREO_ENV_ID)) { log.debug("The key is not mapped to any specific environment."); - // Check whether the application is internal. If so the environment is a mandatory parameter, - // then need to fail the access. + // In the future, + // If the application is internal (the key environment is a mandatory), + // then need to fail the access. // If the application is external and key's environment is not defined or ALL, - // then allow access only if the environment is critical. + // then allow access only if the environment is critical. + } else { + if (StringUtils.equals(keyEnvId, apiEnvId)) { + log.debug("The access token has access to the API environment {}.", apiEnvId); + } else { + log.warn("[Cross Environment Access] API: {}, API Env: {} , Key Env: {} ", + matchedAPI.getName(), apiEnvId, keyEnvId); + // Enable Key Env validation only if system property is set. + String enableKeyEnvValidation = System.getProperty(ENABLE_KEY_ENV_VALIDATION); + if (Boolean.parseBoolean(enableKeyEnvValidation)) { + throw new APISecurityException(APIConstants.StatusCodes.UNAUTHORIZED.getCode(), + APISecurityConstants.API_AUTH_KEY_ENVIRONMENT_MISMATCH, + APISecurityConstants.API_AUTH_KEY_ENVIRONMENT_MISMATCH_ERROR_MESSAGE); + } + } } }