From 9472574e1d6cb262924cda1721653e32804e9a38 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Tue, 9 Apr 2019 12:32:46 +0530 Subject: [PATCH 01/52] Refactor auth package for inbound auth --- .../{auth_store_provider.bal => auth_provider.bal} | 6 +++--- .../ballerina/auth/config_auth_store_provider.bal | 9 ++++----- .../main/ballerina/auth/{ => jwt}/jwt_common.bal | 0 .../main/ballerina/auth/{ => jwt}/jwt_issuer.bal | 0 .../ballerina/auth/{ => jwt}/jwt_validator.bal | 0 .../src/main/ballerina/auth/jwt_auth_provider.bal | 3 +-- .../ballerina/auth/ldap_auth_store_provider.bal | 14 +++++++------- 7 files changed, 15 insertions(+), 17 deletions(-) rename stdlib/auth/src/main/ballerina/auth/{auth_store_provider.bal => auth_provider.bal} (86%) rename stdlib/auth/src/main/ballerina/auth/{ => jwt}/jwt_common.bal (100%) rename stdlib/auth/src/main/ballerina/auth/{ => jwt}/jwt_issuer.bal (100%) rename stdlib/auth/src/main/ballerina/auth/{ => jwt}/jwt_validator.bal (100%) diff --git a/stdlib/auth/src/main/ballerina/auth/auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/auth_provider.bal similarity index 86% rename from stdlib/auth/src/main/ballerina/auth/auth_store_provider.bal rename to stdlib/auth/src/main/ballerina/auth/auth_provider.bal index 30acd6a9c213..25c3cf6b63f2 100644 --- a/stdlib/auth/src/main/ballerina/auth/auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/auth_provider.bal @@ -16,7 +16,7 @@ # Represents the auth store provider. Any type of implementation, such as # LDAP, JDBC, file based, etc. should be object-wise similar -public type AuthStoreProvider object { +public type AuthProvider object { # Authenticate with username and password # @@ -32,11 +32,11 @@ public type AuthStoreProvider object { public function getScopes(string username) returns string[]; }; -public function AuthStoreProvider.authenticate(string username, string password) returns boolean { +public function AuthProvider.authenticate(string username, string password) returns boolean { return true; } -public function AuthStoreProvider.getScopes(string username) returns string[] { +public function AuthProvider.getScopes(string username) returns string[] { string[] val = []; return val; } diff --git a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal index 21c9863b955f..84cebcb5bef0 100644 --- a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal @@ -22,8 +22,7 @@ import ballerina/runtime; const string CONFIG_USER_SECTION = "b7a.users"; # Represents configurations that required for Config auth store. -# -public type ConfigAuthProviderConfig record {| +public type ConfigAuthStoreProviderConfig record {| |}; # Represents Ballerina configuration file based auth store provider. @@ -31,13 +30,13 @@ public type ConfigAuthProviderConfig record {| # + configAuthProviderConfig - Config auth store configurations public type ConfigAuthStoreProvider object { - public ConfigAuthProviderConfig configAuthProviderConfig; + public ConfigAuthStoreProviderConfig configAuthStoreProviderConfig; # Create an Config auth store with the given configurations. # # + configAuthProviderConfig - Config auth store configurations - public function __init(ConfigAuthProviderConfig configAuthProviderConfig) { - self.configAuthProviderConfig = configAuthProviderConfig; + public function __init(ConfigAuthStoreProviderConfig configAuthStoreProviderConfig) { + self.configAuthStoreProviderConfig = configAuthStoreProviderConfig; } # Attempts to authenticate with username and password. diff --git a/stdlib/auth/src/main/ballerina/auth/jwt_common.bal b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_common.bal similarity index 100% rename from stdlib/auth/src/main/ballerina/auth/jwt_common.bal rename to stdlib/auth/src/main/ballerina/auth/jwt/jwt_common.bal diff --git a/stdlib/auth/src/main/ballerina/auth/jwt_issuer.bal b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_issuer.bal similarity index 100% rename from stdlib/auth/src/main/ballerina/auth/jwt_issuer.bal rename to stdlib/auth/src/main/ballerina/auth/jwt/jwt_issuer.bal diff --git a/stdlib/auth/src/main/ballerina/auth/jwt_validator.bal b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal similarity index 100% rename from stdlib/auth/src/main/ballerina/auth/jwt_validator.bal rename to stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal diff --git a/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal b/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal index 9b065c623d61..d48382d5fddf 100644 --- a/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal @@ -80,7 +80,7 @@ public type JWTAuthProvider object { } } - function authenticateFromCache(string jwtToken) returns JwtPayload|() { + function authenticateFromCache(string jwtToken) returns JwtPayload? { var cachedJwt = trap self.jwtAuthProviderConfig.jwtCache.get(jwtToken); if (cachedJwt is CachedJwt) { // convert to current time and check the expiry time @@ -94,7 +94,6 @@ public type JWTAuthProvider object { self.jwtAuthProviderConfig.jwtCache.remove(jwtToken); } } - return (); } function addToAuthenticationCache(string jwtToken, int exp, JwtPayload payload) { diff --git a/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal index da2f856649f3..a5ef161bd0fb 100644 --- a/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal @@ -41,7 +41,7 @@ import ballerina/runtime; # + retryAttempts - Retry the authentication request if a timeout happened # + secureClientSocket - The SSL configurations for the ldap client socket. This needs to be configured in order to # communicate through ldaps. -public type LdapAuthProviderConfig record {| +public type LdapAuthStoreProviderConfig record {| string domainName; string connectionURL; string connectionName; @@ -76,19 +76,19 @@ public type SecureClientSocket record {| # Represents Ballerina configuration for LDAP based auth store provider # -# + ldapAuthProviderConfig - LDAP auth store configurations +# + ldapAuthStoreProviderConfig - LDAP auth store configurations # + instanceId - Endpoint instance id public type LdapAuthStoreProvider object { - public LdapAuthProviderConfig ldapAuthProviderConfig; + public LdapAuthStoreProviderConfig ldapAuthStoreProviderConfig; public string instanceId; # Create an LDAP auth store with the given configurations. # - # + ldapAuthProviderConfig - LDAP auth store configurations + # + ldapAuthStoreProviderConfig - LDAP auth store configurations # + instanceId - Endpoint instance id - public function __init(LdapAuthProviderConfig ldapAuthProviderConfig, string instanceId) { - self.ldapAuthProviderConfig = ldapAuthProviderConfig; + public function __init(LdapAuthStoreProviderConfig ldapAuthStoreProviderConfig, string instanceId) { + self.ldapAuthStoreProviderConfig = ldapAuthStoreProviderConfig; self.instanceId = instanceId; initLdapConnectionContext(self, instanceId); } @@ -102,7 +102,7 @@ public type LdapAuthStoreProvider object { boolean isAuthenticated = self.doAuthenticate(username, password); if (isAuthenticated) { runtime:Principal principal = runtime:getInvocationContext().principal; - principal.userId = self.ldapAuthProviderConfig.domainName + ":" + username; + principal.userId = self.ldapAuthStoreProviderConfig.domainName + ":" + username; // By default set userId as username. principal.username = username; } From 08a504f44078ebbda9c4a44deb5828ff9c60754d Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Tue, 9 Apr 2019 16:59:47 +0530 Subject: [PATCH 02/52] Rename client auth config --- stdlib/http/src/main/ballerina/http/client_endpoint.bal | 6 +++--- .../http/src/main/ballerina/http/http_secure_client.bal | 8 ++++---- .../http/resiliency/failover_client_endpoint.bal | 2 +- .../http/resiliency/load_balance_client_endpoint.bal | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/stdlib/http/src/main/ballerina/http/client_endpoint.bal b/stdlib/http/src/main/ballerina/http/client_endpoint.bal index 9b58ea292ea7..686333084566 100644 --- a/stdlib/http/src/main/ballerina/http/client_endpoint.bal +++ b/stdlib/http/src/main/ballerina/http/client_endpoint.bal @@ -241,7 +241,7 @@ public type ClientEndpointConfig record {| SecureSocket? secureSocket = (); CacheConfig cache = {}; Compression compression = COMPRESSION_AUTO; - AuthConfig? auth = (); + OutboundAuthConfig? auth = (); |}; @@ -319,11 +319,11 @@ public type ProxyConfig record {| string password = ""; |}; -# The `AuthConfig` record can be used to configure the authentication mechanism used by the HTTP endpoint. +# The `OutboundAuthConfig` record can be used to configure the authentication mechanism used by the HTTP endpoint. # # + scheme - Authentication scheme # + config - Configuration related to the selected authenticator. -public type AuthConfig record {| +public type OutboundAuthConfig record {| OutboundAuthScheme scheme; BasicAuthConfig|OAuth2AuthConfig|JwtAuthConfig config?; |}; diff --git a/stdlib/http/src/main/ballerina/http/http_secure_client.bal b/stdlib/http/src/main/ballerina/http/http_secure_client.bal index 89ae142afe97..22bb5ee1604d 100644 --- a/stdlib/http/src/main/ballerina/http/http_secure_client.bal +++ b/stdlib/http/src/main/ballerina/http/http_secure_client.bal @@ -336,7 +336,7 @@ public type HttpSecureClient client object { # + return - Created secure HTTP client public function createHttpSecureClient(string url, ClientEndpointConfig config) returns Client|error { HttpSecureClient httpSecureClient; - if (config.auth is AuthConfig) { + if (config.auth is OutboundAuthConfig) { httpSecureClient = new(url, config); return httpSecureClient; } else { @@ -354,7 +354,7 @@ public function createHttpSecureClient(string url, ClientEndpointConfig config) # `error` if an error occurred during the HTTP client invocation function generateSecureRequest(Request req, ClientEndpointConfig config, CachedToken tokenCache) returns boolean|error { var auth = config.auth; - if (auth is AuthConfig) { + if (auth is OutboundAuthConfig) { var authConfig = auth["config"]; if (auth.scheme == BASIC_AUTH) { if (authConfig is BasicAuthConfig) { @@ -906,7 +906,7 @@ function updateTokenCache(json responsePayload, CachedToken tokenCache, int cloc function isRetryRequired(boolean retryRequired, Response res, ClientEndpointConfig config) returns boolean { if (retryRequired && res.statusCode == UNAUTHORIZED_401) { var auth = config.auth; - if (auth is AuthConfig) { + if (auth is OutboundAuthConfig) { var authConfig = auth.config; if (auth.scheme == OAUTH2 && authConfig is OAuth2AuthConfig) { var grantType = authConfig.grantType; @@ -935,7 +935,7 @@ function isRetryRequired(boolean retryRequired, Response res, ClientEndpointConf # + return - Returns `error` if an error occurred during the HTTP client invocation function updateRequest(Request req, ClientEndpointConfig config, CachedToken tokenCache) returns error? { var auth = config.auth; - if (auth is AuthConfig) { + if (auth is OutboundAuthConfig) { var authConfig = auth.config; if (authConfig is OAuth2AuthConfig) { string authToken; diff --git a/stdlib/http/src/main/ballerina/http/resiliency/failover_client_endpoint.bal b/stdlib/http/src/main/ballerina/http/resiliency/failover_client_endpoint.bal index 894734bf00cf..134c040f19ce 100644 --- a/stdlib/http/src/main/ballerina/http/resiliency/failover_client_endpoint.bal +++ b/stdlib/http/src/main/ballerina/http/resiliency/failover_client_endpoint.bal @@ -466,7 +466,7 @@ public type FailoverClientEndpointConfiguration record {| TargetService[] targets = []; CacheConfig cache = {}; Compression compression = COMPRESSION_AUTO; - AuthConfig? auth = (); + OutboundAuthConfig? auth = (); int[] failoverCodes = [501, 502, 503, 504]; int intervalMillis = 0; |}; diff --git a/stdlib/http/src/main/ballerina/http/resiliency/load_balance_client_endpoint.bal b/stdlib/http/src/main/ballerina/http/resiliency/load_balance_client_endpoint.bal index ab7d98b79319..2c9ab614052d 100644 --- a/stdlib/http/src/main/ballerina/http/resiliency/load_balance_client_endpoint.bal +++ b/stdlib/http/src/main/ballerina/http/resiliency/load_balance_client_endpoint.bal @@ -354,7 +354,7 @@ public type LoadBalanceClientEndpointConfiguration record {| TargetService[] targets = []; CacheConfig cache = {}; Compression compression = COMPRESSION_AUTO; - AuthConfig? auth = (); + OutboundAuthConfig? auth = (); LoadBalancerRule? lbRule = (); boolean failover = true; |}; From 3eac620969a11f4c77f5944ab59a8fea90ada452 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Wed, 10 Apr 2019 10:33:14 +0530 Subject: [PATCH 03/52] Add support for custom auth handler, provider engagement --- .../src/main/ballerina/http/annotation.bal | 27 ++- .../http/auth/auth_handler_registry.bal | 73 -------- .../main/ballerina/http/auth/authn_filter.bal | 139 ++++----------- .../ballerina/http/auth/authn_handler.bal | 3 +- .../http/auth/authn_handler_chain.bal | 85 --------- .../main/ballerina/http/auth/authz_filter.bal | 81 ++++----- .../ballerina/http/auth/authz_handler.bal | 85 ++++----- .../http/auth/basic_authn_handler.bal | 32 ++-- .../src/main/ballerina/http/auth/utils.bal | 78 +++++++-- .../main/ballerina/http/service_endpoint.bal | 163 ++++-------------- 10 files changed, 224 insertions(+), 542 deletions(-) delete mode 100644 stdlib/http/src/main/ballerina/http/auth/auth_handler_registry.bal delete mode 100644 stdlib/http/src/main/ballerina/http/auth/authn_handler_chain.bal diff --git a/stdlib/http/src/main/ballerina/http/annotation.bal b/stdlib/http/src/main/ballerina/http/annotation.bal index d2cbd8e9b1ff..1eaf2e2ec5fe 100644 --- a/stdlib/http/src/main/ballerina/http/annotation.bal +++ b/stdlib/http/src/main/ballerina/http/annotation.bal @@ -28,7 +28,7 @@ # + chunking - Configures the chunking behaviour for the service # + cors - The cross origin resource sharing configurations for the service # + versioning - The version of the service to be used -# + authConfig - Authentication configurations for securing the service +# + auth - Authentication configurations for securing the service public type HttpServiceConfig record {| Listener?[] endpoints = []; string host = "b7a.default"; @@ -37,7 +37,7 @@ public type HttpServiceConfig record {| Chunking chunking = CHUNKING_AUTO; CorsConfig cors = {}; Versioning versioning = {}; - ListenerAuthConfig? authConfig = {}; + ServiceResourceAuthConfig auth?; |}; # Configurations for CORS support. @@ -109,7 +109,7 @@ public annotation WebSocketServiceConfig WSServiceConfig; # + cors - The cross origin resource sharing configurations for the resource. If not set, the resource will inherit the CORS behaviour of the enclosing service. # + transactionInfectable - Allow to participate in the distributed transactions if value is true # + webSocketUpgrade - Annotation to define HTTP to WebSocket upgrade -# + authConfig - Authentication Configs to secure the resource +# + auth - Authentication Configs to secure the resource public type HttpResourceConfig record {| string[] methods = []; string path = ""; @@ -119,7 +119,7 @@ public type HttpResourceConfig record {| CorsConfig cors = {}; boolean transactionInfectable = true; WebSocketUpgradeConfig? webSocketUpgrade = (); - ListenerAuthConfig? authConfig = (); + ServiceResourceAuthConfig auth?; |}; # Resource configuration to upgrade from HTTP to WebSocket. @@ -133,20 +133,13 @@ public type WebSocketUpgradeConfig record {| # Configures the authentication scheme for a service or a resource. # -# + authentication - Enables/disables authentication -# + authProviders - Array of authentication provider IDs -# + scopes - Array of scopes -public type ListenerAuthConfig record {| - Authentication? authentication = (); - string[]? authProviders = (); - string[]? scopes = (); -|}; - -# Can be used for enabling/disabling authentication in an HTTP service. -# # + enabled - Specifies whether authentication is enabled -public type Authentication record {| - boolean enabled = false; +# + auth - Array of inbound authentication configurations +# + scopes - Array of scopes +public type ServiceResourceAuthConfig record {| + boolean enabled = true; + InboundAuthConfig[] auth?; + string[] scopes?; |}; # The annotation which is used to configure an HTTP resource. diff --git a/stdlib/http/src/main/ballerina/http/auth/auth_handler_registry.bal b/stdlib/http/src/main/ballerina/http/auth/auth_handler_registry.bal deleted file mode 100644 index 92be8cfc4c35..000000000000 --- a/stdlib/http/src/main/ballerina/http/auth/auth_handler_registry.bal +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -# Representation of the Http Auth Handler Registry. -# -# + httpAuthHandlers - map for auth handlers. key = auth provider id -public type AuthHandlerRegistry object { - - private map httpAuthHandlers; - - public function __init() { - self.httpAuthHandlers = {}; - } - - # Add an HttpAuthnHandler to HttpAuthHandlerRegistry - # - # + id - Auth provider id - # + authnHandler - HttpAuthnHandler instance - public function add(string id, HttpAuthnHandler authnHandler); - - # Retrieves an HttpAuthnHandler from HttpAuthHandlerRegistry which corresponds to the given id - # - # + id - Auth provider id - # + return - HttpAuthnHandler instance or nil if not found - public function get(string id) returns HttpAuthnHandler?; - - # Retrieve the HttpAuthnHandler map - # - # + return - map of HttpAuthnHandler - public function getAll() returns map; - - # Removes a specific authn handler from the HttpAuthnHandler map - public function remove(string id); - - # Removes all authn handler from the HttpAuthnHandler map - public function clear(); -}; - -public function AuthHandlerRegistry.add(string id, HttpAuthnHandler authnHandler) { - self.httpAuthHandlers[id] = authnHandler; -} - -public function AuthHandlerRegistry.get(string id) returns HttpAuthnHandler? { - if (self.httpAuthHandlers.hasKey(id)) { - return self.httpAuthHandlers[id]; - } - return (); -} - -public function AuthHandlerRegistry.getAll() returns map { - return self.httpAuthHandlers; -} - -public function AuthHandlerRegistry.remove(string id) { - _ = self.httpAuthHandlers.remove(id); -} - -public function AuthHandlerRegistry.clear() { - self.httpAuthHandlers.clear(); -} \ No newline at end of file diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal index 01a9e6e51d75..fb7b048b4c64 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal @@ -14,19 +14,18 @@ // specific language governing permissions and limitations // under the License. - import ballerina/auth; import ballerina/reflect; # Representation of the Authentication filter. # -# + authnHandlerChain - The Authentication handler chain +# + authConfig - Array of inbound authentication configurations public type AuthnFilter object { - public AuthnHandlerChain authnHandlerChain; + public InboundAuthConfig[]? authConfig; - public function __init(AuthnHandlerChain authnHandlerChain) { - self.authnHandlerChain = authnHandlerChain; + public function __init(InboundAuthConfig[]? authConfig) { + self.authConfig = authConfig; } # Request filter method which attempts to authenticated the request. @@ -36,22 +35,18 @@ public type AuthnFilter object { # + context - A filter context # + return - True if the filter succeeds public function filterRequest(Caller caller, Request request, FilterContext context) returns boolean { - // get auth config for this resource - boolean authenticated = false; - var (isSecured, authProviders) = getResourceAuthConfig(context); - if (isSecured) { - // if auth providers are there, use those to authenticate - if (authProviders.length() > 0) { - authenticated = self.authnHandlerChain.handleWithSpecificAuthnHandlers(authProviders, request); - } else { - // if not, try to authenticate using any of available authn handlers - authenticated = self.authnHandlerChain.handle(request); - } + boolean authenticated = true; + var resourceAuthConfig = getResourceAuthConfig(context); + var resourceInboundAuthConfig = resourceAuthConfig["auth"]; + if (resourceInboundAuthConfig is InboundAuthConfig[]) { + authenticated = handleAuthnRequest(resourceInboundAuthConfig, request); } else { - // not secured, no need to authenticate - return isAuthnSuccesfull(caller, true); + var authConfig = self.authConfig; + if (authConfig is InboundAuthConfig[]) { + authenticated = handleAuthnRequest(authConfig, request); + } } - return isAuthnSuccesfull(caller, authenticated); + return isAuthnSuccessful(caller, authenticated); } public function filterResponse(Response response, FilterContext context) returns boolean { @@ -59,12 +54,33 @@ public type AuthnFilter object { } }; +function handleAuthnRequest(InboundAuthConfig[] inboundAuthConfig, Request request) returns boolean { + foreach InboundAuthConfig authConfig in inboundAuthConfig { + AuthnHandler authnHandler = authConfig.authnHandler; + auth:AuthProvider[] authProviders = authConfig.authProviders; + if (authProviders.length() > 0) { + foreach auth:AuthProvider provider in authProviders { + if (authnHandler.canHandle(request)) { + boolean authnSuccessful = authnHandler.handle(request); + if (authnSuccessful) { + // If one of the authenticators from the chain could successfully authenticate the user, it is not + // required to look through other providers. The authenticator chain is using "OR" combination of + // provider results. + return true; + } + } + } + } + } + return false; +} + # Verifies if the authentication is successful. If not responds to the user. # # + caller - Caller for outbound HTTP responses # + authenticated - Authorization status for the request # + return - Authorization result to indicate if the filter can proceed(true) or not(false) -function isAuthnSuccesfull(Caller caller, boolean authenticated) returns boolean { +function isAuthnSuccessful(Caller caller, boolean authenticated) returns boolean { Response response = new; if (!authenticated) { response.statusCode = 401; @@ -77,86 +93,3 @@ function isAuthnSuccesfull(Caller caller, boolean authenticated) returns boolean } return true; } - -# Checks if the resource is secured. -# -# + context - A filter context -# + return - A tuple of whether the resource is secured and the list of auth provider ids -function getResourceAuthConfig(FilterContext context) returns (boolean, string[]) { - boolean resourceSecured; - string[] authProviderIds = []; - // get authn details from the resource level - ListenerAuthConfig? resourceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, RESOURCE_ANN_NAME, - reflect:getResourceAnnotations(context.serviceRef, context.resourceName)); - ListenerAuthConfig? serviceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, SERVICE_ANN_NAME, - reflect:getServiceAnnotations(context.serviceRef)); - // check if authentication is enabled - resourceSecured = isResourceSecured(resourceLevelAuthAnn, serviceLevelAuthAnn); - // if resource is not secured, no need to check further - if (!resourceSecured) { - return (resourceSecured, authProviderIds); - } - // check if auth providers are given at resource level - var resourceProviders = resourceLevelAuthAnn.authProviders; - if (resourceProviders is string[]) { - authProviderIds = resourceProviders; - } else { - // no auth providers found in resource level, try in service level - var serviceProviders = serviceLevelAuthAnn.authProviders; - if (serviceProviders is string[]) { - authProviderIds = serviceProviders; - } - } - return (resourceSecured, authProviderIds); -} - -function isResourceSecured(ListenerAuthConfig? resourceLevelAuthAnn, ListenerAuthConfig? serviceLevelAuthAnn) - returns boolean { - boolean isSecured; - var resourceAuthn = resourceLevelAuthAnn.authentication; - if (resourceAuthn is Authentication) { - isSecured = resourceAuthn.enabled; - } else { - // if not found at resource level, check in the service level - var serviceAuthn = serviceLevelAuthAnn.authentication; - if (serviceAuthn is Authentication) { - isSecured = serviceAuthn.enabled; - } else { - // if still authentication annotation is nil, means the user has not specified that the service - // should be secured. However since the authn filter has been engaged, need to authenticate. - isSecured = true; - } - } - return isSecured; -} - -# Tries to retrieve the annotation value for authentication hierarchically - first from the resource level and then -# from the service level, if it is not there in the resource level. -# -# + annotationModule - Annotation module name -# + annotationName - Annotation name -# + annData - Array of annotationData instances -# + return - ListenerAuthConfig instance if its defined, else nil -function getAuthAnnotation(string annotationModule, string annotationName, reflect:annotationData[] annData) - returns ListenerAuthConfig? { - if (annData.length() == 0) { - return (); - } - reflect:annotationData|() authAnn = (); - foreach var ann in annData { - if (ann.name == annotationName && ann.moduleName == annotationModule) { - authAnn = ann; - break; - } - } - if (authAnn is reflect:annotationData) { - if (annotationName == RESOURCE_ANN_NAME) { - HttpResourceConfig resourceConfig = authAnn.value; - return resourceConfig.authConfig; - } else if (annotationName == SERVICE_ANN_NAME) { - HttpServiceConfig serviceConfig = authAnn.value; - return serviceConfig.authConfig; - } - } - return (); -} diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal index ac52909c54a8..5b2c61d684db 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal @@ -14,11 +14,10 @@ // specific language governing permissions and limitations // under the License. - # Representation of Authentication handler for HTTP traffic. # # + name - Name of the http authn handler -public type HttpAuthnHandler abstract object { +public type AuthnHandler abstract object { public string name = ""; diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_handler_chain.bal b/stdlib/http/src/main/ballerina/http/auth/authn_handler_chain.bal deleted file mode 100644 index bb7110526808..000000000000 --- a/stdlib/http/src/main/ballerina/http/auth/authn_handler_chain.bal +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - - -import ballerina/auth; -import ballerina/log; - -# Representation of Authentication handler chain -# -# + authHandlerRegistry - `AuthHandlerRegistry` instance -public type AuthnHandlerChain object { - - private AuthHandlerRegistry authHandlerRegistry; - - public function __init(AuthHandlerRegistry authHandlerRegistry) { - self.authHandlerRegistry = authHandlerRegistry; - } - - # Tries to authenticate against any one of the available authentication handlers - # - # + req - `Request` instance - # + return - true if authenticated successfully, else false - public function handle(Request req) returns boolean; - - # Tries to authenticate against a specifc sub set of the authentication handlers, using the given array of auth provider ids - # - # + authProviderIds - array of auth provider ids - # + req - `Request` instance - # + return - true if authenticated successfully, else false - public function handleWithSpecificAuthnHandlers(string[] authProviderIds, Request req) returns boolean; -}; - -public function AuthnHandlerChain.handle(Request req) returns boolean { - foreach var (currentAuthProviderType, currentAuthHandler) in self.authHandlerRegistry.getAll() { - HttpAuthnHandler authnHandler = currentAuthHandler; - if (authnHandler.canHandle(req)) { - log:printDebug(function () returns string { - return "Trying to authenticate with the auth provider: " + currentAuthProviderType; - }); - boolean authnSuccessful = authnHandler.handle(req); - if (authnSuccessful) { - // If one of the authenticators from the chain could successfully authenticate the user, it is not - // required to look through other providers. The authenticator chain is using "OR" combination of - // provider results. - return true; - } - } - } - return false; -} - -public function AuthnHandlerChain.handleWithSpecificAuthnHandlers(string[] authProviderIds, Request req) - returns boolean { - foreach var authProviderId in authProviderIds { - var authnHandler = self.authHandlerRegistry.get(authProviderId); - if (authnHandler is HttpAuthnHandler) { - if (authnHandler.canHandle(req)) { - log:printDebug(function () returns string { - return "Trying to authenticate with the auth provider: " + authProviderId; - }); - boolean authnSuccessful = authnHandler.handle(req); - if (authnSuccessful) { - // If one of the authenticators from the chain could successfully authenticate the user, it is not - // required to look through other providers. The authenticator chain is using "OR" combination of - // provider results. - return true; - } - } - } - } - return false; -} diff --git a/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal index ec0e247905fd..cf203c3246cf 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal @@ -14,20 +14,22 @@ // specific language governing permissions and limitations // under the License. - import ballerina/auth; import ballerina/cache; import ballerina/reflect; # Representation of the Authorization filter # -# + authzHandler - `HttpAuthzHandler` instance for handling authorization +# + authzHandler - `AuthzHandler` instance for handling authorization +# + scopes - Array of scopes public type AuthzFilter object { - public HttpAuthzHandler authzHandler; + public AuthzHandler authzHandler; + public string[]? scopes; - public function __init(HttpAuthzHandler authzHandler) { + public function __init(AuthzHandler authzHandler, string[]? scopes) { self.authzHandler = authzHandler; + self.scopes = scopes; } # Filter function implementation which tries to authorize the request @@ -37,35 +39,19 @@ public type AuthzFilter object { # + context - `FilterContext` instance # + return - A flag to indicate if the request flow should be continued(true) or aborted(false), a code and a message public function filterRequest(Caller caller, Request request, FilterContext context) returns boolean { - // first check if the resource is marked to be authenticated. If not, no need to authorize. - ListenerAuthConfig? resourceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, RESOURCE_ANN_NAME, - reflect:getResourceAnnotations(context.serviceRef, context.resourceName)); - ListenerAuthConfig? serviceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, SERVICE_ANN_NAME, - reflect:getServiceAnnotations(context.serviceRef)); - if (!isResourceSecured(resourceLevelAuthAnn, serviceLevelAuthAnn)) { - // not secured, no need to authorize - return isAuthzSuccessfull(caller, true); - } - - string[]? scopes = getScopesForResource(resourceLevelAuthAnn, serviceLevelAuthAnn); - boolean authorized; - if (scopes is string[]) { - if (scopes.length() > 0) { - if (self.authzHandler.canHandle(request)) { - authorized = self.authzHandler.handle(runtime:getInvocationContext().principal.username, - context.serviceName, context.resourceName, request.method, scopes); - } else { - authorized = false; - } - } else { - // scopes are not defined, no need to authorize - authorized = true; - } + boolean authorized = true; + var resourceAuthConfig = getResourceAuthConfig(context); + var resourceInboundScopes = resourceAuthConfig["scopes"]; + if (resourceInboundScopes is string[]) { + authorized = handleAuthzRequest(self.authzHandler, request, context, resourceInboundScopes); } else { // scopes are not defined, no need to authorize - authorized = true; + var scopes = self.scopes; + if (scopes is string[]) { + authorized = handleAuthzRequest(self.authzHandler, request, context, scopes); + } } - return isAuthzSuccessfull(caller, authorized); + return isAuthzSuccessful(caller, authorized); } public function filterResponse(Response response, FilterContext context) returns boolean { @@ -73,13 +59,29 @@ public type AuthzFilter object { } }; +function handleAuthzRequest(AuthzHandler authzHandler, Request request, FilterContext context, string[] scopes) returns boolean { + boolean authorized = true; + if (scopes.length() > 0) { + if (authzHandler.canHandle(request)) { + authorized = authzHandler.handle(runtime:getInvocationContext().principal.username, + context.serviceName, context.resourceName, request.method, scopes); + } else { + authorized = false; + } + } else { + // scopes are not defined, no need to authorize + authorized = true; + } + return authorized; +} + # Verifies if the authorization is successful. If not responds to the user. # # + caller - Caller for outbound HTTP responses # + authorized - flag to indicate if authorization is successful or not # + return - A boolean flag to indicate if the request flow should be continued(true) or # aborted(false) -function isAuthzSuccessfull(Caller caller, boolean authorized) returns boolean { +function isAuthzSuccessful(Caller caller, boolean authorized) returns boolean { Response response = new; if (!authorized) { response.statusCode = 403; @@ -92,20 +94,3 @@ function isAuthzSuccessfull(Caller caller, boolean authorized) returns boolean { } return true; } - -# Retrieves the scope for the resource, if any -# -# + resourceLevelAuthAnn - `ListenerAuthConfig` instance denoting resource level auth annotation details -# + serviceLevelAuthAnn - `ListenerAuthConfig` instance denoting service level auth annotation details -# + return - Array of scopes for the given resource or nil of no scopes are defined -function getScopesForResource (ListenerAuthConfig? resourceLevelAuthAnn, ListenerAuthConfig? serviceLevelAuthAnn) - returns (string[]|()) { - if (resourceLevelAuthAnn.scopes is string[]) { - return resourceLevelAuthAnn.scopes; - } else { - if (serviceLevelAuthAnn.scopes is string[]) { - return serviceLevelAuthAnn.scopes; - } - return (); - } -} diff --git a/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal b/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal index 2952559eef46..7c97ae25c89f 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal @@ -14,7 +14,6 @@ // specific language governing permissions and limitations // under the License. - import ballerina/cache; import ballerina/io; import ballerina/log; @@ -22,17 +21,14 @@ import ballerina/runtime; # Representation of Authorization Handler for HTTP # -# + authStoreProvider - `AuthStoreProvider` instance # + positiveAuthzCache - `Cache` instance, which is cache positive authorizations # + negativeAuthzCache - `Cache` instance, which is cache negative authorizations -public type HttpAuthzHandler object { - public auth:AuthStoreProvider authStoreProvider; - public cache:Cache positiveAuthzCache; - public cache:Cache negativeAuthzCache; - - public function __init(auth:AuthStoreProvider authStoreProvider, cache:Cache positiveAuthzCache, - cache:Cache negativeAuthzCache) { - self.authStoreProvider = authStoreProvider; +public type AuthzHandler object { + + public cache:Cache? positiveAuthzCache; + public cache:Cache? negativeAuthzCache; + + public function __init(cache:Cache? positiveAuthzCache, cache:Cache? negativeAuthzCache) { self.positiveAuthzCache = positiveAuthzCache; self.negativeAuthzCache = negativeAuthzCache; } @@ -41,7 +37,7 @@ public type HttpAuthzHandler object { # # + req - `Request` instance # + return - true if can be authorized, else false - function canHandle(Request req) returns (boolean); + function canHandle(Request req) returns boolean; # Tries to authorize the request # @@ -51,13 +47,13 @@ public type HttpAuthzHandler object { # + method - HTTP method name # + scopes - Array of scopes # + return - true if authorization check is a success, else false - function handle(string username, string serviceName, string resourceName, string method, string[] scopes) - returns boolean; + function handle(string username, string serviceName, string resourceName, string method, string[] scopes) returns boolean; + # Tries to retrieve authorization decision from the cached information, if any # # + authzCacheKey - Cache key # + return - true or false in case of a cache hit, nil in case of a cache miss - function authorizeFromCache(string authzCacheKey) returns (boolean|()); + function authorizeFromCache(string authzCacheKey) returns boolean?; # Cached the authorization result # @@ -66,15 +62,13 @@ public type HttpAuthzHandler object { function cacheAuthzResult(string authzCacheKey, boolean authorized); }; -function HttpAuthzHandler.handle(string username, string serviceName, string resourceName, string method, - string[] scopes) returns boolean { - // first, check in the cache. cache key is ---, +function AuthzHandler.handle(string username, string serviceName, string resourceName, string method, string[] scopes) returns boolean { + // first, check in the cache. cache key is ----, // since different resources can have different scopes - string authzCacheKey = runtime:getInvocationContext().principal.userId + - "-" + serviceName + "-" + resourceName + "-" + method; + string authzCacheKey = runtime:getInvocationContext().principal.userId + "-" + serviceName + "-" + resourceName + "-" + method; string[] authCtxtScopes = runtime:getInvocationContext().principal.scopes; - //TODO: Make sure principal.scopes array is sorted to prevent cache-misses that could happen due to ordering + //TODO: Make sure principal.scopes array is sorted and set to invocation context in order to prevent cache-misses that could happen due to ordering if (authCtxtScopes.length() > 0) { authzCacheKey += "-"; foreach var authCtxtScope in authCtxtScopes { @@ -93,24 +87,9 @@ function HttpAuthzHandler.handle(string username, string serviceName, string res // cache authz result self.cacheAuthzResult(authzCacheKey, authorized); return authorized; - } else { - // no scopes found for user, try to retrieve using the auth provider - string[] scopesFromAuthProvider = self.authStoreProvider.getScopes(username); - if (scopesFromAuthProvider.length() > 0) { - boolean authorized = checkForScopeMatch(scopes, scopesFromAuthProvider, resourceName, method); - // cache authz result - self.cacheAuthzResult(authzCacheKey, authorized); - return authorized; - } else { - self.cacheAuthzResult(authzCacheKey, false); - log:printDebug(function () returns string { - return "No scopes found for user: " + username + " to access resource: " + resourceName + - ", method:" + method; - }); - return false; - } } } + return false; } # Check whether the scopes of the user and scopes of resource matches. @@ -120,8 +99,7 @@ function HttpAuthzHandler.handle(string username, string serviceName, string res # + resourceName - Name of the `resource` # + method - HTTP method name # + return - true if there is a match between resource and user scopes, else false -function checkForScopeMatch (string[] resourceScopes, string[] userScopes, string resourceName, string method) - returns boolean { +function checkForScopeMatch(string[] resourceScopes, string[] userScopes, string resourceName, string method) returns boolean { boolean authorized = matchScopes(resourceScopes, userScopes); if (authorized) { log:printDebug(function () returns string { @@ -135,7 +113,7 @@ function checkForScopeMatch (string[] resourceScopes, string[] userScopes, strin return authorized; } -function HttpAuthzHandler.authorizeFromCache(string authzCacheKey) returns (boolean|()) { +function AuthzHandler.authorizeFromCache(string authzCacheKey) returns boolean? { var positiveCacheResponse = self.positiveAuthzCache.get(authzCacheKey); if (positiveCacheResponse is boolean) { return true; @@ -144,10 +122,9 @@ function HttpAuthzHandler.authorizeFromCache(string authzCacheKey) returns (bool if (negativeCacheResponse is boolean) { return false; } - return (); } -function HttpAuthzHandler.cacheAuthzResult(string authzCacheKey, boolean authorized) { +function AuthzHandler.cacheAuthzResult(string authzCacheKey, boolean authorized) { if (authorized) { self.positiveAuthzCache.put(authzCacheKey, authorized); } else { @@ -157,22 +134,26 @@ function HttpAuthzHandler.cacheAuthzResult(string authzCacheKey, boolean authori # Tries to find a match between the two scope arrays # -# + scopesOfResource - Scopes of resource -# + scopesForRequest - Scopes of the user -# + return - true if there is a match, else false -function matchScopes(string[] scopesOfResource, string[] scopesForRequest) returns boolean { - foreach var scopeForRequest in scopesForRequest { - foreach var scopeOfResource in scopesOfResource { - if (scopeForRequest == scopeOfResource) { - // if that is equal to a group of a scope, authorization passes - return true; +# + resourceScopes - Scopes of resource +# + userScopes - Scopes of the user +# + return - true if resourceScopes is a subset of userScopes, else false +function matchScopes(string[] resourceScopes, string[] userScopes) returns boolean { + foreach var resourceScope in resourceScopes { + boolean matched = false; + foreach var userScope in userScopes { + if (resourceScope == userScope) { + matched = true; + break; } } + if (!matched) { + return false; + } } - return false; + return true; } -function HttpAuthzHandler.canHandle(Request req) returns boolean { +function AuthzHandler.canHandle(Request req) returns boolean { if (runtime:getInvocationContext().principal.username.length() == 0) { log:printError("Username not set in auth context. Unable to authorize"); return false; diff --git a/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal index 06525d12fd0b..a1463477433d 100644 --- a/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal @@ -14,7 +14,6 @@ // specific language governing permissions and limitations // under the License. - import ballerina/auth; import ballerina/encoding; import ballerina/log; @@ -26,30 +25,30 @@ const string AUTH_CACHE = "basic_auth_cache"; # Defines Basic Auth handler for HTTP traffic. # # + name - Authentication handler name -# + authStoreProvider - AuthStoreProvider instance +# + authProvider - AuthProvider instance public type HttpBasicAuthnHandler object { public string name = "basic"; - public auth:AuthStoreProvider authStoreProvider = new; + public auth:AuthProvider authProvider = new; - public function __init(auth:AuthStoreProvider authStoreProvider) { - self.authStoreProvider = authStoreProvider; + public function __init(auth:AuthProvider authProvider) { + self.authProvider = authProvider; } # Checks if the provided request can be authenticated with basic auth. # # + req - Request object # + return - `true` if it is possible authenticate with basic auth, else `false` - public function canHandle(Request req) returns (boolean); + public function canHandle(Request req) returns boolean; # Intercept requests for authentication. # # + req - Request object # + return - `true` if authentication is a success, else `false` - public function handle(Request req) returns (boolean); + public function handle(Request req) returns boolean; }; -public function HttpBasicAuthnHandler.handle(Request req) returns (boolean) { +public function HttpBasicAuthnHandler.handle(Request req) returns boolean { // extract the header value var basicAuthHeader = extractBasicAuthHeaderValue(req); string basicAuthHeaderValue = ""; @@ -62,15 +61,15 @@ public function HttpBasicAuthnHandler.handle(Request req) returns (boolean) { var credentials = extractBasicAuthCredentials(basicAuthHeaderValue); if (credentials is (string, string)) { var (username, password) = credentials; - boolean authenticated = self.authStoreProvider.authenticate(username, password); + boolean authenticated = self.authProvider.authenticate(username, password); if (authenticated) { // set username runtime:getInvocationContext().principal.username = username; // read scopes and set to the invocation context - string[] scopes = self.authStoreProvider.getScopes(username); - if (scopes.length() > 0) { + string[] scopes = self.authProvider.getScopes(username); + //if (scopes.length() > 0) { runtime:getInvocationContext().principal.scopes = scopes; - } + //} } return authenticated; } else { @@ -79,7 +78,7 @@ public function HttpBasicAuthnHandler.handle(Request req) returns (boolean) { return false; } -public function HttpBasicAuthnHandler.canHandle(Request req) returns (boolean) { +public function HttpBasicAuthnHandler.canHandle(Request req) returns boolean { var basicAuthHeader = trap req.getHeader(AUTH_HEADER); if (basicAuthHeader is string) { return basicAuthHeader.hasPrefix(AUTH_SCHEME_BASIC); @@ -93,11 +92,12 @@ public function HttpBasicAuthnHandler.canHandle(Request req) returns (boolean) { # + return - A `string` tuple with the extracted username and password or `error` that occured while extracting credentials function extractBasicAuthCredentials(string authHeader) returns (string, string)|error { // extract user credentials from basic auth header - string decodedBasicAuthHeader = encoding:byteArrayToString(check - encoding:decodeBase64(authHeader.substring(5, authHeader.length()).trim())); + string decodedBasicAuthHeader = encoding:byteArrayToString( + check encoding:decodeBase64(authHeader.substring(5, authHeader.length()).trim())); string[] decodedCredentials = decodedBasicAuthHeader.split(":"); if (decodedCredentials.length() != 2) { - return handleError("Incorrect basic authentication header format"); + error err = error(HTTP_ERROR_CODE, {message: "Incorrect basic authentication header format" }); + return err; } else { return (decodedCredentials[0], decodedCredentials[1]); } diff --git a/stdlib/http/src/main/ballerina/http/auth/utils.bal b/stdlib/http/src/main/ballerina/http/auth/utils.bal index fa2cd0a82690..a97179da8258 100644 --- a/stdlib/http/src/main/ballerina/http/auth/utils.bal +++ b/stdlib/http/src/main/ballerina/http/auth/utils.bal @@ -40,19 +40,11 @@ public const OAUTH2 = "OAUTH2"; # JWT authentication scheme. public const JWT_AUTH = "JWT_AUTH"; -# Authentication storage providers for BasicAuth scheme. -public type AuthStoreProvider CONFIG_AUTH_STORE|LDAP_AUTH_STORE; - -# Configuration file based authentication storage. -public const CONFIG_AUTH_STORE = "CONFIG_AUTH_STORE"; -# LDAP based authentication storage. -public const LDAP_AUTH_STORE = "LDAP_AUTH_STORE"; - # Extracts the basic authentication header value from the request. # # + req - Request instance # + return - Value of the basic authentication header, or nil if not found -public function extractBasicAuthHeaderValue(Request req) returns (string|()) { +public function extractBasicAuthHeaderValue(Request req) returns string? { // extract authorization header var headerValue = trap req.getHeader(AUTH_HEADER); if (headerValue is string) { @@ -63,14 +55,68 @@ public function extractBasicAuthHeaderValue(Request req) returns (string|()) { return "Error in retrieving header " + AUTH_HEADER + ": " + reason; }); } - return (); } -# Error handler. +function getResourceAuthConfig(FilterContext context) returns ServiceResourceAuthConfig? { + // get authn details from the resource level + ServiceResourceAuthConfig? resourceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, RESOURCE_ANN_NAME, + reflect:getResourceAnnotations(context.serviceRef, context.resourceName)); + ServiceResourceAuthConfig? serviceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, SERVICE_ANN_NAME, + reflect:getServiceAnnotations(context.serviceRef)); + // check if authentication is enabled + boolean resourceSecured = isResourceSecured(resourceLevelAuthAnn, serviceLevelAuthAnn); + // if resource is not secured, no need to check further + if (!resourceSecured) { + return (); + } + + // check if auth providers are given at resource level + if (resourceLevelAuthAnn is ServiceResourceAuthConfig) { + return resourceLevelAuthAnn; + } else { + // no auth providers found in resource level, try in service level + if (serviceLevelAuthAnn is ServiceResourceAuthConfig) { + return serviceLevelAuthAnn; + } + } +} + +# Tries to retrieve the annotation value for authentication hierarchically - first from the resource level and then +# from the service level, if it is not there in the resource level. # -# + message - Error message -# + return - Error populated with the message -function handleError(string message) returns (error) { - error e = error(message); - return e; +# + annotationModule - Annotation module name +# + annotationName - Annotation name +# + annData - Array of annotationData instances +# + return - ListenerAuthConfig instance if its defined, else nil +function getAuthAnnotation(string annotationModule, string annotationName, reflect:annotationData[] annData) returns ServiceResourceAuthConfig? { + if (annData.length() == 0) { + return (); + } + reflect:annotationData? authAnn = (); + foreach var ann in annData { + if (ann.name == annotationName && ann.moduleName == annotationModule) { + authAnn = ann; + break; + } + } + if (authAnn is reflect:annotationData) { + if (annotationName == RESOURCE_ANN_NAME) { + HttpResourceConfig resourceConfig = authAnn.value; + return resourceConfig.auth; + } else if (annotationName == SERVICE_ANN_NAME) { + HttpServiceConfig serviceConfig = authAnn.value; + return serviceConfig.auth; + } + } +} + +function isResourceSecured(ServiceResourceAuthConfig? resourceLevelAuthAnn, + ServiceResourceAuthConfig? serviceLevelAuthAnn) returns boolean { + boolean secured = true; + if (resourceLevelAuthAnn is ServiceResourceAuthConfig) { + secured = resourceLevelAuthAnn.enabled; + } else if (serviceLevelAuthAnn is ServiceResourceAuthConfig) { + secured = serviceLevelAuthAnn.enabled; + } + return secured; } diff --git a/stdlib/http/src/main/ballerina/http/service_endpoint.bal b/stdlib/http/src/main/ballerina/http/service_endpoint.bal index 539b3a96fe9b..dea6c6b10297 100644 --- a/stdlib/http/src/main/ballerina/http/service_endpoint.bal +++ b/stdlib/http/src/main/ballerina/http/service_endpoint.bal @@ -74,10 +74,9 @@ public type Listener object { public function Listener.init(ServiceEndpointConfiguration c) { self.config = c; - var authProviders = self.config.authProviders; - if (authProviders is AuthProvider[]) { - var providers = authProviders; - if (providers.length() > 0) { + var authConfig = self.config["auth"]; + if (authConfig is InboundAuthConfig[]) { + if (authConfig.length() > 0) { var secureSocket = self.config.secureSocket; if (secureSocket is ServiceSecureSocket) { addAuthFiltersForSecureListener(self.config, self.instanceId); @@ -141,7 +140,8 @@ public type RequestLimits record {| # + maxPipelinedRequests - Defines the maximum number of requests that can be processed at a given time on a single # connection. By default 10 requests can be pipelined on a single cinnection and user can # change this limit appropriately. This will be applicable only for HTTP 1.1 -# + authProviders - The array of authentication providers which are used to authenticate the users +# + auth - Array of inbound authentication configurations +# + scopes - Array of scopes # + positiveAuthzCache - Caching configurations for positive authorizations # + negativeAuthzCache - Caching configurations for negative authorizations public type ServiceEndpointConfiguration record {| @@ -150,14 +150,21 @@ public type ServiceEndpointConfiguration record {| ServiceSecureSocket? secureSocket = (); string httpVersion = "1.1"; RequestLimits? requestLimits = (); + //TODO: update as a optional field Filter[] filters = []; int timeoutMillis = DEFAULT_LISTENER_TIMEOUT; int maxPipelinedRequests = MAX_PIPELINED_REQUESTS; - AuthProvider[]? authProviders = (); + InboundAuthConfig[] auth?; + string[] scopes?; AuthCacheConfig positiveAuthzCache = {}; AuthCacheConfig negativeAuthzCache = {}; |}; +type InboundAuthConfig record {| + AuthnHandler authnHandler; + auth:AuthProvider[] authProviders; +|}; + # Configures the SSL/TLS options to be used for HTTP service. # # + trustStore - Configures the trust store to be used @@ -210,19 +217,6 @@ public type AuthCacheConfig record {| float evictionFactor = 1; |}; -# Configuration for authentication providers. -# -# + id - Authentication provider instance id -# + scheme - Authentication scheme -# + authStoreProvider - Authentication store provider (Config, LDAP, etc.) implementation -# + config - Configuration related to the selected authentication provider. -public type AuthProvider record {| - string id = ""; - InboundAuthScheme? scheme = (); - AuthStoreProvider? authStoreProvider = (); - auth:LdapAuthProviderConfig|auth:ConfigAuthProviderConfig|auth:JWTAuthProviderConfig? config = (); -|}; - # Defines the possible values for the keep-alive configuration in service and client endpoints. public type KeepAlive KEEPALIVE_AUTO|KEEPALIVE_ALWAYS|KEEPALIVE_NEVER; @@ -240,128 +234,37 @@ public const KEEPALIVE_NEVER = "NEVER"; function addAuthFiltersForSecureListener(ServiceEndpointConfiguration config, string instanceId) { // add authentication and authorization filters as the first two filters. // if there are any other filters specified, those should be added after the authn and authz filters. + Filter[] authFilters = []; + var authConfig = config["auth"]; + AuthnFilter authnFilter = new(authConfig); + authFilters[0] = authnFilter; + + var scopes = config["scopes"]; + cache:Cache positiveAuthzCache = new(expiryTimeMillis = config.positiveAuthzCache.expiryTimeMillis, + capacity = config.positiveAuthzCache.capacity, + evictionFactor = config.positiveAuthzCache.evictionFactor); + cache:Cache negativeAuthzCache = new(expiryTimeMillis = config.negativeAuthzCache.expiryTimeMillis, + capacity = config.negativeAuthzCache.capacity, + evictionFactor = config.negativeAuthzCache.evictionFactor); + AuthzHandler authzHandler = new(positiveAuthzCache, negativeAuthzCache); + AuthzFilter authzFilter = new(authzHandler, scopes); + authFilters[1] = authzFilter; + if (config.filters.length() == 0) { // can add authn and authz filters directly - config.filters = createAuthFiltersForSecureListener(config, instanceId); + config.filters = authFilters; } else { - Filter[] newFilters = createAuthFiltersForSecureListener(config, instanceId); + Filter[] newFilters = authFilters; // add existing filters next int i = 0; while (i < config.filters.length()) { - newFilters[i + (newFilters.length())] = config.filters[i]; - i = i + 1; + newFilters[i + (newFilters.length())] = config.filters[i]; + i = i + 1; } config.filters = newFilters; } } -# Create an array of auth and authz filters. -# -# + config - `ServiceEndpointConfiguration` instance -# + instanceId - Endpoint instance id -# + return - Array of Filters comprising of authn and authz Filters -function createAuthFiltersForSecureListener(ServiceEndpointConfiguration config, string instanceId) returns (Filter[]) { - // parse and create authentication handlers - AuthHandlerRegistry registry = new; - Filter[] authFilters = []; - var authProviderList = config.authProviders; - if (authProviderList is AuthProvider[]) { - if (authProviderList.length() > 0) { - foreach var provider in authProviderList { - if (provider.id.length() > 0) { - registry.add(provider.id, createAuthHandler(provider, instanceId)); - } else { - string providerId = system:uuid(); - registry.add(providerId, createAuthHandler(provider, instanceId)); - } - } - - AuthnHandlerChain authnHandlerChain = new(registry); - AuthnFilter authnFilter = new(authnHandlerChain); - cache:Cache positiveAuthzCache = new(expiryTimeMillis = config.positiveAuthzCache.expiryTimeMillis, - capacity = config.positiveAuthzCache.capacity, - evictionFactor = config.positiveAuthzCache.evictionFactor); - cache:Cache negativeAuthzCache = new(expiryTimeMillis = config.negativeAuthzCache.expiryTimeMillis, - capacity = config.negativeAuthzCache.capacity, - evictionFactor = config.negativeAuthzCache.evictionFactor); - auth:AuthStoreProvider authStoreProvider = new; - - foreach var provider in authProviderList { - var authProviderConfig = provider.config; - if (provider.scheme == BASIC_AUTH) { - if (provider.authStoreProvider == LDAP_AUTH_STORE) { - if (authProviderConfig is auth:LdapAuthProviderConfig) { - auth:LdapAuthStoreProvider ldapAuthStoreProvider = new(authProviderConfig, instanceId); - authStoreProvider = ldapAuthStoreProvider; - } else { - error e = error("LDAP auth provider config not provided"); - panic e; - } - } else if (provider.authStoreProvider == CONFIG_AUTH_STORE) { - auth:ConfigAuthStoreProvider configAuthStoreProvider; - if (authProviderConfig is auth:ConfigAuthProviderConfig) { - configAuthStoreProvider = new(authProviderConfig); - } else { - configAuthStoreProvider = new({}); - } - authStoreProvider = configAuthStoreProvider; - } else { - error configError = error("Unsupported auth store provider"); - panic configError; - } - } - } - - HttpAuthzHandler authzHandler = new(authStoreProvider, positiveAuthzCache, negativeAuthzCache); - AuthzFilter authzFilter = new(authzHandler); - authFilters[0] = authnFilter; - authFilters[1] = authzFilter; - } - } - return authFilters; -} - -function createAuthHandler(AuthProvider authProvider, string instanceId) returns HttpAuthnHandler { - var authProviderConfig = authProvider.config; - if (authProvider.scheme == BASIC_AUTH) { - auth:AuthStoreProvider authStoreProvider = new; - if (authProvider.authStoreProvider == CONFIG_AUTH_STORE) { - auth:ConfigAuthStoreProvider configAuthStoreProvider; - if (authProviderConfig is auth:ConfigAuthProviderConfig) { - configAuthStoreProvider = new(authProviderConfig); - } else { - configAuthStoreProvider = new({}); - } - authStoreProvider = configAuthStoreProvider; - } else if (authProvider.authStoreProvider == LDAP_AUTH_STORE) { - if (authProviderConfig is auth:LdapAuthProviderConfig) { - auth:LdapAuthStoreProvider ldapAuthStoreProvider = new(authProviderConfig, instanceId); - authStoreProvider = ldapAuthStoreProvider; - } else { - error e = error("LDAP auth provider config not provided"); - panic e; - } - } else { - error e = error("Unsupported auth store provider"); - panic e; - } - HttpBasicAuthnHandler basicAuthHandler = new(authStoreProvider); - return basicAuthHandler; - } else if (authProvider.scheme == JWT_AUTH){ - if (authProviderConfig is auth:JWTAuthProviderConfig) { - auth:JWTAuthProvider jwtAuthProvider = new(authProviderConfig); - HttpJwtAuthnHandler jwtAuthnHandler = new(jwtAuthProvider); - return jwtAuthnHandler; - } else { - error e = error("JWT auth provider config not provided"); - panic e; - } - } else { - error e = error("Unsupported auth scheme"); - panic e; - } -} - ////////////////////////////////// /// WebSocket Service Endpoint /// ////////////////////////////////// From 0826822db2a350287247817fc37bc4f18c36880e Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Wed, 10 Apr 2019 10:34:04 +0530 Subject: [PATCH 04/52] Fix websub module for auth --- .../src/main/ballerina/websub/hub_client.bal | 15 +++++++++------ .../src/main/ballerina/websub/hub_service.bal | 14 ++++++-------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/stdlib/websub/src/main/ballerina/websub/hub_client.bal b/stdlib/websub/src/main/ballerina/websub/hub_client.bal index c65f225044b5..f6d2dc594477 100644 --- a/stdlib/websub/src/main/ballerina/websub/hub_client.bal +++ b/stdlib/websub/src/main/ballerina/websub/hub_client.bal @@ -323,8 +323,9 @@ function processHubResponse(@sensitive string hub, @sensitive string mode, # + auth - The auth config to use at the hub, if specified # + return - `SubscriptionChangeResponse` indicating subscription/unsubscription details, if the request was successful # else `error` if an error occurred -function invokeClientConnectorOnRedirection(@sensitive string hub, @sensitive string mode, SubscriptionChangeRequest - subscriptionChangeRequest, http:AuthConfig? auth, int remainingRedirects) +function invokeClientConnectorOnRedirection(@sensitive string hub, @sensitive string mode, + SubscriptionChangeRequest subscriptionChangeRequest, + http:OutboundAuthConfig? auth, int remainingRedirects) returns @tainted SubscriptionChangeResponse|error { if (mode == MODE_SUBSCRIBE) { @@ -333,8 +334,9 @@ function invokeClientConnectorOnRedirection(@sensitive string hub, @sensitive st return unsubscribeWithRetries(hub, subscriptionChangeRequest, auth, remainingRedirects = remainingRedirects); } -function subscribeWithRetries(string hubUrl, SubscriptionChangeRequest subscriptionRequest, http:AuthConfig? auth, - int remainingRedirects = 0) returns @tainted SubscriptionChangeResponse| error { +function subscribeWithRetries(string hubUrl, SubscriptionChangeRequest subscriptionRequest, + http:OutboundAuthConfig? auth, int remainingRedirects = 0) + returns @tainted SubscriptionChangeResponse| error { http:Client clientEndpoint = new http:Client(hubUrl, config = { auth: auth }); http:Request builtSubscriptionRequest = buildSubscriptionChangeRequest(MODE_SUBSCRIBE, subscriptionRequest); var response = clientEndpoint->post("", builtSubscriptionRequest); @@ -342,8 +344,9 @@ function subscribeWithRetries(string hubUrl, SubscriptionChangeRequest subscript remainingRedirects); } -function unsubscribeWithRetries(string hubUrl, SubscriptionChangeRequest unsubscriptionRequest, http:AuthConfig? auth, - int remainingRedirects = 0) returns @tainted SubscriptionChangeResponse|error { +function unsubscribeWithRetries(string hubUrl, SubscriptionChangeRequest unsubscriptionRequest, + http:OutboundAuthConfig? auth, int remainingRedirects = 0) + returns @tainted SubscriptionChangeResponse|error { http:Client clientEndpoint = new http:Client(hubUrl, config = { auth: auth }); diff --git a/stdlib/websub/src/main/ballerina/websub/hub_service.bal b/stdlib/websub/src/main/ballerina/websub/hub_service.bal index 72b44ab93c1f..4749b068308b 100644 --- a/stdlib/websub/src/main/ballerina/websub/hub_service.bal +++ b/stdlib/websub/src/main/ballerina/websub/hub_service.bal @@ -29,10 +29,8 @@ map pendingRequests = {}; service hubService = @http:ServiceConfig { basePath: BASE_PATH, - authConfig: { - authentication: { - enabled: config:getAsBoolean("b7a.websub.hub.auth.enabled", defaultValue = false) - }, + auth: { + enabled: config:getAsBoolean("b7a.websub.hub.auth.enabled", defaultValue = false), scopes: getArray(config:getAsString("b7a.websub.hub.auth.scopes")) } } @@ -550,12 +548,12 @@ function buildWebSubLinkHeader(string hub, string topic) returns (string) { # Construct an array of groups from the comma separed group string passed # -# + groupString - comma separated string of groups -# + return - array of groups, nil if the groups string is empty/nil -function getArray(string groupString) returns string[]? { +# + groupString - Comma separated string of groups +# + return - Array of groups +function getArray(string groupString) returns string[] { string[] groupsArr = []; if (groupString.length() == 0) { - return (); + return groupsArr; } return groupString.split(","); } From 70979043cef92393614caaa1e0c30d5b2b11a07d Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Wed, 10 Apr 2019 11:36:58 +0530 Subject: [PATCH 05/52] Fix http unit tests for auth --- .../stdlib/auth/AuthnHandlerChainTest.java | 112 ------------------ ...erTest.java => BasicAuthnHandlerTest.java} | 4 +- .../auth/authn-handler-chain-test.bal | 67 ----------- .../test-src/auth/authn-handler-test.bal | 64 ---------- .../auth/basic-authn-handler-test.bal | 64 ++++++++++ .../test-src/auth/jwt-authn-handler-test.bal | 10 +- 6 files changed, 71 insertions(+), 250 deletions(-) delete mode 100644 stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/AuthnHandlerChainTest.java rename stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/{AuthnHandlerTest.java => BasicAuthnHandlerTest.java} (98%) delete mode 100644 stdlib/http/src/test/resources/test-src/auth/authn-handler-chain-test.bal delete mode 100644 stdlib/http/src/test/resources/test-src/auth/authn-handler-test.bal create mode 100644 stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal diff --git a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/AuthnHandlerChainTest.java b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/AuthnHandlerChainTest.java deleted file mode 100644 index 7591c4f3356c..000000000000 --- a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/AuthnHandlerChainTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.ballerinalang.stdlib.auth; - -import org.ballerinalang.config.ConfigRegistry; -import org.ballerinalang.launcher.util.BCompileUtil; -import org.ballerinalang.launcher.util.BRunUtil; -import org.ballerinalang.launcher.util.CompileResult; -import org.ballerinalang.model.values.BBoolean; -import org.ballerinalang.model.values.BMap; -import org.ballerinalang.model.values.BValue; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collections; - -/** - * Authentication handler chain Testcase. - */ -public class AuthnHandlerChainTest { - - private static final String BALLERINA_CONF = "ballerina.conf"; - private CompileResult compileResult; - private Path secretCopyPath; - - @BeforeClass - public void setup() throws IOException { - String resourceRoot = Paths.get("src", "test", "resources").toAbsolutePath().toString(); - Path sourceRoot = Paths.get(resourceRoot, "test-src", "auth"); - Path ballerinaConfPath = Paths.get(resourceRoot, "datafiles", "config", "authprovider", BALLERINA_CONF); - - // Copy the ballerina.conf to the source root before starting the tests - compileResult = BCompileUtil.compile(sourceRoot.resolve("authn-handler-chain-test.bal").toString()); - - String secretFile = "secret.txt"; - Path secretFilePath = Paths.get(resourceRoot, "datafiles", "config", secretFile); - secretCopyPath = Paths.get(resourceRoot, "datafiles", "config", "authprovider", secretFile); - Files.deleteIfExists(secretCopyPath); - copySecretFile(secretFilePath.toString(), secretCopyPath.toString()); - - // load configs - ConfigRegistry registry = ConfigRegistry.getInstance(); - registry.initRegistry(Collections.singletonMap("b7a.config.secret", secretCopyPath.toString()), - ballerinaConfPath.toString(), null); - } - - private void copySecretFile(String from, String to) throws IOException { - Files.copy(Paths.get(from), Paths.get(to)); - } - - @Test(description = "Test case for creating authn handler chain") - public void testCreateAuthnHandlerChain() { - BValue[] returns = BRunUtil.invoke(compileResult, "testCreateAuthnHandlerChain"); - Assert.assertTrue(returns[0] instanceof BMap); - Assert.assertNotNull(returns[0]); - } - - @Test(description = "Test case for authn handler chain authn failure scenario") - public void testAuthFailure() { - BValue[] returns = BRunUtil.invoke(compileResult, "testAuthFailure"); - Assert.assertTrue(returns[0] instanceof BBoolean); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); - } - - @Test(description = "Test case for authn handler chain authn failure scenario with specific handlers") - public void testAuthFailureWithSpecificHandlers() { - BValue[] returns = BRunUtil.invoke(compileResult, "testAuthFailureWithSpecificHandlers"); - Assert.assertTrue(returns[0] instanceof BBoolean); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); - } - - @Test(description = "Test case for authn handler chain authn success scenario") - public void testAuthSuccessWithSpecificHandlers() { - BValue[] returns = BRunUtil.invoke(compileResult, "testAuthSuccessWithSpecificHandlers"); - Assert.assertTrue(returns[0] instanceof BBoolean); - Assert.assertTrue(((BBoolean) returns[0]).booleanValue()); - } - - @Test(description = "Test case for authn handler chain authn success scenario with specific handlers") - public void testAuthSuccess() { - BValue[] returns = BRunUtil.invoke(compileResult, "testAuthSuccess"); - Assert.assertTrue(returns[0] instanceof BBoolean); - Assert.assertTrue(((BBoolean) returns[0]).booleanValue()); - } - - @AfterClass - public void tearDown() throws IOException { - Files.deleteIfExists(secretCopyPath); - } -} diff --git a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/AuthnHandlerTest.java b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java similarity index 98% rename from stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/AuthnHandlerTest.java rename to stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java index 8ca3a378c708..72fa4e8ce809 100644 --- a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/AuthnHandlerTest.java +++ b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java @@ -38,7 +38,7 @@ /** * Authentication handler testcase. */ -public class AuthnHandlerTest { +public class BasicAuthnHandlerTest { private static final String BALLERINA_CONF = "ballerina.conf"; private CompileResult compileResult; @@ -51,7 +51,7 @@ public void setup() throws IOException { Path ballerinaConfPath = Paths.get(resourceRoot, "datafiles", "config", "authprovider", BALLERINA_CONF); // Copy the ballerina.conf to the source root before starting the tests - compileResult = BCompileUtil.compile(sourceRoot.resolve("authn-handler-test.bal").toString()); + compileResult = BCompileUtil.compile(sourceRoot.resolve("basic-authn-handler-test.bal").toString()); String secretFile = "secret.txt"; Path secretFilePath = Paths.get(resourceRoot, "datafiles", "config", secretFile); diff --git a/stdlib/http/src/test/resources/test-src/auth/authn-handler-chain-test.bal b/stdlib/http/src/test/resources/test-src/auth/authn-handler-chain-test.bal deleted file mode 100644 index 085a929f9f3e..000000000000 --- a/stdlib/http/src/test/resources/test-src/auth/authn-handler-chain-test.bal +++ /dev/null @@ -1,67 +0,0 @@ -import ballerina/auth; -import ballerina/http; - -function testCreateAuthnHandlerChain() returns (http:AuthnHandlerChain) { - http:AuthHandlerRegistry registry = new; - http:AuthnHandlerChain authnHandlerChain = new(registry); - return authnHandlerChain; -} - -function testAuthFailure() returns (boolean) { - http:AuthHandlerRegistry registry = new; - registry.add("basicProvider1", createBasicAuthnHandler()); - http:Request inRequest = createRequest(); - string basicAutheaderValue = "123Basic xxxxx"; - inRequest.setHeader("123Authorization", basicAutheaderValue); - http:AuthnHandlerChain authnHandlerChain = new(registry); - return authnHandlerChain.handle(inRequest); -} - -function testAuthFailureWithSpecificHandlers() returns (boolean) { - http:AuthHandlerRegistry registry = new; - registry.add("basicProvider1", createBasicAuthnHandler()); - http:Request inRequest = createRequest(); - string basicAutheaderValue = "123Basic xxxxx"; - inRequest.setHeader("123Authorization", basicAutheaderValue); - http:AuthnHandlerChain authnHandlerChain = new(registry); - string[] authProviders = []; - authProviders[0] = "basicProvider1"; - return authnHandlerChain.handleWithSpecificAuthnHandlers(authProviders, inRequest); -} - -function testAuthSuccess() returns (boolean) { - http:AuthHandlerRegistry registry = new; - registry.add("basicProvider1", createBasicAuthnHandler()); - http:Request inRequest = createRequest(); - string basicAutheaderValue = "Basic aXN1cnU6eHh4"; - inRequest.setHeader("Authorization", basicAutheaderValue); - http:AuthnHandlerChain authnHandlerChain = new(registry); - return authnHandlerChain.handle(inRequest); -} - -function testAuthSuccessWithSpecificHandlers() returns (boolean) { - http:AuthHandlerRegistry registry = new; - registry.add("basicProvider1", createBasicAuthnHandler()); - http:Request inRequest = createRequest(); - string basicAutheaderValue = "Basic aXN1cnU6eHh4"; - inRequest.setHeader("Authorization", basicAutheaderValue); - http:AuthnHandlerChain authnHandlerChain = new(registry); - string[] authProviders = []; - authProviders[0] = "basicProvider1"; - return authnHandlerChain.handleWithSpecificAuthnHandlers(authProviders, inRequest); -} - -function createRequest() returns (http:Request) { - http:Request inRequest = new; - inRequest.rawPath = "/helloWorld/sayHello"; - inRequest.method = "GET"; - inRequest.httpVersion = "1.1"; - return inRequest; -} - -function createBasicAuthnHandler() returns (http:HttpAuthnHandler) { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - auth:AuthStoreProvider authStoreProvider = configAuthStoreProvider; - http:HttpBasicAuthnHandler basicAuthnHandler = new(authStoreProvider); - return basicAuthnHandler; -} diff --git a/stdlib/http/src/test/resources/test-src/auth/authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/authn-handler-test.bal deleted file mode 100644 index fded7d7fcf85..000000000000 --- a/stdlib/http/src/test/resources/test-src/auth/authn-handler-test.bal +++ /dev/null @@ -1,64 +0,0 @@ -import ballerina/auth; -import ballerina/http; - -function testCanHandleHttpBasicAuthWithoutHeader() returns (boolean) { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - auth:AuthStoreProvider authStoreProvider = configAuthStoreProvider; - http:HttpBasicAuthnHandler handler = new(authStoreProvider); - http:Request inRequest = createRequest(); - string basicAutheaderValue = "123Basic xxxxxx"; - inRequest.setHeader("123Authorization", basicAutheaderValue); - return handler.canHandle(inRequest); -} - -function testCanHandleHttpBasicAuth() returns (boolean) { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - auth:AuthStoreProvider authStoreProvider = configAuthStoreProvider; - http:HttpBasicAuthnHandler handler = new(authStoreProvider); - http:Request inRequest = createRequest(); - string basicAutheaderValue = "Basic xxxxxx"; - inRequest.setHeader("Authorization", basicAutheaderValue); - return handler.canHandle(inRequest); -} - -function testHandleHttpBasicAuthFailure() returns (boolean) { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - auth:AuthStoreProvider authStoreProvider = configAuthStoreProvider; - http:HttpBasicAuthnHandler handler = new(authStoreProvider); - http:Request inRequest = createRequest(); - string basicAutheaderValue = "Basic YW1pbGE6cHFy"; - inRequest.setHeader("Authorization", basicAutheaderValue); - return handler.handle(inRequest); -} - -function testHandleHttpBasicAuth() returns (boolean) { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - auth:AuthStoreProvider authStoreProvider = configAuthStoreProvider; - http:HttpBasicAuthnHandler handler = new(authStoreProvider); - http:Request inRequest = createRequest(); - string basicAutheaderValue = "Basic aXN1cnU6eHh4"; - inRequest.setHeader("Authorization", basicAutheaderValue); - return handler.handle(inRequest); -} - -function testNonExistingBasicAuthHeaderValue() returns (string|()) { - // create dummy request - http:Request inRequest = createRequest(); - return http:extractBasicAuthHeaderValue(inRequest); -} - -function testExtractBasicAuthHeaderValue() returns (string|()) { - // create dummy request - http:Request inRequest = createRequest(); - string basicAutheaderValue = "Basic aXN1cnU6eHh4"; - inRequest.setHeader("Authorization", basicAutheaderValue); - return http:extractBasicAuthHeaderValue(inRequest); -} - -function createRequest() returns (http:Request) { - http:Request inRequest = new; - inRequest.rawPath = "/helloWorld/sayHello"; - inRequest.method = "GET"; - inRequest.httpVersion = "1.1"; - return inRequest; -} diff --git a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal new file mode 100644 index 000000000000..c35dcc93f338 --- /dev/null +++ b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal @@ -0,0 +1,64 @@ +import ballerina/auth; +import ballerina/http; + +function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { + auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:AuthProvider authProvider = configAuthStoreProvider; + http:HttpBasicAuthnHandler handler = new(authProvider); + http:Request inRequest = createRequest(); + string basicAuthHeaderValue = "123Basic xxxxxx"; + inRequest.setHeader("123Authorization", basicAuthHeaderValue); + return handler.canHandle(inRequest); +} + +function testCanHandleHttpBasicAuth() returns boolean { + auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:AuthProvider authProvider = configAuthStoreProvider; + http:HttpBasicAuthnHandler handler = new(authProvider); + http:Request inRequest = createRequest(); + string basicAuthHeaderValue = "Basic xxxxxx"; + inRequest.setHeader("Authorization", basicAuthHeaderValue); + return handler.canHandle(inRequest); +} + +function testHandleHttpBasicAuthFailure() returns boolean { + auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:AuthProvider authProvider = configAuthStoreProvider; + http:HttpBasicAuthnHandler handler = new(authProvider); + http:Request inRequest = createRequest(); + string basicAuthHeaderValue = "Basic YW1pbGE6cHFy"; + inRequest.setHeader("Authorization", basicAuthHeaderValue); + return handler.handle(inRequest); +} + +function testHandleHttpBasicAuth() returns boolean { + auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:AuthProvider authProvider = configAuthStoreProvider; + http:HttpBasicAuthnHandler handler = new(authProvider); + http:Request inRequest = createRequest(); + string basicAuthHeaderValue = "Basic aXN1cnU6eHh4"; + inRequest.setHeader("Authorization", basicAuthHeaderValue); + return handler.handle(inRequest); +} + +function testNonExistingBasicAuthHeaderValue() returns string? { + // create dummy request + http:Request inRequest = createRequest(); + return http:extractBasicAuthHeaderValue(inRequest); +} + +function testExtractBasicAuthHeaderValue() returns string? { + // create dummy request + http:Request inRequest = createRequest(); + string basicAuthHeaderValue = "Basic aXN1cnU6eHh4"; + inRequest.setHeader("Authorization", basicAuthHeaderValue); + return http:extractBasicAuthHeaderValue(inRequest); +} + +function createRequest() returns http:Request { + http:Request inRequest = new; + inRequest.rawPath = "/helloWorld/sayHello"; + inRequest.method = "GET"; + inRequest.httpVersion = "1.1"; + return inRequest; +} diff --git a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal index be8786aa751f..6b371cdb264d 100644 --- a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal @@ -2,7 +2,7 @@ import ballerina/auth; import ballerina/http; import ballerina/crypto; -function testCanHandleHttpJwtAuthWithoutHeader() returns (boolean) { +function testCanHandleHttpJwtAuthWithoutHeader() returns boolean { http:HttpJwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Basic xxxxxx"; @@ -10,7 +10,7 @@ function testCanHandleHttpJwtAuthWithoutHeader() returns (boolean) { return handler.canHandle(request); } -function testCanHandleHttpJwtAuth() returns (boolean) { +function testCanHandleHttpJwtAuth() returns boolean { http:HttpJwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Bearer xxx.yyy.zzz"; @@ -18,7 +18,7 @@ function testCanHandleHttpJwtAuth() returns (boolean) { return handler.canHandle(request); } -function testHandleHttpJwtAuthFailure() returns (boolean) { +function testHandleHttpJwtAuthFailure() returns boolean { http:HttpJwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Bearer xxx.yyy.zzz"; @@ -26,7 +26,7 @@ function testHandleHttpJwtAuthFailure() returns (boolean) { return handler.handle(request); } -function testHandleHttpJwtAuth(string token, string trustStorePath) returns (boolean) { +function testHandleHttpJwtAuth(string token, string trustStorePath) returns boolean { http:HttpJwtAuthnHandler handler = new(createJwtAuthProvider(trustStorePath)); http:Request request = createRequest(); string authHeaderValue = "Bearer " + token; @@ -34,7 +34,7 @@ function testHandleHttpJwtAuth(string token, string trustStorePath) returns (boo return handler.handle(request); } -function createRequest() returns (http:Request) { +function createRequest() returns http:Request { http:Request inRequest = new; inRequest.rawPath = "/helloWorld/sayHello"; inRequest.method = "GET"; From 75360e1ee3bb370403c75910b5df4d85ae821e4a Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Wed, 10 Apr 2019 12:59:58 +0530 Subject: [PATCH 06/52] Refactor auth config records --- .../src/main/ballerina/http/annotation.bal | 12 +-- .../main/ballerina/http/auth/authn_filter.bal | 11 +-- .../src/main/ballerina/http/auth/utils.bal | 20 ++--- .../main/ballerina/http/service_endpoint.bal | 90 +++++++++++-------- 4 files changed, 72 insertions(+), 61 deletions(-) diff --git a/stdlib/http/src/main/ballerina/http/annotation.bal b/stdlib/http/src/main/ballerina/http/annotation.bal index 1eaf2e2ec5fe..67ce1d3fa3c9 100644 --- a/stdlib/http/src/main/ballerina/http/annotation.bal +++ b/stdlib/http/src/main/ballerina/http/annotation.bal @@ -28,7 +28,7 @@ # + chunking - Configures the chunking behaviour for the service # + cors - The cross origin resource sharing configurations for the service # + versioning - The version of the service to be used -# + auth - Authentication configurations for securing the service +# + auth - Authentication configurations for secure the service public type HttpServiceConfig record {| Listener?[] endpoints = []; string host = "b7a.default"; @@ -37,7 +37,7 @@ public type HttpServiceConfig record {| Chunking chunking = CHUNKING_AUTO; CorsConfig cors = {}; Versioning versioning = {}; - ServiceResourceAuthConfig auth?; + ServiceResourceAuth auth?; |}; # Configurations for CORS support. @@ -119,7 +119,7 @@ public type HttpResourceConfig record {| CorsConfig cors = {}; boolean transactionInfectable = true; WebSocketUpgradeConfig? webSocketUpgrade = (); - ServiceResourceAuthConfig auth?; + ServiceResourceAuth auth?; |}; # Resource configuration to upgrade from HTTP to WebSocket. @@ -134,11 +134,11 @@ public type WebSocketUpgradeConfig record {| # Configures the authentication scheme for a service or a resource. # # + enabled - Specifies whether authentication is enabled -# + auth - Array of inbound authentication configurations +# + authConfig - Array of inbound authentication configurations # + scopes - Array of scopes -public type ServiceResourceAuthConfig record {| +public type ServiceResourceAuth record {| boolean enabled = true; - InboundAuthConfig[] auth?; + InboundAuthConfig[] authConfig?; string[] scopes?; |}; diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal index fb7b048b4c64..92e73135b59f 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal @@ -22,9 +22,9 @@ import ballerina/reflect; # + authConfig - Array of inbound authentication configurations public type AuthnFilter object { - public InboundAuthConfig[]? authConfig; + public InboundAuthConfig[] authConfig; - public function __init(InboundAuthConfig[]? authConfig) { + public function __init(InboundAuthConfig[] authConfig) { self.authConfig = authConfig; } @@ -37,14 +37,11 @@ public type AuthnFilter object { public function filterRequest(Caller caller, Request request, FilterContext context) returns boolean { boolean authenticated = true; var resourceAuthConfig = getResourceAuthConfig(context); - var resourceInboundAuthConfig = resourceAuthConfig["auth"]; + var resourceInboundAuthConfig = resourceAuthConfig["authConfig"]; if (resourceInboundAuthConfig is InboundAuthConfig[]) { authenticated = handleAuthnRequest(resourceInboundAuthConfig, request); } else { - var authConfig = self.authConfig; - if (authConfig is InboundAuthConfig[]) { - authenticated = handleAuthnRequest(authConfig, request); - } + authenticated = handleAuthnRequest(self.authConfig, request); } return isAuthnSuccessful(caller, authenticated); } diff --git a/stdlib/http/src/main/ballerina/http/auth/utils.bal b/stdlib/http/src/main/ballerina/http/auth/utils.bal index a97179da8258..c2234903dbef 100644 --- a/stdlib/http/src/main/ballerina/http/auth/utils.bal +++ b/stdlib/http/src/main/ballerina/http/auth/utils.bal @@ -57,11 +57,11 @@ public function extractBasicAuthHeaderValue(Request req) returns string? { } } -function getResourceAuthConfig(FilterContext context) returns ServiceResourceAuthConfig? { +function getResourceAuthConfig(FilterContext context) returns ServiceResourceAuth? { // get authn details from the resource level - ServiceResourceAuthConfig? resourceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, RESOURCE_ANN_NAME, + ServiceResourceAuth? resourceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, RESOURCE_ANN_NAME, reflect:getResourceAnnotations(context.serviceRef, context.resourceName)); - ServiceResourceAuthConfig? serviceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, SERVICE_ANN_NAME, + ServiceResourceAuth? serviceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, SERVICE_ANN_NAME, reflect:getServiceAnnotations(context.serviceRef)); // check if authentication is enabled boolean resourceSecured = isResourceSecured(resourceLevelAuthAnn, serviceLevelAuthAnn); @@ -71,11 +71,11 @@ function getResourceAuthConfig(FilterContext context) returns ServiceResourceAut } // check if auth providers are given at resource level - if (resourceLevelAuthAnn is ServiceResourceAuthConfig) { + if (resourceLevelAuthAnn is ServiceResourceAuth) { return resourceLevelAuthAnn; } else { // no auth providers found in resource level, try in service level - if (serviceLevelAuthAnn is ServiceResourceAuthConfig) { + if (serviceLevelAuthAnn is ServiceResourceAuth) { return serviceLevelAuthAnn; } } @@ -88,7 +88,7 @@ function getResourceAuthConfig(FilterContext context) returns ServiceResourceAut # + annotationName - Annotation name # + annData - Array of annotationData instances # + return - ListenerAuthConfig instance if its defined, else nil -function getAuthAnnotation(string annotationModule, string annotationName, reflect:annotationData[] annData) returns ServiceResourceAuthConfig? { +function getAuthAnnotation(string annotationModule, string annotationName, reflect:annotationData[] annData) returns ServiceResourceAuth? { if (annData.length() == 0) { return (); } @@ -110,12 +110,12 @@ function getAuthAnnotation(string annotationModule, string annotationName, refle } } -function isResourceSecured(ServiceResourceAuthConfig? resourceLevelAuthAnn, - ServiceResourceAuthConfig? serviceLevelAuthAnn) returns boolean { +function isResourceSecured(ServiceResourceAuth? resourceLevelAuthAnn, + ServiceResourceAuth? serviceLevelAuthAnn) returns boolean { boolean secured = true; - if (resourceLevelAuthAnn is ServiceResourceAuthConfig) { + if (resourceLevelAuthAnn is ServiceResourceAuth) { secured = resourceLevelAuthAnn.enabled; - } else if (serviceLevelAuthAnn is ServiceResourceAuthConfig) { + } else if (serviceLevelAuthAnn is ServiceResourceAuth) { secured = serviceLevelAuthAnn.enabled; } return secured; diff --git a/stdlib/http/src/main/ballerina/http/service_endpoint.bal b/stdlib/http/src/main/ballerina/http/service_endpoint.bal index dea6c6b10297..d942a6459d6b 100644 --- a/stdlib/http/src/main/ballerina/http/service_endpoint.bal +++ b/stdlib/http/src/main/ballerina/http/service_endpoint.bal @@ -74,12 +74,12 @@ public type Listener object { public function Listener.init(ServiceEndpointConfiguration c) { self.config = c; - var authConfig = self.config["auth"]; - if (authConfig is InboundAuthConfig[]) { - if (authConfig.length() > 0) { + var auth = self.config["auth"]; + if (auth is ListenerAuth) { + if (auth.authConfig.length() > 0) { var secureSocket = self.config.secureSocket; if (secureSocket is ServiceSecureSocket) { - addAuthFiltersForSecureListener(self.config, self.instanceId); + addAuthFiltersForSecureListener(self.config); } else { error err = error("Secure sockets have not been cofigured in order to enable auth providers."); panic err; @@ -140,10 +140,7 @@ public type RequestLimits record {| # + maxPipelinedRequests - Defines the maximum number of requests that can be processed at a given time on a single # connection. By default 10 requests can be pipelined on a single cinnection and user can # change this limit appropriately. This will be applicable only for HTTP 1.1 -# + auth - Array of inbound authentication configurations -# + scopes - Array of scopes -# + positiveAuthzCache - Caching configurations for positive authorizations -# + negativeAuthzCache - Caching configurations for negative authorizations +# + auth - Listener authenticaton configurations public type ServiceEndpointConfiguration record {| string host = "0.0.0.0"; KeepAlive keepAlive = KEEPALIVE_AUTO; @@ -154,13 +151,27 @@ public type ServiceEndpointConfiguration record {| Filter[] filters = []; int timeoutMillis = DEFAULT_LISTENER_TIMEOUT; int maxPipelinedRequests = MAX_PIPELINED_REQUESTS; - InboundAuthConfig[] auth?; + ListenerAuth auth?; +|}; + +# Authentication configurations for the listener. +# +# + authConfig - Array of inbound authentication configurations +# + scopes - Array of scopes +# + positiveAuthzCache - Caching configurations for positive authorizations +# + negativeAuthzCache - Caching configurations for negative authorizations +public type ListenerAuth record {| + InboundAuthConfig[] authConfig; string[] scopes?; AuthCacheConfig positiveAuthzCache = {}; AuthCacheConfig negativeAuthzCache = {}; |}; -type InboundAuthConfig record {| +# Inbound authentication configurations with handlers and providers. +# +# + authnHandler - Authentication handler +# + authProviders - Array of auth providers +public type InboundAuthConfig record {| AuthnHandler authnHandler; auth:AuthProvider[] authProviders; |}; @@ -230,38 +241,41 @@ public const KEEPALIVE_NEVER = "NEVER"; # Add authn and authz filters # # + config - `ServiceEndpointConfiguration` instance -# + instanceId - Endpoint instance id -function addAuthFiltersForSecureListener(ServiceEndpointConfiguration config, string instanceId) { +function addAuthFiltersForSecureListener(ServiceEndpointConfiguration config) { // add authentication and authorization filters as the first two filters. // if there are any other filters specified, those should be added after the authn and authz filters. Filter[] authFilters = []; - var authConfig = config["auth"]; - AuthnFilter authnFilter = new(authConfig); - authFilters[0] = authnFilter; - - var scopes = config["scopes"]; - cache:Cache positiveAuthzCache = new(expiryTimeMillis = config.positiveAuthzCache.expiryTimeMillis, - capacity = config.positiveAuthzCache.capacity, - evictionFactor = config.positiveAuthzCache.evictionFactor); - cache:Cache negativeAuthzCache = new(expiryTimeMillis = config.negativeAuthzCache.expiryTimeMillis, - capacity = config.negativeAuthzCache.capacity, - evictionFactor = config.negativeAuthzCache.evictionFactor); - AuthzHandler authzHandler = new(positiveAuthzCache, negativeAuthzCache); - AuthzFilter authzFilter = new(authzHandler, scopes); - authFilters[1] = authzFilter; - - if (config.filters.length() == 0) { - // can add authn and authz filters directly - config.filters = authFilters; - } else { - Filter[] newFilters = authFilters; - // add existing filters next - int i = 0; - while (i < config.filters.length()) { - newFilters[i + (newFilters.length())] = config.filters[i]; - i = i + 1; + + var auth = config["auth"]; + if (auth is ListenerAuth) { + InboundAuthConfig[] authConfig = auth.authConfig; + AuthnFilter authnFilter = new(authConfig); + authFilters[0] = authnFilter; + + var scopes = auth["scopes"]; + cache:Cache positiveAuthzCache = new(expiryTimeMillis = auth.positiveAuthzCache.expiryTimeMillis, + capacity = auth.positiveAuthzCache.capacity, + evictionFactor = auth.positiveAuthzCache.evictionFactor); + cache:Cache negativeAuthzCache = new(expiryTimeMillis = auth.negativeAuthzCache.expiryTimeMillis, + capacity = auth.negativeAuthzCache.capacity, + evictionFactor = auth.negativeAuthzCache.evictionFactor); + AuthzHandler authzHandler = new(positiveAuthzCache, negativeAuthzCache); + AuthzFilter authzFilter = new(authzHandler, scopes); + authFilters[1] = authzFilter; + + if (config.filters.length() == 0) { + // can add authn and authz filters directly + config.filters = authFilters; + } else { + Filter[] newFilters = authFilters; + // add existing filters next + int i = 0; + while (i < config.filters.length()) { + newFilters[i + (newFilters.length())] = config.filters[i]; + i = i + 1; + } + config.filters = newFilters; } - config.filters = newFilters; } } From 0cea25c3a9b15d09b9895e6e960846a962c5fc02 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 11 Apr 2019 10:36:44 +0530 Subject: [PATCH 07/52] Fix auth providers with object similarity --- .../src/main/ballerina/auth/auth_provider.bal | 30 ++----- .../auth/config_auth_store_provider.bal | 57 ++++++++---- .../main/ballerina/auth/jwt_auth_provider.bal | 15 ++-- .../auth/ldap_auth_store_provider.bal | 39 ++++---- .../stdlib/auth/ConfigAuthProviderTest.java | 43 +++------ .../test-src/config_auth_provider_test.bal | 89 +++++++++++-------- 6 files changed, 142 insertions(+), 131 deletions(-) diff --git a/stdlib/auth/src/main/ballerina/auth/auth_provider.bal b/stdlib/auth/src/main/ballerina/auth/auth_provider.bal index 25c3cf6b63f2..79df104b8a59 100644 --- a/stdlib/auth/src/main/ballerina/auth/auth_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/auth_provider.bal @@ -14,29 +14,13 @@ // specific language governing permissions and limitations // under the License. -# Represents the auth store provider. Any type of implementation, such as -# LDAP, JDBC, file based, etc. should be object-wise similar -public type AuthProvider object { +# Represents the auth provider. Any type of implementation, such as LDAP, JDBC, file based, etc. +# should be object-wise similar +public type AuthProvider abstract object { - # Authenticate with username and password + # Authenticate with credential value passed. # - # + username - user name - # + password - password - # + return - true if authentication is a success, else false - public function authenticate(string username, string password) returns boolean; - - # Reads the scope(s) for the user with the given username - # - # + username - user name - # + return - array of groups for the user denoted by the username - public function getScopes(string username) returns string[]; + # + credential - Credential value + # + return - True if authentication is a success, else false or `error` occurred + public function authenticate(string credential) returns boolean|error; }; - -public function AuthProvider.authenticate(string username, string password) returns boolean { - return true; -} - -public function AuthProvider.getScopes(string username) returns string[] { - string[] val = []; - return val; -} diff --git a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal index 84cebcb5bef0..281b04a33606 100644 --- a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal @@ -27,9 +27,11 @@ public type ConfigAuthStoreProviderConfig record {| # Represents Ballerina configuration file based auth store provider. # -# + configAuthProviderConfig - Config auth store configurations +# + configAuthStoreProviderConfig - Config auth store configurations public type ConfigAuthStoreProvider object { + *AuthProvider; + public ConfigAuthStoreProviderConfig configAuthStoreProviderConfig; # Create an Config auth store with the given configurations. @@ -39,16 +41,18 @@ public type ConfigAuthStoreProvider object { self.configAuthStoreProviderConfig = configAuthStoreProviderConfig; } - # Attempts to authenticate with username and password. + # Attempts to authenticate with credential. # - # + user - user name - # + password - password - # + return - true if authentication is a success, else false - public function authenticate(string user, string password) returns boolean { - if (user == EMPTY_STRING || password == EMPTY_STRING) { + # + credential - Credential + # + return - True if authentication is a success, else false or `error` that occured while extracting credentials + public function authenticate(string credential) returns boolean|error { + if (credential == EMPTY_STRING) { return false; } - string passwordFromConfig = self.readPassword(user); + string username; + string password; + (username, password) = check extractCredentials(credential); + string passwordFromConfig = self.readPassword(username); boolean isAuthenticated = false; // This check is added to avoid having to go through multiple condition evaluations, when value is plain text. if (passwordFromConfig.hasPrefix(CONFIG_PREFIX)) { @@ -69,34 +73,34 @@ public type ConfigAuthStoreProvider object { } if (isAuthenticated) { runtime:Principal principal = runtime:getInvocationContext().principal; - principal.userId = user; - principal.username = user; + principal.userId = username; + principal.username = username; } return isAuthenticated; } # Extract password hash from the configuration file. # - # + configValue - config value to extract the password from - # + return - password hash extracted from the configuration field + # + configValue - Config value to extract the password from + # + return - Password hash extracted from the configuration field public function extractHash(string configValue) returns string { return configValue.substring(configValue.indexOf("{") + 1, configValue.lastIndexOf("}")); } # Reads the scope(s) for the user with the given username. # - # + username - username - # + return - array of groups for the user denoted by the username + # + username - Username + # + return - Array of groups for the user denoted by the username public function getScopes(string username) returns string[] { // first read the user id from user->id mapping - // reads the groups for the userid + // reads the groups for the user-id return self.getArray(self.getConfigAuthValue(CONFIG_USER_SECTION + "." + username, "scopes")); } # Reads the password hash for a user. # - # + username - username - # + return - password hash read from userstore, or nil if not found + # + username - Username + # + return - Password hash read from userstore, or nil if not found public function readPassword(string username) returns string { // first read the user id from user->id mapping // read the hashed password from the userstore file, using the user id @@ -109,8 +113,8 @@ public type ConfigAuthStoreProvider object { # Construct an array of groups from the comma separed group string passed. # - # + groupString - comma separated string of groups - # + return - array of groups, nil if the groups string is empty/nil + # + groupString - Comma separated string of groups + # + return - Array of groups, nil if the groups string is empty/nil public function getArray(string groupString) returns (string[]) { string[] groupsArr = []; if (groupString.length() == 0) { @@ -119,3 +123,18 @@ public type ConfigAuthStoreProvider object { return groupString.split(","); } }; + +# Extracts the username and password from credential value. +# +# + credential - Credential value +# + return - A `string` tuple with the extracted username and password or `error` that occured while extracting credentials +function extractCredentials(string credential) returns (string, string)|error { + string decodedHeaderValue = encoding:byteArrayToString(check encoding:decodeBase64(credential)); + string[] decodedCredentials = decodedHeaderValue.split(":"); + if (decodedCredentials.length() != 2) { + error err = error(AUTH_ERROR_CODE, {message: "Incorrect credential format" }); + return err; + } else { + return (decodedCredentials[0], decodedCredentials[1]); + } +} diff --git a/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal b/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal index d48382d5fddf..8b0b52d71e52 100644 --- a/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal @@ -19,23 +19,24 @@ import ballerina/log; import ballerina/runtime; import ballerina/time; -# Represents a JWT Authenticator -# +# Represents a JWT Authenticator. public type JWTAuthProvider object { + *AuthProvider; + public JWTAuthProviderConfig jwtAuthProviderConfig; - # Provides authentication based on the provided jwt token + # Provides authentication based on the provided jwt token. # # + jwtAuthProviderConfig - JWT authentication provider configurations public function __init(JWTAuthProviderConfig jwtAuthProviderConfig) { self.jwtAuthProviderConfig = jwtAuthProviderConfig; } - # Authenticate with a jwt token + # Authenticate with a jwt token. # # + jwtToken - Jwt token extracted from the authentication header - # + return - true if authentication is successful, false otherwise. + # + return - True if authentication is successful, false otherwise. # If an error occur during authentication, the error will be returned. public function authenticate(string jwtToken) returns boolean|error { if (self.jwtAuthProviderConfig.jwtCache.hasKey(jwtToken)) { @@ -134,7 +135,7 @@ const string GROUPS = "groups"; const string USERNAME = "name"; const string AUTH_TYPE_JWT = "jwt"; -# Represents JWT validator configurations +# Represents JWT validator configurations. # # + issuer - Identifier of the token issuer # + audience - Identifier of the token recipients @@ -153,7 +154,7 @@ public type JWTAuthProviderConfig record {| cache:Cache jwtCache = new; |}; -# Represents parsed and cached JWT +# Represents parsed and cached JWT. # # + jwtPayload - Parsed JWT payload # + expiryTime - Expiry time of the JWT diff --git a/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal index a5ef161bd0fb..1e0e9260326d 100644 --- a/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal @@ -74,12 +74,14 @@ public type SecureClientSocket record {| string trustedCertFile = ""; |}; -# Represents Ballerina configuration for LDAP based auth store provider +# Represents Ballerina configuration for LDAP based auth store provider. # # + ldapAuthStoreProviderConfig - LDAP auth store configurations # + instanceId - Endpoint instance id public type LdapAuthStoreProvider object { + *AuthProvider; + public LdapAuthStoreProviderConfig ldapAuthStoreProviderConfig; public string instanceId; @@ -93,12 +95,17 @@ public type LdapAuthStoreProvider object { initLdapConnectionContext(self, instanceId); } - # Authenticate with username and password + # Authenticate with username and password. # - # + username - user name - # + password - password - # + return - true if authentication is a success, else false - public function authenticate(string username, string password) returns boolean { + # + credential - Credential value + # + return - True if authentication is a success, else false or `error` that occured while extracting credentials + public function authenticate(string credential) returns boolean|error { + if (credential == EMPTY_STRING) { + return false; + } + string username; + string password; + (username, password) = check extractCredentials(credential); boolean isAuthenticated = self.doAuthenticate(username, password); if (isAuthenticated) { runtime:Principal principal = runtime:getInvocationContext().principal; @@ -109,30 +116,30 @@ public type LdapAuthStoreProvider object { return isAuthenticated; } - # Reads the scope(s) for the user with the given username + # Reads the scope(s) for the user with the given username. # - # + username - username - # + return - array of groups for the user denoted by the username + # + username - Username + # + return - Array of groups for the user denoted by the username public function getScopes(string username) returns string[] { // Reads the groups for the username return self.getScopesOfUser(username); } - # Authenticate with username and password + # Authenticate with username and password. # - # + username - user name - # + password - password + # + username - Username + # + password - Password # + return - true if authentication is a success, else false public function doAuthenticate(string username, string password) returns boolean = external; - # Reads the scope(s) for the user with the given username + # Reads the scope(s) for the user with the given username. # - # + username - username - # + return - array of groups for the user denoted by the username + # + username - Username + # + return - Array of groups for the user denoted by the username public function getScopesOfUser(string username) returns string[] = external; }; -# Initailizes LDAP connection context +# Initailizes LDAP connection context. # # + ldapAuthStoreProvider - LdapAuthStoreProvider provider object # + instanceId - Unique id generated to identify an endpoint diff --git a/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java b/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java index 6ab4addc99c8..a6893377620c 100644 --- a/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java +++ b/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java @@ -81,94 +81,77 @@ public void testCreateConfigAuthProvider() { public void testAuthenticationOfNonExistingUser() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationOfNonExistingUser"); Assert.assertNotNull(returns); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for authenticating with invalid password") public void testAuthenticationOfNonExistingPassword() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationOfNonExistingPassword"); Assert.assertNotNull(returns); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for successful authentication") public void testAuthentication() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthentication"); Assert.assertNotNull(returns); - Assert.assertTrue(((BBoolean) returns[0]).booleanValue()); - } - - @Test(description = "Test case for reading groups of non-existing user") - public void testReadScopesOfNonExistingUser() { - BValue[] returns = BRunUtil.invoke(compileResult, "testReadScopesOfNonExistingUser"); - Assert.assertNotNull(returns); - Assert.assertEquals(((BValueArray) returns[0]).size(), 0); - } - - @Test(description = "Test case for reading groups of a user") - public void testReadScopesOfUser() { - BValue[] returns = BRunUtil.invoke(compileResult, "testReadScopesOfUser"); - Assert.assertNotNull(returns); - BValueArray groups = ((BValueArray) returns[0]); - Assert.assertEquals(groups.size(), 1); - - Assert.assertEquals(groups.getString(0), "scope1"); + Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for unsuccessful authentication when username is empty") public void testAuthenticationWithEmptyUsername() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationWithEmptyUsername"); Assert.assertNotNull(returns); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for unsuccessful authentication when password is empty") public void testAuthenticationWithEmptyPassword() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationWithEmptyPassword"); Assert.assertNotNull(returns); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for unsuccessful authentication when password is empty and username is invalid") public void testAuthenticationWithEmptyPasswordAndInvalidUsername() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationWithEmptyPasswordAndInvalidUsername"); Assert.assertNotNull(returns); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for unsuccessful authentication when username and password are empty") public void testAuthenticationWithEmptyUsernameAndEmptyPassword() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationWithEmptyUsernameAndEmptyPassword"); Assert.assertNotNull(returns); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for successful authentication with sha-256 hashed password") public void testAuthenticationSha256() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationSha256"); Assert.assertNotNull(returns); - Assert.assertTrue(((BBoolean) returns[0]).booleanValue()); + Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for successful authentication with sha-384 hashed password") public void testAuthenticationSha384() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationSha384"); Assert.assertNotNull(returns); - Assert.assertTrue(((BBoolean) returns[0]).booleanValue()); + Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for successful authentication with sha-512 hashed password") public void testAuthenticationSha512() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationSha512"); Assert.assertNotNull(returns); - Assert.assertTrue(((BBoolean) returns[0]).booleanValue()); + Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for successful authentication with plain text password") public void testAuthenticationPlain() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationPlain"); Assert.assertNotNull(returns); - Assert.assertTrue(((BBoolean) returns[0]).booleanValue()); + Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for unsuccessful authentication with sha-512 hashed password, using invalid " + @@ -176,14 +159,14 @@ public void testAuthenticationPlain() { public void testAuthenticationSha512Negative() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationSha512Negative"); Assert.assertNotNull(returns); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for unsuccessful authentication with plain text password, using invalid password") public void testAuthenticationPlainNegative() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationPlainNegative"); Assert.assertNotNull(returns); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); } @AfterClass diff --git a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal index bfaf430623a7..2d211eb03abf 100644 --- a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal +++ b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal @@ -15,83 +15,100 @@ // under the License. import ballerina/auth; +import ballerina/encoding; function testCreateConfigAuthProvider() returns (auth:ConfigAuthStoreProvider) { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); return configAuthStoreProvider; } -function testAuthenticationOfNonExistingUser() returns (boolean) { +function testAuthenticationOfNonExistingUser() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("amila", "abc"); + string usernameAndPassword = "amila:abc"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthenticationOfNonExistingPassword() returns (boolean) { +function testAuthenticationOfNonExistingPassword() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("isuru", "xxy"); + string usernameAndPassword = "isuru:xxy"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthentication() returns (boolean) { +function testAuthentication() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("isuru", "xxx"); + string usernameAndPassword = "isuru:xxx"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testReadScopesOfNonExistingUser() returns (string[]) { +function testAuthenticationWithEmptyUsername() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.getScopes("amila"); + string usernameAndPassword = ":xxx"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testReadScopesOfUser() returns (string[]) { +function testAuthenticationWithEmptyPassword() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.getScopes("ishara"); + string usernameAndPassword = "isuru:"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthenticationWithEmptyUsername() returns (boolean) { +function testAuthenticationWithEmptyPasswordAndInvalidUsername() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("", "xxx"); + string usernameAndPassword = "invalid:"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthenticationWithEmptyPassword() returns (boolean) { +function testAuthenticationWithEmptyUsernameAndEmptyPassword() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("isuru", ""); + string usernameAndPassword = ":"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthenticationWithEmptyPasswordAndInvalidUsername() returns (boolean) { +function testAuthenticationSha256() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("invalid", ""); + string usernameAndPassword = "hashedSha256:xxx"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthenticationWithEmptyUsernameAndEmptyPassword() returns (boolean) { +function testAuthenticationSha384() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("", ""); + string usernameAndPassword = "hashedSha384:xxx"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthenticationSha256() returns (boolean) { +function testAuthenticationSha512() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("hashedSha256", "xxx"); + string usernameAndPassword = "hashedSha512:xxx"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthenticationSha384() returns (boolean) { +function testAuthenticationPlain() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("hashedSha384", "xxx"); + string usernameAndPassword = "plain:plainpassword"; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthenticationSha512() returns (boolean) { +function testAuthenticationSha512Negative() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("hashedSha512", "xxx"); + string usernameAndPassword = "hashedSha512:xxx "; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } -function testAuthenticationPlain() returns (boolean) { +function testAuthenticationPlainNegative() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("plain", "plainpassword"); -} - -function testAuthenticationSha512Negative() returns (boolean) { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("hashedSha512", "xxx "); -} - -function testAuthenticationPlainNegative() returns (boolean) { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); - return configAuthStoreProvider.authenticate("plain", "plainpassword "); + string usernameAndPassword = "plain:plainpassword "; + string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); + return configAuthStoreProvider.authenticate(credential); } From b90072d4ab5326cc2788a3c0e76983f35849f3b2 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 11 Apr 2019 17:19:31 +0530 Subject: [PATCH 08/52] Refactor auth package --- .../auth/config_auth_store_provider.bal | 86 ++++++--------- .../main/ballerina/auth/jwt_auth_provider.bal | 103 +++++++++--------- .../auth/ldap_auth_store_provider.bal | 16 +-- .../auth/{auth_constants.bal => utils.bal} | 17 +++ .../ldap/nativeimpl/GetLdapScopesOfUser.java | 2 +- .../test-src/config_auth_provider_test.bal | 2 +- 6 files changed, 110 insertions(+), 116 deletions(-) rename stdlib/auth/src/main/ballerina/auth/{auth_constants.bal => utils.bal} (64%) diff --git a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal index 281b04a33606..4d883c68ad1d 100644 --- a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal @@ -44,27 +44,27 @@ public type ConfigAuthStoreProvider object { # Attempts to authenticate with credential. # # + credential - Credential - # + return - True if authentication is a success, else false or `error` that occured while extracting credentials + # + return - True if authentication is a success, else false or `error` occured while extracting credentials public function authenticate(string credential) returns boolean|error { if (credential == EMPTY_STRING) { return false; } string username; string password; - (username, password) = check extractCredentials(credential); - string passwordFromConfig = self.readPassword(username); + (username, password) = check extractUsernameAndPassword(credential); + string passwordFromConfig = readPassword(username); boolean isAuthenticated = false; // This check is added to avoid having to go through multiple condition evaluations, when value is plain text. if (passwordFromConfig.hasPrefix(CONFIG_PREFIX)) { if (passwordFromConfig.hasPrefix(CONFIG_PREFIX_SHA256)) { isAuthenticated = encoding:encodeHex(crypto:hashSha256(password.toByteArray(DEFAULT_CHARSET))) - .equalsIgnoreCase(self.extractHash(passwordFromConfig)); + .equalsIgnoreCase(extractHash(passwordFromConfig)); } else if (passwordFromConfig.hasPrefix(CONFIG_PREFIX_SHA384)) { isAuthenticated = encoding:encodeHex(crypto:hashSha384(password.toByteArray(DEFAULT_CHARSET))) - .equalsIgnoreCase(self.extractHash(passwordFromConfig)); + .equalsIgnoreCase(extractHash(passwordFromConfig)); } else if (passwordFromConfig.hasPrefix(CONFIG_PREFIX_SHA512)) { isAuthenticated = encoding:encodeHex(crypto:hashSha512(password.toByteArray(DEFAULT_CHARSET))) - .equalsIgnoreCase(self.extractHash(passwordFromConfig)); + .equalsIgnoreCase(extractHash(passwordFromConfig)); } else { isAuthenticated = password == passwordFromConfig; } @@ -75,18 +75,11 @@ public type ConfigAuthStoreProvider object { runtime:Principal principal = runtime:getInvocationContext().principal; principal.userId = username; principal.username = username; + principal.scopes = self.getScopes(username); } return isAuthenticated; } - # Extract password hash from the configuration file. - # - # + configValue - Config value to extract the password from - # + return - Password hash extracted from the configuration field - public function extractHash(string configValue) returns string { - return configValue.substring(configValue.indexOf("{") + 1, configValue.lastIndexOf("}")); - } - # Reads the scope(s) for the user with the given username. # # + username - Username @@ -94,47 +87,40 @@ public type ConfigAuthStoreProvider object { public function getScopes(string username) returns string[] { // first read the user id from user->id mapping // reads the groups for the user-id - return self.getArray(self.getConfigAuthValue(CONFIG_USER_SECTION + "." + username, "scopes")); + return getArray(getConfigAuthValue(CONFIG_USER_SECTION + "." + username, "scopes")); } +}; - # Reads the password hash for a user. - # - # + username - Username - # + return - Password hash read from userstore, or nil if not found - public function readPassword(string username) returns string { - // first read the user id from user->id mapping - // read the hashed password from the userstore file, using the user id - return self.getConfigAuthValue(CONFIG_USER_SECTION + "." + username, "password"); - } +# Extract password hash from the configuration file. +# +# + configValue - Config value to extract the password from +# + return - Password hash extracted from the configuration field +function extractHash(string configValue) returns string { + return configValue.substring(configValue.indexOf("{") + 1, configValue.lastIndexOf("}")); +} - public function getConfigAuthValue(string instanceId, string property) returns string { - return config:getAsString(instanceId + "." + property, defaultValue = ""); - } +# Reads the password hash for a user. +# +# + username - Username +# + return - Password hash read from userstore, or nil if not found +function readPassword(string username) returns string { + // first read the user id from user->id mapping + // read the hashed password from the userstore file, using the user id + return getConfigAuthValue(CONFIG_USER_SECTION + "." + username, "password"); +} - # Construct an array of groups from the comma separed group string passed. - # - # + groupString - Comma separated string of groups - # + return - Array of groups, nil if the groups string is empty/nil - public function getArray(string groupString) returns (string[]) { - string[] groupsArr = []; - if (groupString.length() == 0) { - return groupsArr; - } - return groupString.split(","); - } -}; +function getConfigAuthValue(string instanceId, string property) returns string { + return config:getAsString(instanceId + "." + property, defaultValue = ""); +} -# Extracts the username and password from credential value. +# Construct an array of groups from the comma separed group string passed. # -# + credential - Credential value -# + return - A `string` tuple with the extracted username and password or `error` that occured while extracting credentials -function extractCredentials(string credential) returns (string, string)|error { - string decodedHeaderValue = encoding:byteArrayToString(check encoding:decodeBase64(credential)); - string[] decodedCredentials = decodedHeaderValue.split(":"); - if (decodedCredentials.length() != 2) { - error err = error(AUTH_ERROR_CODE, {message: "Incorrect credential format" }); - return err; - } else { - return (decodedCredentials[0], decodedCredentials[1]); +# + groupString - Comma separated string of groups +# + return - Array of groups, nil if the groups string is empty/nil +function getArray(string groupString) returns string[] { + string[] groupsArr = []; + if (groupString.length() == 0) { + return groupsArr; } + return groupString.split(","); } diff --git a/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal b/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal index 8b0b52d71e52..4b5627c128d2 100644 --- a/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal @@ -40,9 +40,9 @@ public type JWTAuthProvider object { # If an error occur during authentication, the error will be returned. public function authenticate(string jwtToken) returns boolean|error { if (self.jwtAuthProviderConfig.jwtCache.hasKey(jwtToken)) { - var payload = self.authenticateFromCache(jwtToken); + var payload = authenticateFromCache(self.jwtAuthProviderConfig, jwtToken); if (payload is JwtPayload) { - self.setAuthenticationContext(payload, jwtToken); + setAuthenticationContext(payload, jwtToken); return true; } else { return false; @@ -73,61 +73,13 @@ public type JWTAuthProvider object { var payload = validateJwt(jwtToken, jwtValidatorConfig); if (payload is JwtPayload) { - self.setAuthenticationContext(payload, jwtToken); - self.addToAuthenticationCache(jwtToken, payload.exp, payload); + setAuthenticationContext(payload, jwtToken); + addToAuthenticationCache(self.jwtAuthProviderConfig, jwtToken, payload.exp, payload); return true; } else { return payload; } } - - function authenticateFromCache(string jwtToken) returns JwtPayload? { - var cachedJwt = trap self.jwtAuthProviderConfig.jwtCache.get(jwtToken); - if (cachedJwt is CachedJwt) { - // convert to current time and check the expiry time - if (cachedJwt.expiryTime > (time:currentTime().time / 1000)) { - JwtPayload payload = cachedJwt.jwtPayload; - log:printDebug(function() returns string { - return "Authenticate user :" + payload.sub + " from cache"; - }); - return payload; - } else { - self.jwtAuthProviderConfig.jwtCache.remove(jwtToken); - } - } - } - - function addToAuthenticationCache(string jwtToken, int exp, JwtPayload payload) { - CachedJwt cachedJwt = {jwtPayload : payload, expiryTime : exp}; - self.jwtAuthProviderConfig.jwtCache.put(jwtToken, cachedJwt); - log:printDebug(function() returns string { - return "Add authenticated user :" + payload.sub + " to the cache"; - }); - } - - function setAuthenticationContext(JwtPayload jwtPayload, string jwtToken) { - runtime:Principal principal = runtime:getInvocationContext().principal; - principal.userId = jwtPayload.iss + ":" + jwtPayload.sub; - // By default set sub as username. - principal.username = jwtPayload.sub; - principal.claims = jwtPayload.customClaims; - if (jwtPayload.customClaims.hasKey(SCOPES)) { - var scopeString = jwtPayload.customClaims[SCOPES]; - if (scopeString is string) { - principal.scopes = scopeString.split(" "); - } - } - if (jwtPayload.customClaims.hasKey(USERNAME)) { - var name = jwtPayload.customClaims[USERNAME]; - if (name is string) { - principal.username = name; - } - } - runtime:AuthenticationContext authenticationContext = runtime:getInvocationContext().authenticationContext; - authenticationContext.scheme = AUTH_TYPE_JWT; - authenticationContext.authToken = jwtToken; - } - }; const string SCOPES = "scope"; @@ -162,3 +114,50 @@ public type CachedJwt record {| JwtPayload jwtPayload; int expiryTime; |}; + +function authenticateFromCache(JWTAuthProviderConfig jwtAuthProviderConfig, string jwtToken) returns JwtPayload? { + var cachedJwt = trap jwtAuthProviderConfig.jwtCache.get(jwtToken); + if (cachedJwt is CachedJwt) { + // convert to current time and check the expiry time + if (cachedJwt.expiryTime > (time:currentTime().time / 1000)) { + JwtPayload payload = cachedJwt.jwtPayload; + log:printDebug(function() returns string { + return "Authenticate user :" + payload.sub + " from cache"; + }); + return payload; + } else { + jwtAuthProviderConfig.jwtCache.remove(jwtToken); + } + } +} + +function addToAuthenticationCache(JWTAuthProviderConfig jwtAuthProviderConfig, string jwtToken, int exp, JwtPayload payload) { + CachedJwt cachedJwt = {jwtPayload : payload, expiryTime : exp}; + jwtAuthProviderConfig.jwtCache.put(jwtToken, cachedJwt); + log:printDebug(function() returns string { + return "Add authenticated user :" + payload.sub + " to the cache"; + }); +} + +function setAuthenticationContext(JwtPayload jwtPayload, string jwtToken) { + runtime:Principal principal = runtime:getInvocationContext().principal; + principal.userId = jwtPayload.iss + ":" + jwtPayload.sub; + // By default set sub as username. + principal.username = jwtPayload.sub; + principal.claims = jwtPayload.customClaims; + if (jwtPayload.customClaims.hasKey(SCOPES)) { + var scopeString = jwtPayload.customClaims[SCOPES]; + if (scopeString is string) { + principal.scopes = scopeString.split(" "); + } + } + if (jwtPayload.customClaims.hasKey(USERNAME)) { + var name = jwtPayload.customClaims[USERNAME]; + if (name is string) { + principal.username = name; + } + } + runtime:AuthenticationContext authenticationContext = runtime:getInvocationContext().authenticationContext; + authenticationContext.scheme = AUTH_TYPE_JWT; + authenticationContext.authToken = jwtToken; +} diff --git a/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal index 1e0e9260326d..9a4a6fe0c416 100644 --- a/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal @@ -98,20 +98,21 @@ public type LdapAuthStoreProvider object { # Authenticate with username and password. # # + credential - Credential value - # + return - True if authentication is a success, else false or `error` that occured while extracting credentials + # + return - True if authentication is a success, else false or `error` occured while extracting credentials public function authenticate(string credential) returns boolean|error { if (credential == EMPTY_STRING) { return false; } string username; string password; - (username, password) = check extractCredentials(credential); + (username, password) = check extractUsernameAndPassword(credential); boolean isAuthenticated = self.doAuthenticate(username, password); if (isAuthenticated) { runtime:Principal principal = runtime:getInvocationContext().principal; principal.userId = self.ldapAuthStoreProviderConfig.domainName + ":" + username; // By default set userId as username. principal.username = username; + principal.scopes = self.getScopes(username); } return isAuthenticated; } @@ -120,10 +121,7 @@ public type LdapAuthStoreProvider object { # # + username - Username # + return - Array of groups for the user denoted by the username - public function getScopes(string username) returns string[] { - // Reads the groups for the username - return self.getScopesOfUser(username); - } + public function getScopes(string username) returns string[] = external; # Authenticate with username and password. # @@ -131,12 +129,6 @@ public type LdapAuthStoreProvider object { # + password - Password # + return - true if authentication is a success, else false public function doAuthenticate(string username, string password) returns boolean = external; - - # Reads the scope(s) for the user with the given username. - # - # + username - Username - # + return - Array of groups for the user denoted by the username - public function getScopesOfUser(string username) returns string[] = external; }; # Initailizes LDAP connection context. diff --git a/stdlib/auth/src/main/ballerina/auth/auth_constants.bal b/stdlib/auth/src/main/ballerina/auth/utils.bal similarity index 64% rename from stdlib/auth/src/main/ballerina/auth/auth_constants.bal rename to stdlib/auth/src/main/ballerina/auth/utils.bal index 88352af9ad3c..1a01b8f1dd46 100644 --- a/stdlib/auth/src/main/ballerina/auth/auth_constants.bal +++ b/stdlib/auth/src/main/ballerina/auth/utils.bal @@ -14,6 +14,8 @@ // specific language governing permissions and limitations // under the License. +import ballerina/encoding; + # Constant for the auth error code. public const AUTH_ERROR_CODE = "{ballerina/auth}AuthError"; @@ -34,3 +36,18 @@ public const string CONFIG_PREFIX_SHA384 = "@sha384:"; # Prefix used to denote that the config value is a SHA-512 hash. public const string CONFIG_PREFIX_SHA512 = "@sha512:"; + +# Extracts the username and password from credential value. +# +# + credential - Credential value +# + return - A `string` tuple with the extracted username and password or `error` occured while extracting credentials +function extractUsernameAndPassword(string credential) returns (string, string)|error { + string decodedHeaderValue = encoding:byteArrayToString(check encoding:decodeBase64(credential)); + string[] decodedCredentials = decodedHeaderValue.split(":"); + if (decodedCredentials.length() != 2) { + error err = error(AUTH_ERROR_CODE, {message: "Incorrect credential format. Format should be username:password" }); + return err; + } else { + return (decodedCredentials[0], decodedCredentials[1]); + } +} diff --git a/stdlib/auth/src/main/java/org/ballerinalang/auth/ldap/nativeimpl/GetLdapScopesOfUser.java b/stdlib/auth/src/main/java/org/ballerinalang/auth/ldap/nativeimpl/GetLdapScopesOfUser.java index 4b36f1e779c2..57b1a55562e6 100644 --- a/stdlib/auth/src/main/java/org/ballerinalang/auth/ldap/nativeimpl/GetLdapScopesOfUser.java +++ b/stdlib/auth/src/main/java/org/ballerinalang/auth/ldap/nativeimpl/GetLdapScopesOfUser.java @@ -55,7 +55,7 @@ */ @BallerinaFunction( orgName = "ballerina", packageName = "auth", - functionName = "LdapAuthStoreProvider.getScopesOfUser", + functionName = "LdapAuthStoreProvider.getScopes", args = {@Argument(name = "username", type = TypeKind.STRING)}, returnType = {@ReturnType(type = TypeKind.ARRAY, elementType = TypeKind.STRING)}, isPublic = true) diff --git a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal index 2d211eb03abf..77da6dad7365 100644 --- a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal +++ b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/encoding; -function testCreateConfigAuthProvider() returns (auth:ConfigAuthStoreProvider) { +function testCreateConfigAuthProvider() returns auth:ConfigAuthStoreProvider { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); return configAuthStoreProvider; } From ce3d083ce13102635696f9df7b4e55fec2df50db Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 11 Apr 2019 18:02:23 +0530 Subject: [PATCH 09/52] Change custom handler engagement --- .../src/main/ballerina/http/annotation.bal | 4 +- .../main/ballerina/http/auth/authn_filter.bal | 42 +++++----- .../ballerina/http/auth/authn_handler.bal | 4 - .../main/ballerina/http/auth/authz_filter.bal | 2 +- .../http/auth/basic_authn_handler.bal | 79 +++++-------------- .../ballerina/http/auth/jwt_authn_handler.bal | 46 +++++------ .../src/main/ballerina/http/auth/utils.bal | 26 ++++-- .../main/ballerina/http/service_endpoint.bal | 20 ++--- .../auth/basic-authn-handler-test.bal | 8 +- .../test-src/auth/jwt-authn-handler-test.bal | 8 +- 10 files changed, 94 insertions(+), 145 deletions(-) diff --git a/stdlib/http/src/main/ballerina/http/annotation.bal b/stdlib/http/src/main/ballerina/http/annotation.bal index 67ce1d3fa3c9..d85271cf8b16 100644 --- a/stdlib/http/src/main/ballerina/http/annotation.bal +++ b/stdlib/http/src/main/ballerina/http/annotation.bal @@ -134,11 +134,11 @@ public type WebSocketUpgradeConfig record {| # Configures the authentication scheme for a service or a resource. # # + enabled - Specifies whether authentication is enabled -# + authConfig - Array of inbound authentication configurations +# + authnHandlers - Array of authentication handlers # + scopes - Array of scopes public type ServiceResourceAuth record {| boolean enabled = true; - InboundAuthConfig[] authConfig?; + AuthnHandler[] authnHandlers?; string[] scopes?; |}; diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal index 92e73135b59f..8fcaaa99ad9f 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal @@ -19,13 +19,13 @@ import ballerina/reflect; # Representation of the Authentication filter. # -# + authConfig - Array of inbound authentication configurations +# + authnHandlers - Array of authentication handlers public type AuthnFilter object { - public InboundAuthConfig[] authConfig; + public AuthnHandler[] authnHandlers; - public function __init(InboundAuthConfig[] authConfig) { - self.authConfig = authConfig; + public function __init(AuthnHandler[] authnHandlers) { + self.authnHandlers = authnHandlers; } # Request filter method which attempts to authenticated the request. @@ -36,12 +36,12 @@ public type AuthnFilter object { # + return - True if the filter succeeds public function filterRequest(Caller caller, Request request, FilterContext context) returns boolean { boolean authenticated = true; - var resourceAuthConfig = getResourceAuthConfig(context); - var resourceInboundAuthConfig = resourceAuthConfig["authConfig"]; - if (resourceInboundAuthConfig is InboundAuthConfig[]) { - authenticated = handleAuthnRequest(resourceInboundAuthConfig, request); + var resourceAuthConfig = getServiceResourceAuthConfig(context); + var resourceAuthHandlers = resourceAuthConfig["authnHandlers"]; + if (resourceAuthHandlers is AuthnHandler[]) { + authenticated = handleAuthnRequest(resourceAuthHandlers, request); } else { - authenticated = handleAuthnRequest(self.authConfig, request); + authenticated = handleAuthnRequest(self.authnHandlers, request); } return isAuthnSuccessful(caller, authenticated); } @@ -51,21 +51,15 @@ public type AuthnFilter object { } }; -function handleAuthnRequest(InboundAuthConfig[] inboundAuthConfig, Request request) returns boolean { - foreach InboundAuthConfig authConfig in inboundAuthConfig { - AuthnHandler authnHandler = authConfig.authnHandler; - auth:AuthProvider[] authProviders = authConfig.authProviders; - if (authProviders.length() > 0) { - foreach auth:AuthProvider provider in authProviders { - if (authnHandler.canHandle(request)) { - boolean authnSuccessful = authnHandler.handle(request); - if (authnSuccessful) { - // If one of the authenticators from the chain could successfully authenticate the user, it is not - // required to look through other providers. The authenticator chain is using "OR" combination of - // provider results. - return true; - } - } +function handleAuthnRequest(AuthnHandler[] authnHandlers, Request request) returns boolean { + foreach AuthnHandler authnHandler in authnHandlers { + if (authnHandler.canHandle(request)) { + boolean authnSuccessful = authnHandler.handle(request); + if (authnSuccessful) { + // If one of the authenticators from the chain could successfully authenticate the user, it is not + // required to look through other providers. The authenticator chain is using "OR" combination of + // provider results. + return true; } } } diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal index 5b2c61d684db..7f8865482af9 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal @@ -15,12 +15,8 @@ // under the License. # Representation of Authentication handler for HTTP traffic. -# -# + name - Name of the http authn handler public type AuthnHandler abstract object { - public string name = ""; - # Checks if the request can be authenticated with the relevant `HttpAuthnHandler` implementation # # + req - `Request` instance diff --git a/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal index cf203c3246cf..abec0928aae4 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal @@ -40,7 +40,7 @@ public type AuthzFilter object { # + return - A flag to indicate if the request flow should be continued(true) or aborted(false), a code and a message public function filterRequest(Caller caller, Request request, FilterContext context) returns boolean { boolean authorized = true; - var resourceAuthConfig = getResourceAuthConfig(context); + var resourceAuthConfig = getServiceResourceAuthConfig(context); var resourceInboundScopes = resourceAuthConfig["scopes"]; if (resourceInboundScopes is string[]) { authorized = handleAuthzRequest(self.authzHandler, request, context, resourceInboundScopes); diff --git a/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal index a1463477433d..a309b66f99b3 100644 --- a/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal @@ -19,86 +19,49 @@ import ballerina/encoding; import ballerina/log; import ballerina/runtime; -# Authentication cache name. -const string AUTH_CACHE = "basic_auth_cache"; - # Defines Basic Auth handler for HTTP traffic. # -# + name - Authentication handler name # + authProvider - AuthProvider instance -public type HttpBasicAuthnHandler object { +public type BasicAuthnHandler object { + + *AuthnHandler; - public string name = "basic"; - public auth:AuthProvider authProvider = new; + public auth:AuthProvider authProvider; public function __init(auth:AuthProvider authProvider) { self.authProvider = authProvider; } - - # Checks if the provided request can be authenticated with basic auth. - # - # + req - Request object - # + return - `true` if it is possible authenticate with basic auth, else `false` - public function canHandle(Request req) returns boolean; - - # Intercept requests for authentication. - # - # + req - Request object - # + return - `true` if authentication is a success, else `false` - public function handle(Request req) returns boolean; }; -public function HttpBasicAuthnHandler.handle(Request req) returns boolean { +# Checks if the provided request can be authenticated with basic auth. +# +# + req - Request object +# + return - `true` if it is possible authenticate with basic auth, else `false` +public function BasicAuthnHandler.handle(Request req) returns boolean { // extract the header value var basicAuthHeader = extractBasicAuthHeaderValue(req); - string basicAuthHeaderValue = ""; if (basicAuthHeader is string) { - basicAuthHeaderValue = basicAuthHeader; - } else { - log:printError("Error in extracting basic authentication header"); - return false; - } - var credentials = extractBasicAuthCredentials(basicAuthHeaderValue); - if (credentials is (string, string)) { - var (username, password) = credentials; - boolean authenticated = self.authProvider.authenticate(username, password); - if (authenticated) { - // set username - runtime:getInvocationContext().principal.username = username; - // read scopes and set to the invocation context - string[] scopes = self.authProvider.getScopes(username); - //if (scopes.length() > 0) { - runtime:getInvocationContext().principal.scopes = scopes; - //} + string credential = basicAuthHeader.substring(5, basicAuthHeader.length()).trim(); + var authenticated = self.authProvider.authenticate(credential); + if (authenticated is boolean) { + return authenticated; + } else { + log:printError("Error while authenticating with BasicAuthnHandler", err = authenticated); } - return authenticated; } else { - log:printError("Error in decoding basic authentication header", err = credentials); + log:printError("Error in extracting basic authentication header"); } return false; } -public function HttpBasicAuthnHandler.canHandle(Request req) returns boolean { +# Intercept requests for authentication. +# +# + req - Request object +# + return - `true` if authentication is a success, else `false` +public function BasicAuthnHandler.canHandle(Request req) returns boolean { var basicAuthHeader = trap req.getHeader(AUTH_HEADER); if (basicAuthHeader is string) { return basicAuthHeader.hasPrefix(AUTH_SCHEME_BASIC); } return false; } - -# Extracts the basic authentication credentials from the header value. -# -# + authHeader - Basic authentication header -# + return - A `string` tuple with the extracted username and password or `error` that occured while extracting credentials -function extractBasicAuthCredentials(string authHeader) returns (string, string)|error { - // extract user credentials from basic auth header - string decodedBasicAuthHeader = encoding:byteArrayToString( - check encoding:decodeBase64(authHeader.substring(5, authHeader.length()).trim())); - string[] decodedCredentials = decodedBasicAuthHeader.split(":"); - if (decodedCredentials.length() != 2) { - error err = error(HTTP_ERROR_CODE, {message: "Incorrect basic authentication header format" }); - return err; - } else { - return (decodedCredentials[0], decodedCredentials[1]); - } -} diff --git a/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal index a0769a5cda0b..d607bd3c7315 100644 --- a/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal @@ -19,31 +19,23 @@ import ballerina/log; # Representation of JWT Auth handler for HTTP traffic # -# + name - Name of the auth handler -# + jwtAuthenticator - `JWTAuthenticator` instance -public type HttpJwtAuthnHandler object { +# + authProvider - `JWTAuthProvider` instance +public type JwtAuthnHandler object { - public string name = "jwt"; - public auth:JWTAuthProvider jwtAuthenticator; + *AuthnHandler; - public function __init(auth:JWTAuthProvider jwtAuthenticator) { - self.jwtAuthenticator = jwtAuthenticator; - } - - # Checks if the request can be authenticated with JWT - # - # + req - `Request` instance - # + return - true if can be authenticated, else false - public function canHandle(Request req) returns boolean; + public auth:AuthProvider authProvider; - # Authenticates the incoming request using JWT authentication - # - # + req - `Request` instance - # + return - true if authenticated successfully, else false - public function handle(Request req) returns boolean; + public function __init(auth:AuthProvider authProvider) { + self.authProvider = authProvider; + } }; -public function HttpJwtAuthnHandler.canHandle(Request req) returns boolean { +# Checks if the request can be authenticated with JWT +# +# + req - `Request` instance +# + return - true if can be authenticated, else false +public function JwtAuthnHandler.canHandle(Request req) returns boolean { string authHeader = ""; var headerValue = trap req.getHeader(AUTH_HEADER); if (headerValue is string) { @@ -68,21 +60,21 @@ public function HttpJwtAuthnHandler.canHandle(Request req) returns boolean { return false; } -public function HttpJwtAuthnHandler.handle(Request req) returns boolean { +# Authenticates the incoming request using JWT authentication +# +# + req - `Request` instance +# + return - true if authenticated successfully, else false +public function JwtAuthnHandler.handle(Request req) returns boolean { string jwtToken = extractJWTToken(req); - var authenticated = self.jwtAuthenticator.authenticate(jwtToken); + var authenticated = self.authProvider.authenticate(jwtToken); if (authenticated is boolean) { return authenticated; } else { - log:printError("Error while validating JWT token ", err = authenticated); + log:printError("Error while validating JWT token", err = authenticated); } return false; } -# Extracts the JWT from the incoming request -# -# + req - `Request` instance -# + return - Extracted JWT string function extractJWTToken(Request req) returns string { string authHeader = req.getHeader(AUTH_HEADER); string[] authHeaderComponents = authHeader.split(" "); diff --git a/stdlib/http/src/main/ballerina/http/auth/utils.bal b/stdlib/http/src/main/ballerina/http/auth/utils.bal index c2234903dbef..766630b29996 100644 --- a/stdlib/http/src/main/ballerina/http/auth/utils.bal +++ b/stdlib/http/src/main/ballerina/http/auth/utils.bal @@ -14,6 +14,9 @@ // specific language governing permissions and limitations // under the License. +import ballerina/log; +import ballerina/reflect; + # Auth annotation module. const string ANN_MODULE = "ballerina/http"; # Resource level annotation name. @@ -57,14 +60,19 @@ public function extractBasicAuthHeaderValue(Request req) returns string? { } } -function getResourceAuthConfig(FilterContext context) returns ServiceResourceAuth? { +# Tries to retrieve the annotation value for authentication hierarchically - first from the resource level and then +# from the service level, if it is not there in the resource level. +# +# + context - `FilterContext` instance +# + return - `ServiceResourceAuth` instance if its defined, else nil +function getServiceResourceAuthConfig(FilterContext context) returns ServiceResourceAuth? { // get authn details from the resource level ServiceResourceAuth? resourceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, RESOURCE_ANN_NAME, reflect:getResourceAnnotations(context.serviceRef, context.resourceName)); ServiceResourceAuth? serviceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, SERVICE_ANN_NAME, reflect:getServiceAnnotations(context.serviceRef)); // check if authentication is enabled - boolean resourceSecured = isResourceSecured(resourceLevelAuthAnn, serviceLevelAuthAnn); + boolean resourceSecured = isServiceResourceSecured(resourceLevelAuthAnn, serviceLevelAuthAnn); // if resource is not secured, no need to check further if (!resourceSecured) { return (); @@ -81,13 +89,12 @@ function getResourceAuthConfig(FilterContext context) returns ServiceResourceAut } } -# Tries to retrieve the annotation value for authentication hierarchically - first from the resource level and then -# from the service level, if it is not there in the resource level. +# Retrieves and return the auth annotation with the given module name, annotation name and annotation data. # # + annotationModule - Annotation module name # + annotationName - Annotation name # + annData - Array of annotationData instances -# + return - ListenerAuthConfig instance if its defined, else nil +# + return - `ServiceResourceAuth` instance if its defined, else nil function getAuthAnnotation(string annotationModule, string annotationName, reflect:annotationData[] annData) returns ServiceResourceAuth? { if (annData.length() == 0) { return (); @@ -110,8 +117,13 @@ function getAuthAnnotation(string annotationModule, string annotationName, refle } } -function isResourceSecured(ServiceResourceAuth? resourceLevelAuthAnn, - ServiceResourceAuth? serviceLevelAuthAnn) returns boolean { +# Check for the service or the resource is secured by evaluating the enabled flag configured by the user. +# +# + resourceLevelAuthAnn - Resource level auth annotations +# + serviceLevelAuthAnn - Service level auth annotations +# + return - Whether the service or resource secured or not +function isServiceResourceSecured(ServiceResourceAuth? resourceLevelAuthAnn, + ServiceResourceAuth? serviceLevelAuthAnn) returns boolean { boolean secured = true; if (resourceLevelAuthAnn is ServiceResourceAuth) { secured = resourceLevelAuthAnn.enabled; diff --git a/stdlib/http/src/main/ballerina/http/service_endpoint.bal b/stdlib/http/src/main/ballerina/http/service_endpoint.bal index d942a6459d6b..d40cf8616e69 100644 --- a/stdlib/http/src/main/ballerina/http/service_endpoint.bal +++ b/stdlib/http/src/main/ballerina/http/service_endpoint.bal @@ -76,7 +76,7 @@ public function Listener.init(ServiceEndpointConfiguration c) { self.config = c; var auth = self.config["auth"]; if (auth is ListenerAuth) { - if (auth.authConfig.length() > 0) { + if (auth.authnHandlers.length() > 0) { var secureSocket = self.config.secureSocket; if (secureSocket is ServiceSecureSocket) { addAuthFiltersForSecureListener(self.config); @@ -156,26 +156,17 @@ public type ServiceEndpointConfiguration record {| # Authentication configurations for the listener. # -# + authConfig - Array of inbound authentication configurations +# + authnHandlers - Array of authentication handlers # + scopes - Array of scopes # + positiveAuthzCache - Caching configurations for positive authorizations # + negativeAuthzCache - Caching configurations for negative authorizations public type ListenerAuth record {| - InboundAuthConfig[] authConfig; + AuthnHandler[] authnHandlers; string[] scopes?; AuthCacheConfig positiveAuthzCache = {}; AuthCacheConfig negativeAuthzCache = {}; |}; -# Inbound authentication configurations with handlers and providers. -# -# + authnHandler - Authentication handler -# + authProviders - Array of auth providers -public type InboundAuthConfig record {| - AuthnHandler authnHandler; - auth:AuthProvider[] authProviders; -|}; - # Configures the SSL/TLS options to be used for HTTP service. # # + trustStore - Configures the trust store to be used @@ -248,8 +239,8 @@ function addAuthFiltersForSecureListener(ServiceEndpointConfiguration config) { var auth = config["auth"]; if (auth is ListenerAuth) { - InboundAuthConfig[] authConfig = auth.authConfig; - AuthnFilter authnFilter = new(authConfig); + AuthnHandler[] authnHandlers = auth.authnHandlers; + AuthnFilter authnFilter = new(authnHandlers); authFilters[0] = authnFilter; var scopes = auth["scopes"]; @@ -277,6 +268,7 @@ function addAuthFiltersForSecureListener(ServiceEndpointConfiguration config) { config.filters = newFilters; } } + // No need to validate else part since the function is called if and only if the `auth is ListenerAuth` } ////////////////////////////////// diff --git a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal index c35dcc93f338..535afac4120c 100644 --- a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal @@ -4,7 +4,7 @@ import ballerina/http; function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); auth:AuthProvider authProvider = configAuthStoreProvider; - http:HttpBasicAuthnHandler handler = new(authProvider); + http:BasicAuthnHandler handler = new(authProvider); http:Request inRequest = createRequest(); string basicAuthHeaderValue = "123Basic xxxxxx"; inRequest.setHeader("123Authorization", basicAuthHeaderValue); @@ -14,7 +14,7 @@ function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { function testCanHandleHttpBasicAuth() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); auth:AuthProvider authProvider = configAuthStoreProvider; - http:HttpBasicAuthnHandler handler = new(authProvider); + http:BasicAuthnHandler handler = new(authProvider); http:Request inRequest = createRequest(); string basicAuthHeaderValue = "Basic xxxxxx"; inRequest.setHeader("Authorization", basicAuthHeaderValue); @@ -24,7 +24,7 @@ function testCanHandleHttpBasicAuth() returns boolean { function testHandleHttpBasicAuthFailure() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); auth:AuthProvider authProvider = configAuthStoreProvider; - http:HttpBasicAuthnHandler handler = new(authProvider); + http:BasicAuthnHandler handler = new(authProvider); http:Request inRequest = createRequest(); string basicAuthHeaderValue = "Basic YW1pbGE6cHFy"; inRequest.setHeader("Authorization", basicAuthHeaderValue); @@ -34,7 +34,7 @@ function testHandleHttpBasicAuthFailure() returns boolean { function testHandleHttpBasicAuth() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); auth:AuthProvider authProvider = configAuthStoreProvider; - http:HttpBasicAuthnHandler handler = new(authProvider); + http:BasicAuthnHandler handler = new(authProvider); http:Request inRequest = createRequest(); string basicAuthHeaderValue = "Basic aXN1cnU6eHh4"; inRequest.setHeader("Authorization", basicAuthHeaderValue); diff --git a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal index 6b371cdb264d..3b0fa22a841f 100644 --- a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal @@ -3,7 +3,7 @@ import ballerina/http; import ballerina/crypto; function testCanHandleHttpJwtAuthWithoutHeader() returns boolean { - http:HttpJwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); + http:JwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Basic xxxxxx"; request.setHeader("Authorization", authHeaderValue); @@ -11,7 +11,7 @@ function testCanHandleHttpJwtAuthWithoutHeader() returns boolean { } function testCanHandleHttpJwtAuth() returns boolean { - http:HttpJwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); + http:JwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Bearer xxx.yyy.zzz"; request.setHeader("Authorization", authHeaderValue); @@ -19,7 +19,7 @@ function testCanHandleHttpJwtAuth() returns boolean { } function testHandleHttpJwtAuthFailure() returns boolean { - http:HttpJwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); + http:JwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Bearer xxx.yyy.zzz"; request.setHeader("Authorization", authHeaderValue); @@ -27,7 +27,7 @@ function testHandleHttpJwtAuthFailure() returns boolean { } function testHandleHttpJwtAuth(string token, string trustStorePath) returns boolean { - http:HttpJwtAuthnHandler handler = new(createJwtAuthProvider(trustStorePath)); + http:JwtAuthnHandler handler = new(createJwtAuthProvider(trustStorePath)); http:Request request = createRequest(); string authHeaderValue = "Bearer " + token; request.setHeader("Authorization", authHeaderValue); From 64641756399e1e319a34e96da6cdb6523ee5238c Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 11 Apr 2019 18:10:51 +0530 Subject: [PATCH 10/52] Update language server jsons --- .../annotation/serviceAnnotation3.json | 8 +- .../packageimport/packageImport.json | 1673 +++++++++-------- .../service/serviceBodyCompletion5.json | 1673 +++++++++-------- .../service/serviceEndpointBind4.json | 1470 ++++++++------- .../toplevel/globalVarDefPackageContent.json | 195 +- .../topLevelPackageContentAccess.json | 345 ++-- 6 files changed, 2784 insertions(+), 2580 deletions(-) diff --git a/language-server/modules/langserver-core/src/test/resources/completion/annotation/serviceAnnotation3.json b/language-server/modules/langserver-core/src/test/resources/completion/annotation/serviceAnnotation3.json index b9cf4be0998c..b826d31d614e 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/annotation/serviceAnnotation3.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/annotation/serviceAnnotation3.json @@ -62,11 +62,11 @@ "insertTextFormat": "Snippet" }, { - "label": "authConfig", + "label": "auth", "kind": "Field", "detail": "Field", "sortText": "120", - "insertText": "authConfig: ${1:{}} // Values allowed: ballerina/http:ListenerAuthConfig|()", + "insertText": "auth: {\n\t${1}\n}", "insertTextFormat": "Snippet" }, { @@ -74,8 +74,8 @@ "kind": "Property", "detail": "none", "sortText": "110", - "insertText": "endpoints: [],\nhost: \"\",\nbasePath: \"\",\ncompression: {},\nchunking: \"AUTO\", // Values allowed: AUTO|ALWAYS|NEVER,\ncors: {},\nversioning: {},\nauthConfig: {} // Values allowed: ballerina/http:ListenerAuthConfig|()", + "insertText": "endpoints: [],\nhost: \"\",\nbasePath: \"\",\ncompression: {},\nchunking: \"AUTO\", // Values allowed: AUTO|ALWAYS|NEVER,\ncors: {},\nversioning: {},\nauth: {}", "insertTextFormat": "Snippet" } ] -} \ No newline at end of file +} diff --git a/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json b/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json index 202ac3cdf3d0..180c5628c5c2 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json @@ -6,1133 +6,1166 @@ "source": "packageimport/source/packageImport.bal", "items": [ { - "label":"extractBasicAuthHeaderValue(http:Request req)(string?)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nballerina/http:" + "label": "extractBasicAuthHeaderValue(http:Request req)(string?)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" } }, - "sortText":"121", - "insertText":"extractBasicAuthHeaderValue(${1:req})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "extractBasicAuthHeaderValue(${1:req})", + "insertTextFormat": "Snippet" }, { - "label":"createHttpCachingClient(string url, http:ClientEndpointConfig config, http:CacheConfig cacheConfig)(ballerina/http:Client|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:" + "label": "createHttpCachingClient(string url, http:ClientEndpointConfig config, http:CacheConfig cacheConfig)(ballerina/http:Client|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:Client|error" } }, - "sortText":"121", - "insertText":"createHttpCachingClient(${1:url}, ${2:config}, ${3:cacheConfig})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "createHttpCachingClient(${1:url}, ${2:config}, ${3:cacheConfig})", + "insertTextFormat": "Snippet" }, { - "label":"parseHeader(string headerValue)((string,map)|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \nballerina/http:" + "label": "parseHeader(string headerValue)((string,map)|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \n(string,map)|error" } }, - "sortText":"121", - "insertText":"parseHeader(${1:headerValue})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "parseHeader(${1:headerValue})", + "insertTextFormat": "Snippet" }, { - "label":"invokeEndpoint(string path, http:Request outRequest, FORWARD|GET|POST|DELETE|OPTIONS|PUT|PATCH|HEAD|NONE requestAction, http:Client httpClient)(ballerina/http:Response|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:" + "label": "invokeEndpoint(string path, http:Request outRequest, FORWARD|GET|POST|DELETE|OPTIONS|PUT|PATCH|HEAD|NONE requestAction, http:Client httpClient)(ballerina/http:Response|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:Response|error" } }, - "sortText":"121", - "insertText":"invokeEndpoint(${1:path}, ${2:outRequest}, ${3:requestAction}, ${4:httpClient})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "invokeEndpoint(${1:path}, ${2:outRequest}, ${3:requestAction}, ${4:httpClient})", + "insertTextFormat": "Snippet" }, { - "label":"createHttpSecureClient(string url, http:ClientEndpointConfig config)(ballerina/http:Client|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:" + "label": "createHttpSecureClient(string url, http:ClientEndpointConfig config)(ballerina/http:Client|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:Client|error" } }, - "sortText":"121", - "insertText":"createHttpSecureClient(${1:url}, ${2:config})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "createHttpSecureClient(${1:url}, ${2:config})", + "insertTextFormat": "Snippet" }, { - "label":"encode(string url, string charset)(string|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nballerina/http:" + "label": "encode(string url, string charset)(string|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nstring|error" } }, - "sortText":"121", - "insertText":"encode(${1:url}, ${2:charset})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "encode(${1:url}, ${2:charset})", + "insertTextFormat": "Snippet" }, { - "label":"decode(string url, string charset)(string|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nballerina/http:" + "label": "decode(string url, string charset)(string|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nstring|error" } }, - "sortText":"121", - "insertText":"decode(${1:url}, ${2:charset})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "decode(${1:url}, ${2:charset})", + "insertTextFormat": "Snippet" }, { - "label":"HttpServiceConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Contains the configurations for an HTTP service.\n" + "label": "HttpServiceConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Contains the configurations for an HTTP service.\n" }, - "sortText":"171", - "insertText":"HttpServiceConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpServiceConfig", + "insertTextFormat": "Snippet" }, { - "label":"CorsConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for CORS support.\n" + "label": "CorsConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for CORS support.\n" }, - "sortText":"171", - "insertText":"CorsConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CorsConfig", + "insertTextFormat": "Snippet" }, { - "label":"Versioning", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for service versioning.\n" + "label": "Versioning", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for service versioning.\n" }, - "sortText":"171", - "insertText":"Versioning", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Versioning", + "insertTextFormat": "Snippet" }, { - "label":"WSServiceConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for a WebSocket service.\n" + "label": "WSServiceConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for a WebSocket service.\n" }, - "sortText":"171", - "insertText":"WSServiceConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WSServiceConfig", + "insertTextFormat": "Snippet" }, { - "label":"HttpResourceConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configuration for an HTTP resource.\n" + "label": "HttpResourceConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configuration for an HTTP resource.\n" }, - "sortText":"171", - "insertText":"HttpResourceConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpResourceConfig", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketUpgradeConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Resource configuration to upgrade from HTTP to WebSocket.\n" + "label": "WebSocketUpgradeConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Resource configuration to upgrade from HTTP to WebSocket.\n" }, - "sortText":"171", - "insertText":"WebSocketUpgradeConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketUpgradeConfig", + "insertTextFormat": "Snippet" }, { - "label":"ListenerAuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures the authentication scheme for a service or a resource.\n" + "label": "ServiceResourceAuth", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures the authentication scheme for a service or a resource.\n" }, - "sortText":"171", - "insertText":"ListenerAuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ServiceResourceAuth", + "insertTextFormat": "Snippet" }, { - "label":"Authentication", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Can be used for enabling/disabling authentication in an HTTP service.\n" + "label": "CacheConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the caching behaviour of the endpoint.\n" }, - "sortText":"171", - "insertText":"Authentication", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CacheConfig", + "insertTextFormat": "Snippet" }, { - "label":"CacheConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the caching behaviour of the endpoint.\n" + "label": "TargetService", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a single service and its related configurations.\n" }, - "sortText":"171", - "insertText":"CacheConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "TargetService", + "insertTextFormat": "Snippet" }, { - "label":"TargetService", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a single service and its related configurations.\n" + "label": "ClientEndpointConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the behaviours when communicating with a remote HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"TargetService", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ClientEndpointConfig", + "insertTextFormat": "Snippet" }, { - "label":"ClientEndpointConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the behaviours when communicating with a remote HTTP endpoint.\n" + "label": "RetryConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides configurations for controlling the retrying behavior in failure scenarios.\n" }, - "sortText":"171", - "insertText":"ClientEndpointConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RetryConfig", + "insertTextFormat": "Snippet" }, { - "label":"RetryConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides configurations for controlling the retry behaviour in failure scenarios.\n" + "label": "SecureSocket", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides configurations for facilitating secure communication with a remote HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"RetryConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "SecureSocket", + "insertTextFormat": "Snippet" }, { - "label":"SecureSocket", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides configurations for facilitating secure communication with a remote HTTP endpoint.\n" + "label": "FollowRedirects", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides configurations for controlling the endpoint's behaviour in response to HTTP redirect related responses.\n" }, - "sortText":"171", - "insertText":"SecureSocket", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FollowRedirects", + "insertTextFormat": "Snippet" }, { - "label":"FollowRedirects", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides configurations for controlling the endpoint\u0027s behaviour in response to HTTP redirect related responses.\n" + "label": "ProxyConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Proxy server configurations to be used with the HTTP client endpoint.\n" }, - "sortText":"171", - "insertText":"FollowRedirects", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ProxyConfig", + "insertTextFormat": "Snippet" }, { - "label":"ProxyConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Proxy server configurations to be used with the HTTP client endpoint.\n" + "label": "OutboundAuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `OutboundAuthConfig` record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"ProxyConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "OutboundAuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"AuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"AuthConfig record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" + "label": "BasicAuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `BasicAuthConfig` record can be used to configure Basic Authentication used by the HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"AuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "BasicAuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"BasicAuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"BasicAuthConfig record can be used to configure Basic Authentication used by the HTTP endpoint.\n" + "label": "OAuth2AuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `OAuth2AuthConfig` record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"BasicAuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "OAuth2AuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"OAuth2AuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"OAuth2AuthConfig record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" + "label": "ClientCredentialsGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `ClientCredentialsGrantConfig` record can be used to configue OAuth2 client credentials grant type.\n" }, - "sortText":"171", - "insertText":"OAuth2AuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ClientCredentialsGrantConfig", + "insertTextFormat": "Snippet" }, { - "label":"JwtAuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"JwtAuthConfig record can be used to configure JWT based authentication used by the HTTP endpoint.\n" + "label": "PasswordGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `PasswordGrantConfig` record can be used to configue OAuth2 password grant type\n" }, - "sortText":"171", - "insertText":"JwtAuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "PasswordGrantConfig", + "insertTextFormat": "Snippet" }, { - "label":"HttpTimeoutError", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Defines a timeout error occurred during service invocation.\n" + "label": "DirectTokenConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenConfig` record configures the access token directly.\n" }, - "sortText":"171", - "insertText":"HttpTimeoutError", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "DirectTokenConfig", + "insertTextFormat": "Snippet" }, { - "label":"PoolConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for managing HTTP client connection pool.\n" + "label": "RefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `RefreshConfig` record can be used to pass the configurations for refreshing the access token of password grant type.\n" }, - "sortText":"171", - "insertText":"PoolConfiguration", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RefreshConfig", + "insertTextFormat": "Snippet" }, { - "label":"Protocols", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for configuring SSL/TLS protocol and version to be used.\n" + "label": "DirectTokenRefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenRefreshConfig` record passes the configurations for refreshing the access token for \nthe grant type of the direct token grant type.\n" }, - "sortText":"171", - "insertText":"Protocols", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "DirectTokenRefreshConfig", + "insertTextFormat": "Snippet" }, { - "label":"ValidateCert", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing configurations for certificate revocation status checks.\n" + "label": "JwtAuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `JwtAuthConfig` record can be used to configure JWT based authentication used by the HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"ValidateCert", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "JwtAuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"ServiceOcspStapling", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing configurations for certificate revocation status checks.\n" + "label": "HttpTimeoutError", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Defines a timeout error occurred during service invocation.\n" }, - "sortText":"171", - "insertText":"ServiceOcspStapling", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpTimeoutError", + "insertTextFormat": "Snippet" }, { - "label":"CompressionConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing configurations for content compression.\n" + "label": "PoolConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for managing HTTP client connection pool.\n" }, - "sortText":"171", - "insertText":"CompressionConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "PoolConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"MutualSslHandshake", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing mutual ssl handshake results.\n" + "label": "Protocols", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for configuring SSL/TLS protocol and version to be used.\n" }, - "sortText":"171", - "insertText":"MutualSslHandshake", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Protocols", + "insertTextFormat": "Snippet" }, { - "label":"FailoverConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the failover behaviour of the endpoint.\n" + "label": "ValidateCert", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing configurations for certificate revocation status checks.\n" }, - "sortText":"171", - "insertText":"FailoverConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ValidateCert", + "insertTextFormat": "Snippet" }, { - "label":"FailoverInferredConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Inferred failover configurations passed into the failover client.\n" + "label": "ServiceOcspStapling", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing configurations for certificate revocation status checks.\n" }, - "sortText":"171", - "insertText":"FailoverInferredConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ServiceOcspStapling", + "insertTextFormat": "Snippet" }, { - "label":"FailoverClientEndpointConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of HTTP related configurations and failover related configurations.\n" + "label": "CompressionConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing configurations for content compression.\n" }, - "sortText":"171", - "insertText":"FailoverClientEndpointConfiguration", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CompressionConfig", + "insertTextFormat": "Snippet" }, { - "label":"CircuitHealth", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Maintains the health of the Circuit Breaker.\n" + "label": "MutualSslHandshake", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing mutual ssl handshake results.\n" }, - "sortText":"171", - "insertText":"CircuitHealth", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "MutualSslHandshake", + "insertTextFormat": "Snippet" }, { - "label":"CircuitBreakerConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the behaviour of the Circuit Breaker.\n" + "label": "CachedToken", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `CachedToken` stores the values received from the authorization/token server to use them\nfor the latter requests without requesting tokens again.\n" }, - "sortText":"171", - "insertText":"CircuitBreakerConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CachedToken", + "insertTextFormat": "Snippet" }, { - "label":"RollingWindow", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a rolling window in the Circuit Breaker.\n" + "label": "FailoverConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the failover behaviour of the endpoint.\n" }, - "sortText":"171", - "insertText":"RollingWindow", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FailoverConfig", + "insertTextFormat": "Snippet" }, { - "label":"Bucket", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a discrete sub-part of the time window (Bucket).\n" + "label": "FailoverInferredConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Inferred failover configurations passed into the failover client.\n" }, - "sortText":"171", - "insertText":"Bucket", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FailoverInferredConfig", + "insertTextFormat": "Snippet" }, { - "label":"CircuitBreakerInferredConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Derived set of configurations from the `CircuitBreakerConfig`.\n" + "label": "FailoverClientEndpointConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of HTTP related configurations and failover related configurations.\n" }, - "sortText":"171", - "insertText":"CircuitBreakerInferredConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FailoverClientEndpointConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"RetryInferredConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Derived set of configurations from the `RetryConfig`.\n" + "label": "CircuitHealth", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Maintains the health of the Circuit Breaker.\n" }, - "sortText":"171", - "insertText":"RetryInferredConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitHealth", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalanceActionErrorData", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an error occurred in an remote function of the Load Balance connector.\n" + "label": "CircuitBreakerConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the behaviour of the Circuit Breaker.\n" }, - "sortText":"171", - "insertText":"LoadBalanceActionErrorData", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitBreakerConfig", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalanceClientEndpointConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"The configurations related to the load balance client endpoint.\n" + "label": "RollingWindow", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a rolling window in the Circuit Breaker.\n" }, - "sortText":"171", - "insertText":"LoadBalanceClientEndpointConfiguration", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RollingWindow", + "insertTextFormat": "Snippet" }, { - "label":"Remote", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Presents a read-only view of the remote address.\n" + "label": "Bucket", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a discrete sub-part of the time window (Bucket).\n" }, - "sortText":"171", - "insertText":"Remote", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Bucket", + "insertTextFormat": "Snippet" }, { - "label":"Local", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Presents a read-only view of the local address.\n" + "label": "CircuitBreakerInferredConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Derived set of configurations from the `CircuitBreakerConfig`.\n" }, - "sortText":"171", - "insertText":"Local", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitBreakerInferredConfig", + "insertTextFormat": "Snippet" }, { - "label":"RequestLimits", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures limits for requests. If these limits are violated, the request is rejected.\n" + "label": "RetryInferredConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Derived set of configurations from the `RetryConfig`.\n" }, - "sortText":"171", - "insertText":"RequestLimits", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RetryInferredConfig", + "insertTextFormat": "Snippet" }, { - "label":"ServiceEndpointConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for HTTP service endpoints.\n" + "label": "LoadBalanceActionErrorData", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an error occurred in an remote function of the Load Balance connector.\n" }, - "sortText":"171", - "insertText":"ServiceEndpointConfiguration", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalanceActionErrorData", + "insertTextFormat": "Snippet" }, { - "label":"ServiceSecureSocket", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures the SSL/TLS options to be used for HTTP service.\n" + "label": "LoadBalanceClientEndpointConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The configurations related to the load balance client endpoint.\n" }, - "sortText":"171", - "insertText":"ServiceSecureSocket", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalanceClientEndpointConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"AuthCacheConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" + "label": "Remote", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Presents a read-only view of the remote address.\n" }, - "sortText":"171", - "insertText":"AuthCacheConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Remote", + "insertTextFormat": "Snippet" }, { - "label":"AuthProvider", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configuration for authentication providers.\n" + "label": "Local", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Presents a read-only view of the local address.\n" }, - "sortText":"171", - "insertText":"AuthProvider", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Local", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketClientEndpointConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configuration for the WebSocket client endpoint.\n" + "label": "RequestLimits", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures limits for requests. If these limits are violated, the request is rejected.\n" }, - "sortText":"171", - "insertText":"WebSocketClientEndpointConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RequestLimits", + "insertTextFormat": "Snippet" }, { - "label":"AuthHandlerRegistry", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of the Http Auth Handler Registry.\n" + "label": "ServiceEndpointConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for HTTP service endpoints.\n" }, - "sortText":"171", - "insertText":"AuthHandlerRegistry", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ServiceEndpointConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"AuthnFilter", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of the Authentication filter.\n" + "label": "ListenerAuth", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Authentication configurations for the listener.\n" }, - "sortText":"171", - "insertText":"AuthnFilter", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ListenerAuth", + "insertTextFormat": "Snippet" }, { - "label":"HttpAuthnHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of Authentication handler for HTTP traffic.\n" + "label": "ServiceSecureSocket", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures the SSL/TLS options to be used for HTTP service.\n" }, - "sortText":"171", - "insertText":"HttpAuthnHandler", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ServiceSecureSocket", + "insertTextFormat": "Snippet" }, { - "label":"AuthnHandlerChain", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of Authentication handler chain\n" + "label": "AuthCacheConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" }, - "sortText":"171", - "insertText":"AuthnHandlerChain", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthCacheConfig", + "insertTextFormat": "Snippet" }, { - "label":"AuthzFilter", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of the Authorization filter\n" + "label": "WebSocketClientEndpointConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configuration for the WebSocket client endpoint.\n" }, - "sortText":"171", - "insertText":"AuthzFilter", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketClientEndpointConfig", + "insertTextFormat": "Snippet" }, { - "label":"HttpAuthzHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of Authorization Handler for HTTP\n" + "label": "AuthnFilter", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of the Authentication filter.\n" }, - "sortText":"171", - "insertText":"HttpAuthzHandler", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthnFilter", + "insertTextFormat": "Snippet" }, { - "label":"HttpBasicAuthnHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Defines Basic Auth handler for HTTP traffic.\n" + "label": "AuthnHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of Authentication handler for HTTP traffic." }, - "sortText":"171", - "insertText":"HttpBasicAuthnHandler", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthnHandler", + "insertTextFormat": "Snippet" }, { - "label":"HttpJwtAuthnHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of JWT Auth handler for HTTP traffic\n" + "label": "AuthzFilter", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of the Authorization filter\n" }, - "sortText":"171", - "insertText":"HttpJwtAuthnHandler", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthzFilter", + "insertTextFormat": "Snippet" }, { - "label":"RequestCacheControl", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures cache control directives for a `Request`.\n" + "label": "AuthzHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of Authorization Handler for HTTP\n" }, - "sortText":"171", - "insertText":"RequestCacheControl", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthzHandler", + "insertTextFormat": "Snippet" }, { - "label":"ResponseCacheControl", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures cache control directives for a `Response`.\n" + "label": "BasicAuthnHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Defines Basic Auth handler for HTTP traffic.\n" }, - "sortText":"171", - "insertText":"ResponseCacheControl", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "BasicAuthnHandler", + "insertTextFormat": "Snippet" }, { - "label":"HttpCache", - "kind":"Class", - "detail":"BType", - "sortText":"171", - "insertText":"HttpCache", - "insertTextFormat":"Snippet" + "label": "JwtAuthnHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of JWT Auth handler for HTTP traffic\n" + }, + "sortText": "171", + "insertText": "JwtAuthnHandler", + "insertTextFormat": "Snippet" + }, + { + "label": "RequestCacheControl", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures cache control directives for a `Request`.\n" + }, + "sortText": "171", + "insertText": "RequestCacheControl", + "insertTextFormat": "Snippet" + }, + { + "label": "ResponseCacheControl", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures cache control directives for a `Response`.\n" + }, + "sortText": "171", + "insertText": "ResponseCacheControl", + "insertTextFormat": "Snippet" + }, + { + "label": "HttpCache", + "kind": "Class", + "detail": "BType", + "sortText": "171", + "insertText": "HttpCache", + "insertTextFormat": "Snippet" }, { - "label":"HttpFuture", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a \u0027future\u0027 that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." + "label": "HttpFuture", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a 'future' that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." }, - "sortText":"171", - "insertText":"HttpFuture", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpFuture", + "insertTextFormat": "Snippet" }, { - "label":"PushPromise", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an HTTP/2 `PUSH_PROMISE` frame.\n" + "label": "PushPromise", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an HTTP/2 `PUSH_PROMISE` frame.\n" }, - "sortText":"171", - "insertText":"PushPromise", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "PushPromise", + "insertTextFormat": "Snippet" }, { - "label":"Filter", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of a HTTP Request Filter. This filter will be applied before the request is dispatched to the relevant resource. Any Filter implementation should be structurally similar to the Filter object." + "label": "Filter", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of a HTTP Request Filter. This filter will be applied before the request is dispatched to the relevant resource. Any Filter implementation should be structurally similar to the Filter object." }, - "sortText":"171", - "insertText":"Filter", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Filter", + "insertTextFormat": "Snippet" }, { - "label":"FilterContext", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of request filter Context.\n" + "label": "FilterContext", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of request filter Context.\n" }, - "sortText":"171", - "insertText":"FilterContext", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FilterContext", + "insertTextFormat": "Snippet" }, { - "label":"Request", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an HTTP request.\n" + "label": "Request", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an HTTP request.\n" }, - "sortText":"171", - "insertText":"Request", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Request", + "insertTextFormat": "Snippet" }, { - "label":"Response", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an HTTP response.\n" + "label": "Response", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an HTTP response.\n" }, - "sortText":"171", - "insertText":"Response", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Response", + "insertTextFormat": "Snippet" }, { - "label":"MockListener", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Mock server endpoint which does not open a listening port." + "label": "MockListener", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Mock server endpoint which does not open a listening port." }, - "sortText":"171", - "insertText":"MockListener", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "MockListener", + "insertTextFormat": "Snippet" }, { - "label":"CircuitBreakerClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A Circuit Breaker implementation which can be used to gracefully handle network failures.\n" + "label": "CircuitBreakerClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A Circuit Breaker implementation which can be used to gracefully handle network failures.\n" }, - "sortText":"171", - "insertText":"CircuitBreakerClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitBreakerClient", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalancerRule", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"\nLoadBalancerRule provides a required interfaces to implement different algorithms.\n" + "label": "LoadBalancerRule", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "\nLoadBalancerRule provides a required interfaces to implement different algorithms.\n" }, - "sortText":"171", - "insertText":"LoadBalancerRule", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalancerRule", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalancerRounRobinRule", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Implementation of round robin load balancing strategy.\n" + "label": "LoadBalancerRounRobinRule", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Implementation of round robin load balancing strategy.\n" }, - "sortText":"171", - "insertText":"LoadBalancerRounRobinRule", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalancerRounRobinRule", + "insertTextFormat": "Snippet" }, { - "label":"Listener", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"This is used for creating HTTP server endpoints. An HTTP server endpoint is capable of responding to\nremote callers. The `Listener` is responsible for initializing the endpoint using the provided configurations." + "label": "Listener", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "This is used for creating HTTP server endpoints. An HTTP server endpoint is capable of responding to\nremote callers. The `Listener` is responsible for initializing the endpoint using the provided configurations." }, - "sortText":"171", - "insertText":"Listener", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Listener", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketListener", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a WebSocket service endpoint." + "label": "WebSocketListener", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a WebSocket service endpoint." }, - "sortText":"171", - "insertText":"WebSocketListener", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketListener", + "insertTextFormat": "Snippet" }, { - "label":"HttpCachingClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"An HTTP caching client implementation which takes an `HttpActions` instance and wraps it with an HTTP caching layer.\n" + "label": "HttpCachingClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "An HTTP caching client implementation which takes an `HttpActions` instance and wraps it with an HTTP caching layer.\n" }, - "sortText":"171", - "insertText":"HttpCachingClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpCachingClient", + "insertTextFormat": "Snippet" }, { - "label":"Client", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs." + "label": "Client", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs." }, - "sortText":"171", - "insertText":"Client", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Client", + "insertTextFormat": "Snippet" }, { - "label":"HttpCaller", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides the HTTP actions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP actions implementation.\n" + "label": "HttpCaller", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides the HTTP actions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP actions implementation.\n" }, - "sortText":"171", - "insertText":"HttpCaller", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpCaller", + "insertTextFormat": "Snippet" }, { - "label":"Caller", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"The caller actions for responding to client requests.\n" + "label": "Caller", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The caller actions for responding to client requests.\n" }, - "sortText":"171", - "insertText":"Caller", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Caller", + "insertTextFormat": "Snippet" }, { - "label":"HttpSecureClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides secure HTTP remote functions for interacting with HTTP endpoints. This will make use of the authentication\nschemes configured in the HTTP client endpoint to secure the HTTP requests.\n" + "label": "HttpSecureClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides secure HTTP remote functions for interacting with HTTP endpoints. This will make use of the authentication\nschemes configured in the HTTP client endpoint to secure the HTTP requests.\n" }, - "sortText":"171", - "insertText":"HttpSecureClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpSecureClient", + "insertTextFormat": "Snippet" }, { - "label":"HttpClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides the HTTP remote functions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP remote functions implementation.\n" + "label": "HttpClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides the HTTP remote functions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP remote functions implementation.\n" }, - "sortText":"171", - "insertText":"HttpClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpClient", + "insertTextFormat": "Snippet" }, { - "label":"RedirectClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides redirect functionality for HTTP client remote functions.\n" + "label": "RedirectClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides redirect functionality for HTTP client remote functions.\n" }, - "sortText":"171", - "insertText":"RedirectClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RedirectClient", + "insertTextFormat": "Snippet" }, { - "label":"FailoverClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"An HTTP client endpoint which provides failover support over multiple HTTP clients.\n" + "label": "FailoverClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "An HTTP client endpoint which provides failover support over multiple HTTP clients.\n" }, - "sortText":"171", - "insertText":"FailoverClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FailoverClient", + "insertTextFormat": "Snippet" }, { - "label":"RetryClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides the HTTP remote functions for interacting with an HTTP endpoint. This is created by wrapping the HTTP client\nto provide retrying over HTTP requests.\n" + "label": "RetryClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides the HTTP remote functions for interacting with an HTTP endpoint. This is created by wrapping the HTTP client\nto provide retrying over HTTP requests.\n" }, - "sortText":"171", - "insertText":"RetryClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RetryClient", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalanceClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"LoadBalanceClient endpoint provides load balancing functionality over multiple HTTP clients.\n" + "label": "LoadBalanceClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "LoadBalanceClient endpoint provides load balancing functionality over multiple HTTP clients.\n" }, - "sortText":"171", - "insertText":"LoadBalanceClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalanceClient", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketCaller", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a WebSocket caller.\n" + "label": "WebSocketCaller", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a WebSocket caller.\n" }, - "sortText":"171", - "insertText":"WebSocketCaller", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketCaller", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a WebSocket client endpoint.\n" + "label": "WebSocketClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a WebSocket client endpoint.\n" }, - "sortText":"171", - "insertText":"WebSocketClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketClient", + "insertTextFormat": "Snippet" }, { - "label":"InboundAuthScheme", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Inbound authentication schemes." + "label": "InboundAuthScheme", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Inbound authentication schemes." }, - "sortText":"171", - "insertText":"InboundAuthScheme", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "InboundAuthScheme", + "insertTextFormat": "Snippet" }, { - "label":"OutboundAuthScheme", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Outbound authentication schemes." + "label": "OutboundAuthScheme", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Outbound authentication schemes." }, - "sortText":"171", - "insertText":"OutboundAuthScheme", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "OutboundAuthScheme", + "insertTextFormat": "Snippet" }, { - "label":"AuthStoreProvider", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Authentication storage providers for BasicAuth scheme." + "label": "CachingPolicy", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Used for configuring the caching behaviour. Setting the `policy` field in the `CacheConfig` record allows\nthe user to control the caching behaviour." }, - "sortText":"171", - "insertText":"AuthStoreProvider", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CachingPolicy", + "insertTextFormat": "Snippet" }, { - "label":"CachingPolicy", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Used for configuring the caching behaviour. Setting the `policy` field in the `CacheConfig` record allows\nthe user to control the caching behaviour." + "label": "Chunking", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the possible values for the chunking configuration in HTTP services and clients.\n\n`AUTO`: If the payload is less than 8KB, content-length header is set in the outbound request/response,\n otherwise chunking header is set in the outbound request/response\n`ALWAYS`: Always set chunking header in the response\n`NEVER`: Never set the chunking header even if the payload is larger than 8KB in the outbound request/response" }, - "sortText":"171", - "insertText":"CachingPolicy", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Chunking", + "insertTextFormat": "Snippet" }, { - "label":"Chunking", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the possible values for the chunking configuration in HTTP services and clients.\n\n`AUTO`: If the payload is less than 8KB, content-length header is set in the outbound request/response,\n otherwise chunking header is set in the outbound request/response\n`ALWAYS`: Always set chunking header in the response\n`NEVER`: Never set the chunking header even if the payload is larger than 8KB in the outbound request/response" + "label": "Compression", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Options to compress using gzip or deflate.\n\n`AUTO`: When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the\n outbound request/response accept-encoding/content-encoding option\n`ALWAYS`: Always set accept-encoding/content-encoding in outbound request/response\n`NEVER`: Never set accept-encoding/content-encoding header in outbound request/response" }, - "sortText":"171", - "insertText":"Chunking", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Compression", + "insertTextFormat": "Snippet" }, { - "label":"Compression", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Options to compress using gzip or deflate.\n\n`AUTO`: When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the\n outbound request/response accept-encoding/content-encoding option\n`ALWAYS`: Always set accept-encoding/content-encoding in outbound request/response\n`NEVER`: Never set accept-encoding/content-encoding header in outbound request/response" + "label": "HttpOperation", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the HTTP operations related to circuit breaker, failover and load balancer.\n\n`FORWARD`: Forward the specified payload\n`GET`: Request a resource\n`POST`: Create a new resource\n`DELETE`: Deletes the specified resource\n`OPTIONS`: Request communication options available\n`PUT`: Replace the target resource\n`PATCH`: Apply partial modification to the resource\n`HEAD`: Identical to `GET` but no resource body should be returned\n`NONE`: No operation should be performed" }, - "sortText":"171", - "insertText":"Compression", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpOperation", + "insertTextFormat": "Snippet" }, { - "label":"HttpOperation", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the HTTP operations related to circuit breaker, failover and load balancer.\n\n`FORWARD`: Forward the specified payload\n`GET`: Request a resource\n`POST`: Create a new resource\n`DELETE`: Deletes the specified resource\n`OPTIONS`: Request communication options available\n`PUT`: Replace the target resource\n`PATCH`: Apply partial modification to the resource\n`HEAD`: Identical to `GET` but no resource body should be returned\n`NONE`: No operation should be performed" + "label": "RedirectCode", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the HTTP redirect codes as a type." }, - "sortText":"171", - "insertText":"HttpOperation", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RedirectCode", + "insertTextFormat": "Snippet" }, { - "label":"RedirectCode", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the HTTP redirect codes as a type." + "label": "MutualSslStatus", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the possible values for the mutual ssl status.\n\n`passed`: Mutual SSL handshake is succesful.\n`failed`: Mutual SSL handshake has failed." }, - "sortText":"171", - "insertText":"RedirectCode", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "MutualSslStatus", + "insertTextFormat": "Snippet" }, { - "label":"MutualSslStatus", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the possible values for the mutual ssl status.\n\n`passed`: Mutual SSL handshake is succesful.\n`failed`: Mutual SSL handshake has failed." + "label": "CredentialBearer", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Specifies how to send the authentication credentials when exchanging tokens." }, - "sortText":"171", - "insertText":"MutualSslStatus", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CredentialBearer", + "insertTextFormat": "Snippet" }, { - "label":"CredentialBearer", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Specifies how the authentication credentials should be sent when using the refresh token to refresh the access token" + "label": "OAuth2GrantType", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Specifies the type of the OAuth2 grant type" }, - "sortText":"171", - "insertText":"CredentialBearer", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "OAuth2GrantType", + "insertTextFormat": "Snippet" }, { - "label":"CircuitState", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"A finite type for modeling the states of the Circuit Breaker. The Circuit Breaker starts in the `CLOSED` state.\nIf any failure thresholds are exceeded during execution, the circuit trips and goes to the `OPEN` state. After\nthe specified timeout period expires, the circuit goes to the `HALF_OPEN` state. If the trial request sent while\nin the `HALF_OPEN` state succeeds, the circuit goes back to the `CLOSED` state." + "label": "CircuitState", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "A finite type for modeling the states of the Circuit Breaker. The Circuit Breaker starts in the `CLOSED` state.\nIf any failure thresholds are exceeded during execution, the circuit trips and goes to the `OPEN` state. After\nthe specified timeout period expires, the circuit goes to the `HALF_OPEN` state. If the trial request sent while\nin the `HALF_OPEN` state succeeds, the circuit goes back to the `CLOSED` state." }, - "sortText":"171", - "insertText":"CircuitState", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitState", + "insertTextFormat": "Snippet" }, { - "label":"KeepAlive", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the possible values for the keep-alive configuration in service and client endpoints." + "label": "KeepAlive", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the possible values for the keep-alive configuration in service and client endpoints." }, - "sortText":"171", - "insertText":"KeepAlive", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "KeepAlive", + "insertTextFormat": "Snippet" }, { - "label":"RequestMessage", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"The types of messages that are accepted by HTTP `client` when sending out the outbound request." + "label": "RequestMessage", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "The types of messages that are accepted by HTTP `client` when sending out the outbound request." }, - "sortText":"171", - "insertText":"RequestMessage", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RequestMessage", + "insertTextFormat": "Snippet" }, { - "label":"ResponseMessage", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"The types of messages that are accepted by HTTP `listener` when sending out the outbound response." + "label": "ResponseMessage", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "The types of messages that are accepted by HTTP `listener` when sending out the outbound response." }, - "sortText":"171", - "insertText":"ResponseMessage", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ResponseMessage", + "insertTextFormat": "Snippet" } ] } diff --git a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json index cdc48488f90c..3c3eaa2e7084 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json @@ -6,1133 +6,1166 @@ "source": "service/source/serviceBodyCompletion5.bal", "items": [ { - "label":"extractBasicAuthHeaderValue(http:Request req)(string?)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nballerina/http:" + "label": "extractBasicAuthHeaderValue(http:Request req)(string?)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" } }, - "sortText":"121", - "insertText":"extractBasicAuthHeaderValue(${1:req})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "extractBasicAuthHeaderValue(${1:req})", + "insertTextFormat": "Snippet" }, { - "label":"createHttpCachingClient(string url, http:ClientEndpointConfig config, http:CacheConfig cacheConfig)(ballerina/http:Client|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:" + "label": "createHttpCachingClient(string url, http:ClientEndpointConfig config, http:CacheConfig cacheConfig)(ballerina/http:Client|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:Client|error" } }, - "sortText":"121", - "insertText":"createHttpCachingClient(${1:url}, ${2:config}, ${3:cacheConfig})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "createHttpCachingClient(${1:url}, ${2:config}, ${3:cacheConfig})", + "insertTextFormat": "Snippet" }, { - "label":"parseHeader(string headerValue)((string,map)|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \nballerina/http:" + "label": "parseHeader(string headerValue)((string,map)|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \n(string,map)|error" } }, - "sortText":"121", - "insertText":"parseHeader(${1:headerValue})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "parseHeader(${1:headerValue})", + "insertTextFormat": "Snippet" }, { - "label":"invokeEndpoint(string path, http:Request outRequest, FORWARD|GET|POST|DELETE|OPTIONS|PUT|PATCH|HEAD|NONE requestAction, http:Client httpClient)(ballerina/http:Response|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:" + "label": "invokeEndpoint(string path, http:Request outRequest, FORWARD|GET|POST|DELETE|OPTIONS|PUT|PATCH|HEAD|NONE requestAction, http:Client httpClient)(ballerina/http:Response|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:Response|error" } }, - "sortText":"121", - "insertText":"invokeEndpoint(${1:path}, ${2:outRequest}, ${3:requestAction}, ${4:httpClient})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "invokeEndpoint(${1:path}, ${2:outRequest}, ${3:requestAction}, ${4:httpClient})", + "insertTextFormat": "Snippet" }, { - "label":"createHttpSecureClient(string url, http:ClientEndpointConfig config)(ballerina/http:Client|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:" + "label": "createHttpSecureClient(string url, http:ClientEndpointConfig config)(ballerina/http:Client|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:Client|error" } }, - "sortText":"121", - "insertText":"createHttpSecureClient(${1:url}, ${2:config})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "createHttpSecureClient(${1:url}, ${2:config})", + "insertTextFormat": "Snippet" }, { - "label":"encode(string url, string charset)(string|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nballerina/http:" + "label": "encode(string url, string charset)(string|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nstring|error" } }, - "sortText":"121", - "insertText":"encode(${1:url}, ${2:charset})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "encode(${1:url}, ${2:charset})", + "insertTextFormat": "Snippet" }, { - "label":"decode(string url, string charset)(string|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nballerina/http:" + "label": "decode(string url, string charset)(string|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nstring|error" } }, - "sortText":"121", - "insertText":"decode(${1:url}, ${2:charset})", - "insertTextFormat":"Snippet" + "sortText": "121", + "insertText": "decode(${1:url}, ${2:charset})", + "insertTextFormat": "Snippet" }, { - "label":"HttpServiceConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Contains the configurations for an HTTP service.\n" + "label": "HttpServiceConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Contains the configurations for an HTTP service.\n" }, - "sortText":"171", - "insertText":"HttpServiceConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpServiceConfig", + "insertTextFormat": "Snippet" }, { - "label":"CorsConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for CORS support.\n" + "label": "CorsConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for CORS support.\n" }, - "sortText":"171", - "insertText":"CorsConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CorsConfig", + "insertTextFormat": "Snippet" }, { - "label":"Versioning", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for service versioning.\n" + "label": "Versioning", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for service versioning.\n" }, - "sortText":"171", - "insertText":"Versioning", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Versioning", + "insertTextFormat": "Snippet" }, { - "label":"WSServiceConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for a WebSocket service.\n" + "label": "WSServiceConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for a WebSocket service.\n" }, - "sortText":"171", - "insertText":"WSServiceConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WSServiceConfig", + "insertTextFormat": "Snippet" }, { - "label":"HttpResourceConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configuration for an HTTP resource.\n" + "label": "HttpResourceConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configuration for an HTTP resource.\n" }, - "sortText":"171", - "insertText":"HttpResourceConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpResourceConfig", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketUpgradeConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Resource configuration to upgrade from HTTP to WebSocket.\n" + "label": "WebSocketUpgradeConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Resource configuration to upgrade from HTTP to WebSocket.\n" }, - "sortText":"171", - "insertText":"WebSocketUpgradeConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketUpgradeConfig", + "insertTextFormat": "Snippet" }, { - "label":"ListenerAuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures the authentication scheme for a service or a resource.\n" + "label": "ServiceResourceAuth", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures the authentication scheme for a service or a resource.\n" }, - "sortText":"171", - "insertText":"ListenerAuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ServiceResourceAuth", + "insertTextFormat": "Snippet" }, { - "label":"Authentication", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Can be used for enabling/disabling authentication in an HTTP service.\n" + "label": "CacheConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the caching behaviour of the endpoint.\n" }, - "sortText":"171", - "insertText":"Authentication", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CacheConfig", + "insertTextFormat": "Snippet" }, { - "label":"CacheConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the caching behaviour of the endpoint.\n" + "label": "TargetService", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a single service and its related configurations.\n" }, - "sortText":"171", - "insertText":"CacheConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "TargetService", + "insertTextFormat": "Snippet" }, { - "label":"TargetService", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a single service and its related configurations.\n" + "label": "ClientEndpointConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the behaviours when communicating with a remote HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"TargetService", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ClientEndpointConfig", + "insertTextFormat": "Snippet" }, { - "label":"ClientEndpointConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the behaviours when communicating with a remote HTTP endpoint.\n" + "label": "RetryConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides configurations for controlling the retrying behavior in failure scenarios.\n" }, - "sortText":"171", - "insertText":"ClientEndpointConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RetryConfig", + "insertTextFormat": "Snippet" }, { - "label":"RetryConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides configurations for controlling the retry behaviour in failure scenarios.\n" + "label": "SecureSocket", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides configurations for facilitating secure communication with a remote HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"RetryConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "SecureSocket", + "insertTextFormat": "Snippet" }, { - "label":"SecureSocket", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides configurations for facilitating secure communication with a remote HTTP endpoint.\n" + "label": "FollowRedirects", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides configurations for controlling the endpoint's behaviour in response to HTTP redirect related responses.\n" }, - "sortText":"171", - "insertText":"SecureSocket", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FollowRedirects", + "insertTextFormat": "Snippet" }, { - "label":"FollowRedirects", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides configurations for controlling the endpoint\u0027s behaviour in response to HTTP redirect related responses.\n" + "label": "ProxyConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Proxy server configurations to be used with the HTTP client endpoint.\n" }, - "sortText":"171", - "insertText":"FollowRedirects", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ProxyConfig", + "insertTextFormat": "Snippet" }, { - "label":"ProxyConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Proxy server configurations to be used with the HTTP client endpoint.\n" + "label": "OutboundAuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `OutboundAuthConfig` record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"ProxyConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "OutboundAuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"AuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"AuthConfig record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" + "label": "BasicAuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `BasicAuthConfig` record can be used to configure Basic Authentication used by the HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"AuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "BasicAuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"BasicAuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"BasicAuthConfig record can be used to configure Basic Authentication used by the HTTP endpoint.\n" + "label": "OAuth2AuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `OAuth2AuthConfig` record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"BasicAuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "OAuth2AuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"OAuth2AuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"OAuth2AuthConfig record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" + "label": "ClientCredentialsGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `ClientCredentialsGrantConfig` record can be used to configue OAuth2 client credentials grant type.\n" }, - "sortText":"171", - "insertText":"OAuth2AuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ClientCredentialsGrantConfig", + "insertTextFormat": "Snippet" }, { - "label":"JwtAuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"JwtAuthConfig record can be used to configure JWT based authentication used by the HTTP endpoint.\n" + "label": "PasswordGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `PasswordGrantConfig` record can be used to configue OAuth2 password grant type\n" }, - "sortText":"171", - "insertText":"JwtAuthConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "PasswordGrantConfig", + "insertTextFormat": "Snippet" }, { - "label":"HttpTimeoutError", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Defines a timeout error occurred during service invocation.\n" + "label": "DirectTokenConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenConfig` record configures the access token directly.\n" }, - "sortText":"171", - "insertText":"HttpTimeoutError", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "DirectTokenConfig", + "insertTextFormat": "Snippet" }, { - "label":"PoolConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for managing HTTP client connection pool.\n" + "label": "RefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `RefreshConfig` record can be used to pass the configurations for refreshing the access token of password grant type.\n" }, - "sortText":"171", - "insertText":"PoolConfiguration", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RefreshConfig", + "insertTextFormat": "Snippet" }, { - "label":"Protocols", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for configuring SSL/TLS protocol and version to be used.\n" + "label": "DirectTokenRefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenRefreshConfig` record passes the configurations for refreshing the access token for \nthe grant type of the direct token grant type.\n" }, - "sortText":"171", - "insertText":"Protocols", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "DirectTokenRefreshConfig", + "insertTextFormat": "Snippet" }, { - "label":"ValidateCert", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing configurations for certificate revocation status checks.\n" + "label": "JwtAuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `JwtAuthConfig` record can be used to configure JWT based authentication used by the HTTP endpoint.\n" }, - "sortText":"171", - "insertText":"ValidateCert", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "JwtAuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"ServiceOcspStapling", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing configurations for certificate revocation status checks.\n" + "label": "HttpTimeoutError", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Defines a timeout error occurred during service invocation.\n" }, - "sortText":"171", - "insertText":"ServiceOcspStapling", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpTimeoutError", + "insertTextFormat": "Snippet" }, { - "label":"CompressionConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing configurations for content compression.\n" + "label": "PoolConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for managing HTTP client connection pool.\n" }, - "sortText":"171", - "insertText":"CompressionConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "PoolConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"MutualSslHandshake", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing mutual ssl handshake results.\n" + "label": "Protocols", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for configuring SSL/TLS protocol and version to be used.\n" }, - "sortText":"171", - "insertText":"MutualSslHandshake", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Protocols", + "insertTextFormat": "Snippet" }, { - "label":"FailoverConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the failover behaviour of the endpoint.\n" + "label": "ValidateCert", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing configurations for certificate revocation status checks.\n" }, - "sortText":"171", - "insertText":"FailoverConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ValidateCert", + "insertTextFormat": "Snippet" }, { - "label":"FailoverInferredConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Inferred failover configurations passed into the failover client.\n" + "label": "ServiceOcspStapling", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing configurations for certificate revocation status checks.\n" }, - "sortText":"171", - "insertText":"FailoverInferredConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ServiceOcspStapling", + "insertTextFormat": "Snippet" }, { - "label":"FailoverClientEndpointConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of HTTP related configurations and failover related configurations.\n" + "label": "CompressionConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing configurations for content compression.\n" }, - "sortText":"171", - "insertText":"FailoverClientEndpointConfiguration", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CompressionConfig", + "insertTextFormat": "Snippet" }, { - "label":"CircuitHealth", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Maintains the health of the Circuit Breaker.\n" + "label": "MutualSslHandshake", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing mutual ssl handshake results.\n" }, - "sortText":"171", - "insertText":"CircuitHealth", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "MutualSslHandshake", + "insertTextFormat": "Snippet" }, { - "label":"CircuitBreakerConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the behaviour of the Circuit Breaker.\n" + "label": "CachedToken", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `CachedToken` stores the values received from the authorization/token server to use them\nfor the latter requests without requesting tokens again.\n" }, - "sortText":"171", - "insertText":"CircuitBreakerConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CachedToken", + "insertTextFormat": "Snippet" }, { - "label":"RollingWindow", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a rolling window in the Circuit Breaker.\n" + "label": "FailoverConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the failover behaviour of the endpoint.\n" }, - "sortText":"171", - "insertText":"RollingWindow", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FailoverConfig", + "insertTextFormat": "Snippet" }, { - "label":"Bucket", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a discrete sub-part of the time window (Bucket).\n" + "label": "FailoverInferredConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Inferred failover configurations passed into the failover client.\n" }, - "sortText":"171", - "insertText":"Bucket", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FailoverInferredConfig", + "insertTextFormat": "Snippet" }, { - "label":"CircuitBreakerInferredConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Derived set of configurations from the `CircuitBreakerConfig`.\n" + "label": "FailoverClientEndpointConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of HTTP related configurations and failover related configurations.\n" }, - "sortText":"171", - "insertText":"CircuitBreakerInferredConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FailoverClientEndpointConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"RetryInferredConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Derived set of configurations from the `RetryConfig`.\n" + "label": "CircuitHealth", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Maintains the health of the Circuit Breaker.\n" }, - "sortText":"171", - "insertText":"RetryInferredConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitHealth", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalanceActionErrorData", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an error occurred in an remote function of the Load Balance connector.\n" + "label": "CircuitBreakerConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the behaviour of the Circuit Breaker.\n" }, - "sortText":"171", - "insertText":"LoadBalanceActionErrorData", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitBreakerConfig", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalanceClientEndpointConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"The configurations related to the load balance client endpoint.\n" + "label": "RollingWindow", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a rolling window in the Circuit Breaker.\n" }, - "sortText":"171", - "insertText":"LoadBalanceClientEndpointConfiguration", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RollingWindow", + "insertTextFormat": "Snippet" }, { - "label":"Remote", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Presents a read-only view of the remote address.\n" + "label": "Bucket", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a discrete sub-part of the time window (Bucket).\n" }, - "sortText":"171", - "insertText":"Remote", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Bucket", + "insertTextFormat": "Snippet" }, { - "label":"Local", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Presents a read-only view of the local address.\n" + "label": "CircuitBreakerInferredConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Derived set of configurations from the `CircuitBreakerConfig`.\n" }, - "sortText":"171", - "insertText":"Local", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitBreakerInferredConfig", + "insertTextFormat": "Snippet" }, { - "label":"RequestLimits", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures limits for requests. If these limits are violated, the request is rejected.\n" + "label": "RetryInferredConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Derived set of configurations from the `RetryConfig`.\n" }, - "sortText":"171", - "insertText":"RequestLimits", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RetryInferredConfig", + "insertTextFormat": "Snippet" }, { - "label":"ServiceEndpointConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for HTTP service endpoints.\n" + "label": "LoadBalanceActionErrorData", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an error occurred in an remote function of the Load Balance connector.\n" }, - "sortText":"171", - "insertText":"ServiceEndpointConfiguration", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalanceActionErrorData", + "insertTextFormat": "Snippet" }, { - "label":"ServiceSecureSocket", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures the SSL/TLS options to be used for HTTP service.\n" + "label": "LoadBalanceClientEndpointConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The configurations related to the load balance client endpoint.\n" }, - "sortText":"171", - "insertText":"ServiceSecureSocket", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalanceClientEndpointConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"AuthCacheConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" + "label": "Remote", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Presents a read-only view of the remote address.\n" }, - "sortText":"171", - "insertText":"AuthCacheConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Remote", + "insertTextFormat": "Snippet" }, { - "label":"AuthProvider", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configuration for authentication providers.\n" + "label": "Local", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Presents a read-only view of the local address.\n" }, - "sortText":"171", - "insertText":"AuthProvider", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Local", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketClientEndpointConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configuration for the WebSocket client endpoint.\n" + "label": "RequestLimits", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures limits for requests. If these limits are violated, the request is rejected.\n" }, - "sortText":"171", - "insertText":"WebSocketClientEndpointConfig", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RequestLimits", + "insertTextFormat": "Snippet" }, { - "label":"AuthHandlerRegistry", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of the Http Auth Handler Registry.\n" + "label": "ServiceEndpointConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for HTTP service endpoints.\n" }, - "sortText":"171", - "insertText":"AuthHandlerRegistry", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ServiceEndpointConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"AuthnFilter", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of the Authentication filter.\n" + "label": "ListenerAuth", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Authentication configurations for the listener.\n" }, - "sortText":"171", - "insertText":"AuthnFilter", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ListenerAuth", + "insertTextFormat": "Snippet" }, { - "label":"HttpAuthnHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of Authentication handler for HTTP traffic.\n" + "label": "ServiceSecureSocket", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures the SSL/TLS options to be used for HTTP service.\n" }, - "sortText":"171", - "insertText":"HttpAuthnHandler", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ServiceSecureSocket", + "insertTextFormat": "Snippet" }, { - "label":"AuthnHandlerChain", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of Authentication handler chain\n" + "label": "AuthCacheConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" }, - "sortText":"171", - "insertText":"AuthnHandlerChain", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthCacheConfig", + "insertTextFormat": "Snippet" }, { - "label":"AuthzFilter", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of the Authorization filter\n" + "label": "WebSocketClientEndpointConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configuration for the WebSocket client endpoint.\n" }, - "sortText":"171", - "insertText":"AuthzFilter", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketClientEndpointConfig", + "insertTextFormat": "Snippet" }, { - "label":"HttpAuthzHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of Authorization Handler for HTTP\n" + "label": "AuthnFilter", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of the Authentication filter.\n" }, - "sortText":"171", - "insertText":"HttpAuthzHandler", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthnFilter", + "insertTextFormat": "Snippet" }, { - "label":"HttpBasicAuthnHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Defines Basic Auth handler for HTTP traffic.\n" + "label": "AuthnHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of Authentication handler for HTTP traffic." }, - "sortText":"171", - "insertText":"HttpBasicAuthnHandler", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthnHandler", + "insertTextFormat": "Snippet" }, { - "label":"HttpJwtAuthnHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of JWT Auth handler for HTTP traffic\n" + "label": "AuthzFilter", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of the Authorization filter\n" }, - "sortText":"171", - "insertText":"HttpJwtAuthnHandler", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthzFilter", + "insertTextFormat": "Snippet" }, { - "label":"RequestCacheControl", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures cache control directives for a `Request`.\n" + "label": "AuthzHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of Authorization Handler for HTTP\n" }, - "sortText":"171", - "insertText":"RequestCacheControl", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "AuthzHandler", + "insertTextFormat": "Snippet" }, { - "label":"ResponseCacheControl", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures cache control directives for a `Response`.\n" + "label": "BasicAuthnHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Defines Basic Auth handler for HTTP traffic.\n" }, - "sortText":"171", - "insertText":"ResponseCacheControl", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "BasicAuthnHandler", + "insertTextFormat": "Snippet" }, { - "label":"HttpCache", - "kind":"Class", - "detail":"BType", - "sortText":"171", - "insertText":"HttpCache", - "insertTextFormat":"Snippet" + "label": "JwtAuthnHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of JWT Auth handler for HTTP traffic\n" + }, + "sortText": "171", + "insertText": "JwtAuthnHandler", + "insertTextFormat": "Snippet" + }, + { + "label": "RequestCacheControl", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures cache control directives for a `Request`.\n" + }, + "sortText": "171", + "insertText": "RequestCacheControl", + "insertTextFormat": "Snippet" + }, + { + "label": "ResponseCacheControl", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures cache control directives for a `Response`.\n" + }, + "sortText": "171", + "insertText": "ResponseCacheControl", + "insertTextFormat": "Snippet" + }, + { + "label": "HttpCache", + "kind": "Class", + "detail": "BType", + "sortText": "171", + "insertText": "HttpCache", + "insertTextFormat": "Snippet" }, { - "label":"HttpFuture", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a \u0027future\u0027 that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." + "label": "HttpFuture", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a 'future' that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." }, - "sortText":"171", - "insertText":"HttpFuture", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpFuture", + "insertTextFormat": "Snippet" }, { - "label":"PushPromise", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an HTTP/2 `PUSH_PROMISE` frame.\n" + "label": "PushPromise", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an HTTP/2 `PUSH_PROMISE` frame.\n" }, - "sortText":"171", - "insertText":"PushPromise", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "PushPromise", + "insertTextFormat": "Snippet" }, { - "label":"Filter", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of a HTTP Request Filter. This filter will be applied before the request is dispatched to the relevant resource. Any Filter implementation should be structurally similar to the Filter object." + "label": "Filter", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of a HTTP Request Filter. This filter will be applied before the request is dispatched to the relevant resource. Any Filter implementation should be structurally similar to the Filter object." }, - "sortText":"171", - "insertText":"Filter", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Filter", + "insertTextFormat": "Snippet" }, { - "label":"FilterContext", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of request filter Context.\n" + "label": "FilterContext", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of request filter Context.\n" }, - "sortText":"171", - "insertText":"FilterContext", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FilterContext", + "insertTextFormat": "Snippet" }, { - "label":"Request", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an HTTP request.\n" + "label": "Request", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an HTTP request.\n" }, - "sortText":"171", - "insertText":"Request", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Request", + "insertTextFormat": "Snippet" }, { - "label":"Response", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an HTTP response.\n" + "label": "Response", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an HTTP response.\n" }, - "sortText":"171", - "insertText":"Response", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Response", + "insertTextFormat": "Snippet" }, { - "label":"MockListener", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Mock server endpoint which does not open a listening port." + "label": "MockListener", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Mock server endpoint which does not open a listening port." }, - "sortText":"171", - "insertText":"MockListener", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "MockListener", + "insertTextFormat": "Snippet" }, { - "label":"CircuitBreakerClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A Circuit Breaker implementation which can be used to gracefully handle network failures.\n" + "label": "CircuitBreakerClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A Circuit Breaker implementation which can be used to gracefully handle network failures.\n" }, - "sortText":"171", - "insertText":"CircuitBreakerClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitBreakerClient", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalancerRule", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"\nLoadBalancerRule provides a required interfaces to implement different algorithms.\n" + "label": "LoadBalancerRule", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "\nLoadBalancerRule provides a required interfaces to implement different algorithms.\n" }, - "sortText":"171", - "insertText":"LoadBalancerRule", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalancerRule", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalancerRounRobinRule", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Implementation of round robin load balancing strategy.\n" + "label": "LoadBalancerRounRobinRule", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Implementation of round robin load balancing strategy.\n" }, - "sortText":"171", - "insertText":"LoadBalancerRounRobinRule", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalancerRounRobinRule", + "insertTextFormat": "Snippet" }, { - "label":"Listener", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"This is used for creating HTTP server endpoints. An HTTP server endpoint is capable of responding to\nremote callers. The `Listener` is responsible for initializing the endpoint using the provided configurations." + "label": "Listener", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "This is used for creating HTTP server endpoints. An HTTP server endpoint is capable of responding to\nremote callers. The `Listener` is responsible for initializing the endpoint using the provided configurations." }, - "sortText":"171", - "insertText":"Listener", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Listener", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketListener", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a WebSocket service endpoint." + "label": "WebSocketListener", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a WebSocket service endpoint." }, - "sortText":"171", - "insertText":"WebSocketListener", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketListener", + "insertTextFormat": "Snippet" }, { - "label":"HttpCachingClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"An HTTP caching client implementation which takes an `HttpActions` instance and wraps it with an HTTP caching layer.\n" + "label": "HttpCachingClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "An HTTP caching client implementation which takes an `HttpActions` instance and wraps it with an HTTP caching layer.\n" }, - "sortText":"171", - "insertText":"HttpCachingClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpCachingClient", + "insertTextFormat": "Snippet" }, { - "label":"Client", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs." + "label": "Client", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs." }, - "sortText":"171", - "insertText":"Client", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Client", + "insertTextFormat": "Snippet" }, { - "label":"HttpCaller", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides the HTTP actions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP actions implementation.\n" + "label": "HttpCaller", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides the HTTP actions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP actions implementation.\n" }, - "sortText":"171", - "insertText":"HttpCaller", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpCaller", + "insertTextFormat": "Snippet" }, { - "label":"Caller", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"The caller actions for responding to client requests.\n" + "label": "Caller", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The caller actions for responding to client requests.\n" }, - "sortText":"171", - "insertText":"Caller", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Caller", + "insertTextFormat": "Snippet" }, { - "label":"HttpSecureClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides secure HTTP remote functions for interacting with HTTP endpoints. This will make use of the authentication\nschemes configured in the HTTP client endpoint to secure the HTTP requests.\n" + "label": "HttpSecureClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides secure HTTP remote functions for interacting with HTTP endpoints. This will make use of the authentication\nschemes configured in the HTTP client endpoint to secure the HTTP requests.\n" }, - "sortText":"171", - "insertText":"HttpSecureClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpSecureClient", + "insertTextFormat": "Snippet" }, { - "label":"HttpClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides the HTTP remote functions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP remote functions implementation.\n" + "label": "HttpClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides the HTTP remote functions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP remote functions implementation.\n" }, - "sortText":"171", - "insertText":"HttpClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpClient", + "insertTextFormat": "Snippet" }, { - "label":"RedirectClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides redirect functionality for HTTP client remote functions.\n" + "label": "RedirectClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides redirect functionality for HTTP client remote functions.\n" }, - "sortText":"171", - "insertText":"RedirectClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RedirectClient", + "insertTextFormat": "Snippet" }, { - "label":"FailoverClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"An HTTP client endpoint which provides failover support over multiple HTTP clients.\n" + "label": "FailoverClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "An HTTP client endpoint which provides failover support over multiple HTTP clients.\n" }, - "sortText":"171", - "insertText":"FailoverClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "FailoverClient", + "insertTextFormat": "Snippet" }, { - "label":"RetryClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides the HTTP remote functions for interacting with an HTTP endpoint. This is created by wrapping the HTTP client\nto provide retrying over HTTP requests.\n" + "label": "RetryClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides the HTTP remote functions for interacting with an HTTP endpoint. This is created by wrapping the HTTP client\nto provide retrying over HTTP requests.\n" }, - "sortText":"171", - "insertText":"RetryClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RetryClient", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalanceClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"LoadBalanceClient endpoint provides load balancing functionality over multiple HTTP clients.\n" + "label": "LoadBalanceClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "LoadBalanceClient endpoint provides load balancing functionality over multiple HTTP clients.\n" }, - "sortText":"171", - "insertText":"LoadBalanceClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "LoadBalanceClient", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketCaller", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a WebSocket caller.\n" + "label": "WebSocketCaller", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a WebSocket caller.\n" }, - "sortText":"171", - "insertText":"WebSocketCaller", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketCaller", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a WebSocket client endpoint.\n" + "label": "WebSocketClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a WebSocket client endpoint.\n" }, - "sortText":"171", - "insertText":"WebSocketClient", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "WebSocketClient", + "insertTextFormat": "Snippet" }, { - "label":"InboundAuthScheme", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Inbound authentication schemes." + "label": "InboundAuthScheme", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Inbound authentication schemes." }, - "sortText":"171", - "insertText":"InboundAuthScheme", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "InboundAuthScheme", + "insertTextFormat": "Snippet" }, { - "label":"OutboundAuthScheme", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Outbound authentication schemes." + "label": "OutboundAuthScheme", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Outbound authentication schemes." }, - "sortText":"171", - "insertText":"OutboundAuthScheme", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "OutboundAuthScheme", + "insertTextFormat": "Snippet" }, { - "label":"AuthStoreProvider", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Authentication storage providers for BasicAuth scheme." + "label": "CachingPolicy", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Used for configuring the caching behaviour. Setting the `policy` field in the `CacheConfig` record allows\nthe user to control the caching behaviour." }, - "sortText":"171", - "insertText":"AuthStoreProvider", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CachingPolicy", + "insertTextFormat": "Snippet" }, { - "label":"CachingPolicy", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Used for configuring the caching behaviour. Setting the `policy` field in the `CacheConfig` record allows\nthe user to control the caching behaviour." + "label": "Chunking", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the possible values for the chunking configuration in HTTP services and clients.\n\n`AUTO`: If the payload is less than 8KB, content-length header is set in the outbound request/response,\n otherwise chunking header is set in the outbound request/response\n`ALWAYS`: Always set chunking header in the response\n`NEVER`: Never set the chunking header even if the payload is larger than 8KB in the outbound request/response" }, - "sortText":"171", - "insertText":"CachingPolicy", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Chunking", + "insertTextFormat": "Snippet" }, { - "label":"Chunking", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the possible values for the chunking configuration in HTTP services and clients.\n\n`AUTO`: If the payload is less than 8KB, content-length header is set in the outbound request/response,\n otherwise chunking header is set in the outbound request/response\n`ALWAYS`: Always set chunking header in the response\n`NEVER`: Never set the chunking header even if the payload is larger than 8KB in the outbound request/response" + "label": "Compression", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Options to compress using gzip or deflate.\n\n`AUTO`: When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the\n outbound request/response accept-encoding/content-encoding option\n`ALWAYS`: Always set accept-encoding/content-encoding in outbound request/response\n`NEVER`: Never set accept-encoding/content-encoding header in outbound request/response" }, - "sortText":"171", - "insertText":"Chunking", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "Compression", + "insertTextFormat": "Snippet" }, { - "label":"Compression", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Options to compress using gzip or deflate.\n\n`AUTO`: When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the\n outbound request/response accept-encoding/content-encoding option\n`ALWAYS`: Always set accept-encoding/content-encoding in outbound request/response\n`NEVER`: Never set accept-encoding/content-encoding header in outbound request/response" + "label": "HttpOperation", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the HTTP operations related to circuit breaker, failover and load balancer.\n\n`FORWARD`: Forward the specified payload\n`GET`: Request a resource\n`POST`: Create a new resource\n`DELETE`: Deletes the specified resource\n`OPTIONS`: Request communication options available\n`PUT`: Replace the target resource\n`PATCH`: Apply partial modification to the resource\n`HEAD`: Identical to `GET` but no resource body should be returned\n`NONE`: No operation should be performed" }, - "sortText":"171", - "insertText":"Compression", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "HttpOperation", + "insertTextFormat": "Snippet" }, { - "label":"HttpOperation", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the HTTP operations related to circuit breaker, failover and load balancer.\n\n`FORWARD`: Forward the specified payload\n`GET`: Request a resource\n`POST`: Create a new resource\n`DELETE`: Deletes the specified resource\n`OPTIONS`: Request communication options available\n`PUT`: Replace the target resource\n`PATCH`: Apply partial modification to the resource\n`HEAD`: Identical to `GET` but no resource body should be returned\n`NONE`: No operation should be performed" + "label": "RedirectCode", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the HTTP redirect codes as a type." }, - "sortText":"171", - "insertText":"HttpOperation", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RedirectCode", + "insertTextFormat": "Snippet" }, { - "label":"RedirectCode", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the HTTP redirect codes as a type." + "label": "MutualSslStatus", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the possible values for the mutual ssl status.\n\n`passed`: Mutual SSL handshake is succesful.\n`failed`: Mutual SSL handshake has failed." }, - "sortText":"171", - "insertText":"RedirectCode", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "MutualSslStatus", + "insertTextFormat": "Snippet" }, { - "label":"MutualSslStatus", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the possible values for the mutual ssl status.\n\n`passed`: Mutual SSL handshake is succesful.\n`failed`: Mutual SSL handshake has failed." + "label": "CredentialBearer", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Specifies how to send the authentication credentials when exchanging tokens." }, - "sortText":"171", - "insertText":"MutualSslStatus", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CredentialBearer", + "insertTextFormat": "Snippet" }, { - "label":"CredentialBearer", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Specifies how the authentication credentials should be sent when using the refresh token to refresh the access token" + "label": "OAuth2GrantType", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Specifies the type of the OAuth2 grant type" }, - "sortText":"171", - "insertText":"CredentialBearer", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "OAuth2GrantType", + "insertTextFormat": "Snippet" }, { - "label":"CircuitState", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"A finite type for modeling the states of the Circuit Breaker. The Circuit Breaker starts in the `CLOSED` state.\nIf any failure thresholds are exceeded during execution, the circuit trips and goes to the `OPEN` state. After\nthe specified timeout period expires, the circuit goes to the `HALF_OPEN` state. If the trial request sent while\nin the `HALF_OPEN` state succeeds, the circuit goes back to the `CLOSED` state." + "label": "CircuitState", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "A finite type for modeling the states of the Circuit Breaker. The Circuit Breaker starts in the `CLOSED` state.\nIf any failure thresholds are exceeded during execution, the circuit trips and goes to the `OPEN` state. After\nthe specified timeout period expires, the circuit goes to the `HALF_OPEN` state. If the trial request sent while\nin the `HALF_OPEN` state succeeds, the circuit goes back to the `CLOSED` state." }, - "sortText":"171", - "insertText":"CircuitState", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "CircuitState", + "insertTextFormat": "Snippet" }, { - "label":"KeepAlive", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the possible values for the keep-alive configuration in service and client endpoints." + "label": "KeepAlive", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the possible values for the keep-alive configuration in service and client endpoints." }, - "sortText":"171", - "insertText":"KeepAlive", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "KeepAlive", + "insertTextFormat": "Snippet" }, { - "label":"RequestMessage", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"The types of messages that are accepted by HTTP `client` when sending out the outbound request." + "label": "RequestMessage", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "The types of messages that are accepted by HTTP `client` when sending out the outbound request." }, - "sortText":"171", - "insertText":"RequestMessage", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "RequestMessage", + "insertTextFormat": "Snippet" }, { - "label":"ResponseMessage", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"The types of messages that are accepted by HTTP `listener` when sending out the outbound response." + "label": "ResponseMessage", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "The types of messages that are accepted by HTTP `listener` when sending out the outbound response." }, - "sortText":"171", - "insertText":"ResponseMessage", - "insertTextFormat":"Snippet" + "sortText": "171", + "insertText": "ResponseMessage", + "insertTextFormat": "Snippet" } ] } diff --git a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json index 691b68361c90..7fa95e69faa0 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json @@ -6,1032 +6,1062 @@ "source": "service/source/serviceEndpointBind4.bal", "items": [ { - "label":"extractBasicAuthHeaderValue(http:Request req)(string?)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nballerina/http:" + "label": "extractBasicAuthHeaderValue(http:Request req)(string?)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" } }, - "insertText":"extractBasicAuthHeaderValue(${1:req})", - "insertTextFormat":"Snippet" + "insertText": "extractBasicAuthHeaderValue(${1:req})", + "insertTextFormat": "Snippet" }, { - "label":"createHttpCachingClient(string url, http:ClientEndpointConfig config, http:CacheConfig cacheConfig)(ballerina/http:Client|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:" + "label": "createHttpCachingClient(string url, http:ClientEndpointConfig config, http:CacheConfig cacheConfig)(ballerina/http:Client|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:Client|error" } }, - "insertText":"createHttpCachingClient(${1:url}, ${2:config}, ${3:cacheConfig})", - "insertTextFormat":"Snippet" + "insertText": "createHttpCachingClient(${1:url}, ${2:config}, ${3:cacheConfig})", + "insertTextFormat": "Snippet" }, { - "label":"parseHeader(string headerValue)((string,map)|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \nballerina/http:" + "label": "parseHeader(string headerValue)((string,map)|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \n(string,map)|error" } }, - "insertText":"parseHeader(${1:headerValue})", - "insertTextFormat":"Snippet" + "insertText": "parseHeader(${1:headerValue})", + "insertTextFormat": "Snippet" }, { - "label":"invokeEndpoint(string path, http:Request outRequest, FORWARD|GET|POST|DELETE|OPTIONS|PUT|PATCH|HEAD|NONE requestAction, http:Client httpClient)(ballerina/http:Response|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:" + "label": "invokeEndpoint(string path, http:Request outRequest, FORWARD|GET|POST|DELETE|OPTIONS|PUT|PATCH|HEAD|NONE requestAction, http:Client httpClient)(ballerina/http:Response|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:Response|error" } }, - "insertText":"invokeEndpoint(${1:path}, ${2:outRequest}, ${3:requestAction}, ${4:httpClient})", - "insertTextFormat":"Snippet" + "insertText": "invokeEndpoint(${1:path}, ${2:outRequest}, ${3:requestAction}, ${4:httpClient})", + "insertTextFormat": "Snippet" }, { - "label":"createHttpSecureClient(string url, http:ClientEndpointConfig config)(ballerina/http:Client|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:" + "label": "createHttpSecureClient(string url, http:ClientEndpointConfig config)(ballerina/http:Client|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:Client|error" } }, - "insertText":"createHttpSecureClient(${1:url}, ${2:config})", - "insertTextFormat":"Snippet" + "insertText": "createHttpSecureClient(${1:url}, ${2:config})", + "insertTextFormat": "Snippet" }, { - "label":"encode(string url, string charset)(string|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nballerina/http:" + "label": "encode(string url, string charset)(string|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nstring|error" } }, - "insertText":"encode(${1:url}, ${2:charset})", - "insertTextFormat":"Snippet" + "insertText": "encode(${1:url}, ${2:charset})", + "insertTextFormat": "Snippet" }, { - "label":"decode(string url, string charset)(string|error)", - "kind":"Function", - "detail":"Function", - "documentation":{ - "right":{ - "kind":"markdown", - "value":"markdown**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nballerina/http:" + "label": "decode(string url, string charset)(string|error)", + "kind": "Function", + "detail": "Function", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nstring|error" } }, - "insertText":"decode(${1:url}, ${2:charset})", - "insertTextFormat":"Snippet" + "insertText": "decode(${1:url}, ${2:charset})", + "insertTextFormat": "Snippet" }, { - "label":"HttpServiceConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Contains the configurations for an HTTP service.\n" + "label": "HttpServiceConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Contains the configurations for an HTTP service.\n" }, - "insertText":"HttpServiceConfig", - "insertTextFormat":"Snippet" + "insertText": "HttpServiceConfig", + "insertTextFormat": "Snippet" }, { - "label":"CorsConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for CORS support.\n" + "label": "CorsConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for CORS support.\n" }, - "insertText":"CorsConfig", - "insertTextFormat":"Snippet" + "insertText": "CorsConfig", + "insertTextFormat": "Snippet" }, { - "label":"Versioning", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for service versioning.\n" + "label": "Versioning", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for service versioning.\n" }, - "insertText":"Versioning", - "insertTextFormat":"Snippet" + "insertText": "Versioning", + "insertTextFormat": "Snippet" }, { - "label":"WSServiceConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for a WebSocket service.\n" + "label": "WSServiceConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for a WebSocket service.\n" }, - "insertText":"WSServiceConfig", - "insertTextFormat":"Snippet" + "insertText": "WSServiceConfig", + "insertTextFormat": "Snippet" }, { - "label":"HttpResourceConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configuration for an HTTP resource.\n" + "label": "HttpResourceConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configuration for an HTTP resource.\n" }, - "insertText":"HttpResourceConfig", - "insertTextFormat":"Snippet" + "insertText": "HttpResourceConfig", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketUpgradeConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Resource configuration to upgrade from HTTP to WebSocket.\n" + "label": "WebSocketUpgradeConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Resource configuration to upgrade from HTTP to WebSocket.\n" }, - "insertText":"WebSocketUpgradeConfig", - "insertTextFormat":"Snippet" + "insertText": "WebSocketUpgradeConfig", + "insertTextFormat": "Snippet" }, { - "label":"ListenerAuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures the authentication scheme for a service or a resource.\n" + "label": "ServiceResourceAuth", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures the authentication scheme for a service or a resource.\n" }, - "insertText":"ListenerAuthConfig", - "insertTextFormat":"Snippet" + "insertText": "ServiceResourceAuth", + "insertTextFormat": "Snippet" }, { - "label":"Authentication", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Can be used for enabling/disabling authentication in an HTTP service.\n" + "label": "CacheConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the caching behaviour of the endpoint.\n" }, - "insertText":"Authentication", - "insertTextFormat":"Snippet" + "insertText": "CacheConfig", + "insertTextFormat": "Snippet" }, { - "label":"CacheConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the caching behaviour of the endpoint.\n" + "label": "TargetService", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a single service and its related configurations.\n" }, - "insertText":"CacheConfig", - "insertTextFormat":"Snippet" + "insertText": "TargetService", + "insertTextFormat": "Snippet" }, { - "label":"TargetService", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a single service and its related configurations.\n" + "label": "ClientEndpointConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the behaviours when communicating with a remote HTTP endpoint.\n" }, - "insertText":"TargetService", - "insertTextFormat":"Snippet" + "insertText": "ClientEndpointConfig", + "insertTextFormat": "Snippet" }, { - "label":"ClientEndpointConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the behaviours when communicating with a remote HTTP endpoint.\n" + "label": "RetryConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides configurations for controlling the retrying behavior in failure scenarios.\n" }, - "insertText":"ClientEndpointConfig", - "insertTextFormat":"Snippet" + "insertText": "RetryConfig", + "insertTextFormat": "Snippet" }, { - "label":"RetryConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides configurations for controlling the retry behaviour in failure scenarios.\n" + "label": "SecureSocket", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides configurations for facilitating secure communication with a remote HTTP endpoint.\n" }, - "insertText":"RetryConfig", - "insertTextFormat":"Snippet" + "insertText": "SecureSocket", + "insertTextFormat": "Snippet" }, { - "label":"SecureSocket", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides configurations for facilitating secure communication with a remote HTTP endpoint.\n" + "label": "FollowRedirects", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides configurations for controlling the endpoint's behaviour in response to HTTP redirect related responses.\n" }, - "insertText":"SecureSocket", - "insertTextFormat":"Snippet" + "insertText": "FollowRedirects", + "insertTextFormat": "Snippet" }, { - "label":"FollowRedirects", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides configurations for controlling the endpoint\u0027s behaviour in response to HTTP redirect related responses.\n" + "label": "ProxyConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Proxy server configurations to be used with the HTTP client endpoint.\n" }, - "insertText":"FollowRedirects", - "insertTextFormat":"Snippet" + "insertText": "ProxyConfig", + "insertTextFormat": "Snippet" }, { - "label":"ProxyConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Proxy server configurations to be used with the HTTP client endpoint.\n" + "label": "OutboundAuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `OutboundAuthConfig` record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" }, - "insertText":"ProxyConfig", - "insertTextFormat":"Snippet" + "insertText": "OutboundAuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"AuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"AuthConfig record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" + "label": "BasicAuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `BasicAuthConfig` record can be used to configure Basic Authentication used by the HTTP endpoint.\n" }, - "insertText":"AuthConfig", - "insertTextFormat":"Snippet" + "insertText": "BasicAuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"BasicAuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"BasicAuthConfig record can be used to configure Basic Authentication used by the HTTP endpoint.\n" + "label": "OAuth2AuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `OAuth2AuthConfig` record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" }, - "insertText":"BasicAuthConfig", - "insertTextFormat":"Snippet" + "insertText": "OAuth2AuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"OAuth2AuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"OAuth2AuthConfig record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" + "label": "ClientCredentialsGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `ClientCredentialsGrantConfig` record can be used to configue OAuth2 client credentials grant type.\n" }, - "insertText":"OAuth2AuthConfig", - "insertTextFormat":"Snippet" + "insertText": "ClientCredentialsGrantConfig", + "insertTextFormat": "Snippet" }, { - "label":"JwtAuthConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"JwtAuthConfig record can be used to configure JWT based authentication used by the HTTP endpoint.\n" + "label": "PasswordGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `PasswordGrantConfig` record can be used to configue OAuth2 password grant type\n" }, - "insertText":"JwtAuthConfig", - "insertTextFormat":"Snippet" + "insertText": "PasswordGrantConfig", + "insertTextFormat": "Snippet" }, { - "label":"HttpTimeoutError", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Defines a timeout error occurred during service invocation.\n" + "label": "DirectTokenConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenConfig` record configures the access token directly.\n" }, - "insertText":"HttpTimeoutError", - "insertTextFormat":"Snippet" + "insertText": "DirectTokenConfig", + "insertTextFormat": "Snippet" }, { - "label":"PoolConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configurations for managing HTTP client connection pool.\n" + "label": "RefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `RefreshConfig` record can be used to pass the configurations for refreshing the access token of password grant type.\n" }, - "insertText":"PoolConfiguration", - "insertTextFormat":"Snippet" + "insertText": "RefreshConfig", + "insertTextFormat": "Snippet" }, { - "label":"Protocols", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for configuring SSL/TLS protocol and version to be used.\n" + "label": "DirectTokenRefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenRefreshConfig` record passes the configurations for refreshing the access token for \nthe grant type of the direct token grant type.\n" }, - "insertText":"Protocols", - "insertTextFormat":"Snippet" + "insertText": "DirectTokenRefreshConfig", + "insertTextFormat": "Snippet" }, { - "label":"ValidateCert", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing configurations for certificate revocation status checks.\n" + "label": "JwtAuthConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `JwtAuthConfig` record can be used to configure JWT based authentication used by the HTTP endpoint.\n" }, - "insertText":"ValidateCert", - "insertTextFormat":"Snippet" + "insertText": "JwtAuthConfig", + "insertTextFormat": "Snippet" }, { - "label":"ServiceOcspStapling", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing configurations for certificate revocation status checks.\n" + "label": "HttpTimeoutError", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Defines a timeout error occurred during service invocation.\n" }, - "insertText":"ServiceOcspStapling", - "insertTextFormat":"Snippet" + "insertText": "HttpTimeoutError", + "insertTextFormat": "Snippet" }, { - "label":"CompressionConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing configurations for content compression.\n" + "label": "PoolConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configurations for managing HTTP client connection pool.\n" }, - "insertText":"CompressionConfig", - "insertTextFormat":"Snippet" + "insertText": "PoolConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"MutualSslHandshake", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A record for providing mutual ssl handshake results.\n" + "label": "Protocols", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for configuring SSL/TLS protocol and version to be used.\n" }, - "insertText":"MutualSslHandshake", - "insertTextFormat":"Snippet" + "insertText": "Protocols", + "insertTextFormat": "Snippet" }, { - "label":"FailoverConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the failover behaviour of the endpoint.\n" + "label": "ValidateCert", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing configurations for certificate revocation status checks.\n" }, - "insertText":"FailoverConfig", - "insertTextFormat":"Snippet" + "insertText": "ValidateCert", + "insertTextFormat": "Snippet" }, { - "label":"FailoverInferredConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Inferred failover configurations passed into the failover client.\n" + "label": "ServiceOcspStapling", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing configurations for certificate revocation status checks.\n" }, - "insertText":"FailoverInferredConfig", - "insertTextFormat":"Snippet" + "insertText": "ServiceOcspStapling", + "insertTextFormat": "Snippet" }, { - "label":"FailoverClientEndpointConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of HTTP related configurations and failover related configurations.\n" + "label": "CompressionConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing configurations for content compression.\n" }, - "insertText":"FailoverClientEndpointConfiguration", - "insertTextFormat":"Snippet" + "insertText": "CompressionConfig", + "insertTextFormat": "Snippet" }, { - "label":"CircuitHealth", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Maintains the health of the Circuit Breaker.\n" + "label": "MutualSslHandshake", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A record for providing mutual ssl handshake results.\n" }, - "insertText":"CircuitHealth", - "insertTextFormat":"Snippet" + "insertText": "MutualSslHandshake", + "insertTextFormat": "Snippet" }, { - "label":"CircuitBreakerConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the behaviour of the Circuit Breaker.\n" + "label": "CachedToken", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `CachedToken` stores the values received from the authorization/token server to use them\nfor the latter requests without requesting tokens again.\n" }, - "insertText":"CircuitBreakerConfig", - "insertTextFormat":"Snippet" + "insertText": "CachedToken", + "insertTextFormat": "Snippet" }, { - "label":"RollingWindow", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a rolling window in the Circuit Breaker.\n" + "label": "FailoverConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the failover behaviour of the endpoint.\n" }, - "insertText":"RollingWindow", - "insertTextFormat":"Snippet" + "insertText": "FailoverConfig", + "insertTextFormat": "Snippet" }, { - "label":"Bucket", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a discrete sub-part of the time window (Bucket).\n" + "label": "FailoverInferredConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Inferred failover configurations passed into the failover client.\n" }, - "insertText":"Bucket", - "insertTextFormat":"Snippet" + "insertText": "FailoverInferredConfig", + "insertTextFormat": "Snippet" }, { - "label":"CircuitBreakerInferredConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Derived set of configurations from the `CircuitBreakerConfig`.\n" + "label": "FailoverClientEndpointConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of HTTP related configurations and failover related configurations.\n" }, - "insertText":"CircuitBreakerInferredConfig", - "insertTextFormat":"Snippet" + "insertText": "FailoverClientEndpointConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"RetryInferredConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Derived set of configurations from the `RetryConfig`.\n" + "label": "CircuitHealth", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Maintains the health of the Circuit Breaker.\n" }, - "insertText":"RetryInferredConfig", - "insertTextFormat":"Snippet" + "insertText": "CircuitHealth", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalanceActionErrorData", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an error occurred in an remote function of the Load Balance connector.\n" + "label": "CircuitBreakerConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the behaviour of the Circuit Breaker.\n" }, - "insertText":"LoadBalanceActionErrorData", - "insertTextFormat":"Snippet" + "insertText": "CircuitBreakerConfig", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalanceClientEndpointConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"The configurations related to the load balance client endpoint.\n" + "label": "RollingWindow", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a rolling window in the Circuit Breaker.\n" }, - "insertText":"LoadBalanceClientEndpointConfiguration", - "insertTextFormat":"Snippet" + "insertText": "RollingWindow", + "insertTextFormat": "Snippet" }, { - "label":"Remote", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Presents a read-only view of the remote address.\n" + "label": "Bucket", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a discrete sub-part of the time window (Bucket).\n" }, - "insertText":"Remote", - "insertTextFormat":"Snippet" + "insertText": "Bucket", + "insertTextFormat": "Snippet" }, { - "label":"Local", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Presents a read-only view of the local address.\n" + "label": "CircuitBreakerInferredConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Derived set of configurations from the `CircuitBreakerConfig`.\n" }, - "insertText":"Local", - "insertTextFormat":"Snippet" + "insertText": "CircuitBreakerInferredConfig", + "insertTextFormat": "Snippet" }, { - "label":"RequestLimits", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures limits for requests. If these limits are violated, the request is rejected.\n" + "label": "RetryInferredConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Derived set of configurations from the `RetryConfig`.\n" }, - "insertText":"RequestLimits", - "insertTextFormat":"Snippet" + "insertText": "RetryInferredConfig", + "insertTextFormat": "Snippet" }, { - "label":"ServiceEndpointConfiguration", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for HTTP service endpoints.\n" + "label": "LoadBalanceActionErrorData", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an error occurred in an remote function of the Load Balance connector.\n" }, - "insertText":"ServiceEndpointConfiguration", - "insertTextFormat":"Snippet" + "insertText": "LoadBalanceActionErrorData", + "insertTextFormat": "Snippet" }, { - "label":"ServiceSecureSocket", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures the SSL/TLS options to be used for HTTP service.\n" + "label": "LoadBalanceClientEndpointConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The configurations related to the load balance client endpoint.\n" }, - "insertText":"ServiceSecureSocket", - "insertTextFormat":"Snippet" + "insertText": "LoadBalanceClientEndpointConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"AuthCacheConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" + "label": "Remote", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Presents a read-only view of the remote address.\n" }, - "insertText":"AuthCacheConfig", - "insertTextFormat":"Snippet" + "insertText": "Remote", + "insertTextFormat": "Snippet" }, { - "label":"AuthProvider", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configuration for authentication providers.\n" + "label": "Local", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Presents a read-only view of the local address.\n" }, - "insertText":"AuthProvider", - "insertTextFormat":"Snippet" + "insertText": "Local", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketClientEndpointConfig", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configuration for the WebSocket client endpoint.\n" + "label": "RequestLimits", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures limits for requests. If these limits are violated, the request is rejected.\n" }, - "insertText":"WebSocketClientEndpointConfig", - "insertTextFormat":"Snippet" + "insertText": "RequestLimits", + "insertTextFormat": "Snippet" }, { - "label":"AuthHandlerRegistry", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of the Http Auth Handler Registry.\n" + "label": "ServiceEndpointConfiguration", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for HTTP service endpoints.\n" }, - "insertText":"AuthHandlerRegistry", - "insertTextFormat":"Snippet" + "insertText": "ServiceEndpointConfiguration", + "insertTextFormat": "Snippet" }, { - "label":"AuthnFilter", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of the Authentication filter.\n" + "label": "ListenerAuth", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Authentication configurations for the listener.\n" }, - "insertText":"AuthnFilter", - "insertTextFormat":"Snippet" + "insertText": "ListenerAuth", + "insertTextFormat": "Snippet" }, { - "label":"HttpAuthnHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of Authentication handler for HTTP traffic.\n" + "label": "ServiceSecureSocket", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures the SSL/TLS options to be used for HTTP service.\n" }, - "insertText":"HttpAuthnHandler", - "insertTextFormat":"Snippet" + "insertText": "ServiceSecureSocket", + "insertTextFormat": "Snippet" }, { - "label":"AuthnHandlerChain", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of Authentication handler chain\n" + "label": "AuthCacheConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" }, - "insertText":"AuthnHandlerChain", - "insertTextFormat":"Snippet" + "insertText": "AuthCacheConfig", + "insertTextFormat": "Snippet" }, { - "label":"AuthzFilter", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of the Authorization filter\n" + "label": "WebSocketClientEndpointConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configuration for the WebSocket client endpoint.\n" }, - "insertText":"AuthzFilter", - "insertTextFormat":"Snippet" + "insertText": "WebSocketClientEndpointConfig", + "insertTextFormat": "Snippet" }, { - "label":"HttpAuthzHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of Authorization Handler for HTTP\n" + "label": "AuthnFilter", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of the Authentication filter.\n" }, - "insertText":"HttpAuthzHandler", - "insertTextFormat":"Snippet" + "insertText": "AuthnFilter", + "insertTextFormat": "Snippet" }, { - "label":"HttpBasicAuthnHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Defines Basic Auth handler for HTTP traffic.\n" + "label": "AuthnHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of Authentication handler for HTTP traffic." }, - "insertText":"HttpBasicAuthnHandler", - "insertTextFormat":"Snippet" + "insertText": "AuthnHandler", + "insertTextFormat": "Snippet" }, { - "label":"HttpJwtAuthnHandler", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of JWT Auth handler for HTTP traffic\n" + "label": "AuthzFilter", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of the Authorization filter\n" }, - "insertText":"HttpJwtAuthnHandler", - "insertTextFormat":"Snippet" + "insertText": "AuthzFilter", + "insertTextFormat": "Snippet" }, { - "label":"RequestCacheControl", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures cache control directives for a `Request`.\n" + "label": "AuthzHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of Authorization Handler for HTTP\n" }, - "insertText":"RequestCacheControl", - "insertTextFormat":"Snippet" + "insertText": "AuthzHandler", + "insertTextFormat": "Snippet" }, { - "label":"ResponseCacheControl", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Configures cache control directives for a `Response`.\n" + "label": "BasicAuthnHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Defines Basic Auth handler for HTTP traffic.\n" }, - "insertText":"ResponseCacheControl", - "insertTextFormat":"Snippet" + "insertText": "BasicAuthnHandler", + "insertTextFormat": "Snippet" }, { - "label":"HttpCache", - "kind":"Class", - "detail":"BType", - "insertText":"HttpCache", - "insertTextFormat":"Snippet" + "label": "JwtAuthnHandler", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of JWT Auth handler for HTTP traffic\n" + }, + "insertText": "JwtAuthnHandler", + "insertTextFormat": "Snippet" + }, + { + "label": "RequestCacheControl", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures cache control directives for a `Request`.\n" + }, + "insertText": "RequestCacheControl", + "insertTextFormat": "Snippet" + }, + { + "label": "ResponseCacheControl", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Configures cache control directives for a `Response`.\n" + }, + "insertText": "ResponseCacheControl", + "insertTextFormat": "Snippet" + }, + { + "label": "HttpCache", + "kind": "Class", + "detail": "BType", + "insertText": "HttpCache", + "insertTextFormat": "Snippet" }, { - "label":"HttpFuture", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a \u0027future\u0027 that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." + "label": "HttpFuture", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a 'future' that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." }, - "insertText":"HttpFuture", - "insertTextFormat":"Snippet" + "insertText": "HttpFuture", + "insertTextFormat": "Snippet" }, { - "label":"PushPromise", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an HTTP/2 `PUSH_PROMISE` frame.\n" + "label": "PushPromise", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an HTTP/2 `PUSH_PROMISE` frame.\n" }, - "insertText":"PushPromise", - "insertTextFormat":"Snippet" + "insertText": "PushPromise", + "insertTextFormat": "Snippet" }, { - "label":"Filter", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of a HTTP Request Filter. This filter will be applied before the request is dispatched to the relevant resource. Any Filter implementation should be structurally similar to the Filter object." + "label": "Filter", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of a HTTP Request Filter. This filter will be applied before the request is dispatched to the relevant resource. Any Filter implementation should be structurally similar to the Filter object." }, - "insertText":"Filter", - "insertTextFormat":"Snippet" + "insertText": "Filter", + "insertTextFormat": "Snippet" }, { - "label":"FilterContext", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Representation of request filter Context.\n" + "label": "FilterContext", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Representation of request filter Context.\n" }, - "insertText":"FilterContext", - "insertTextFormat":"Snippet" + "insertText": "FilterContext", + "insertTextFormat": "Snippet" }, { - "label":"Request", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an HTTP request.\n" + "label": "Request", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an HTTP request.\n" }, - "insertText":"Request", - "insertTextFormat":"Snippet" + "insertText": "Request", + "insertTextFormat": "Snippet" }, { - "label":"Response", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents an HTTP response.\n" + "label": "Response", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents an HTTP response.\n" }, - "insertText":"Response", - "insertTextFormat":"Snippet" + "insertText": "Response", + "insertTextFormat": "Snippet" }, { - "label":"MockListener", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Mock server endpoint which does not open a listening port." + "label": "MockListener", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Mock server endpoint which does not open a listening port." }, - "insertText":"MockListener", - "insertTextFormat":"Snippet" + "insertText": "MockListener", + "insertTextFormat": "Snippet" }, { - "label":"CircuitBreakerClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"A Circuit Breaker implementation which can be used to gracefully handle network failures.\n" + "label": "CircuitBreakerClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "A Circuit Breaker implementation which can be used to gracefully handle network failures.\n" }, - "insertText":"CircuitBreakerClient", - "insertTextFormat":"Snippet" + "insertText": "CircuitBreakerClient", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalancerRule", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"\nLoadBalancerRule provides a required interfaces to implement different algorithms.\n" + "label": "LoadBalancerRule", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "\nLoadBalancerRule provides a required interfaces to implement different algorithms.\n" }, - "insertText":"LoadBalancerRule", - "insertTextFormat":"Snippet" + "insertText": "LoadBalancerRule", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalancerRounRobinRule", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Implementation of round robin load balancing strategy.\n" + "label": "LoadBalancerRounRobinRule", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Implementation of round robin load balancing strategy.\n" }, - "insertText":"LoadBalancerRounRobinRule", - "insertTextFormat":"Snippet" + "insertText": "LoadBalancerRounRobinRule", + "insertTextFormat": "Snippet" }, { - "label":"Listener", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"This is used for creating HTTP server endpoints. An HTTP server endpoint is capable of responding to\nremote callers. The `Listener` is responsible for initializing the endpoint using the provided configurations." + "label": "Listener", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "This is used for creating HTTP server endpoints. An HTTP server endpoint is capable of responding to\nremote callers. The `Listener` is responsible for initializing the endpoint using the provided configurations." }, - "insertText":"Listener", - "insertTextFormat":"Snippet" + "insertText": "Listener", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketListener", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a WebSocket service endpoint." + "label": "WebSocketListener", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a WebSocket service endpoint." }, - "insertText":"WebSocketListener", - "insertTextFormat":"Snippet" + "insertText": "WebSocketListener", + "insertTextFormat": "Snippet" }, { - "label":"HttpCachingClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"An HTTP caching client implementation which takes an `HttpActions` instance and wraps it with an HTTP caching layer.\n" + "label": "HttpCachingClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "An HTTP caching client implementation which takes an `HttpActions` instance and wraps it with an HTTP caching layer.\n" }, - "insertText":"HttpCachingClient", - "insertTextFormat":"Snippet" + "insertText": "HttpCachingClient", + "insertTextFormat": "Snippet" }, { - "label":"Client", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs." + "label": "Client", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs." }, - "insertText":"Client", - "insertTextFormat":"Snippet" + "insertText": "Client", + "insertTextFormat": "Snippet" }, { - "label":"HttpCaller", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides the HTTP actions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP actions implementation.\n" + "label": "HttpCaller", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides the HTTP actions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP actions implementation.\n" }, - "insertText":"HttpCaller", - "insertTextFormat":"Snippet" + "insertText": "HttpCaller", + "insertTextFormat": "Snippet" }, { - "label":"Caller", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"The caller actions for responding to client requests.\n" + "label": "Caller", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The caller actions for responding to client requests.\n" }, - "insertText":"Caller", - "insertTextFormat":"Snippet" + "insertText": "Caller", + "insertTextFormat": "Snippet" }, { - "label":"HttpSecureClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides secure HTTP remote functions for interacting with HTTP endpoints. This will make use of the authentication\nschemes configured in the HTTP client endpoint to secure the HTTP requests.\n" + "label": "HttpSecureClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides secure HTTP remote functions for interacting with HTTP endpoints. This will make use of the authentication\nschemes configured in the HTTP client endpoint to secure the HTTP requests.\n" }, - "insertText":"HttpSecureClient", - "insertTextFormat":"Snippet" + "insertText": "HttpSecureClient", + "insertTextFormat": "Snippet" }, { - "label":"HttpClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides the HTTP remote functions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP remote functions implementation.\n" + "label": "HttpClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides the HTTP remote functions for interacting with an HTTP server. Apart from the standard HTTP methods, `forward()`\nand `execute()` functions are provided. More complex and specific endpoint types can be created by wrapping this\ngeneric HTTP remote functions implementation.\n" }, - "insertText":"HttpClient", - "insertTextFormat":"Snippet" + "insertText": "HttpClient", + "insertTextFormat": "Snippet" }, { - "label":"RedirectClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides redirect functionality for HTTP client remote functions.\n" + "label": "RedirectClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides redirect functionality for HTTP client remote functions.\n" }, - "insertText":"RedirectClient", - "insertTextFormat":"Snippet" + "insertText": "RedirectClient", + "insertTextFormat": "Snippet" }, { - "label":"FailoverClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"An HTTP client endpoint which provides failover support over multiple HTTP clients.\n" + "label": "FailoverClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "An HTTP client endpoint which provides failover support over multiple HTTP clients.\n" }, - "insertText":"FailoverClient", - "insertTextFormat":"Snippet" + "insertText": "FailoverClient", + "insertTextFormat": "Snippet" }, { - "label":"RetryClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Provides the HTTP remote functions for interacting with an HTTP endpoint. This is created by wrapping the HTTP client\nto provide retrying over HTTP requests.\n" + "label": "RetryClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Provides the HTTP remote functions for interacting with an HTTP endpoint. This is created by wrapping the HTTP client\nto provide retrying over HTTP requests.\n" }, - "insertText":"RetryClient", - "insertTextFormat":"Snippet" + "insertText": "RetryClient", + "insertTextFormat": "Snippet" }, { - "label":"LoadBalanceClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"LoadBalanceClient endpoint provides load balancing functionality over multiple HTTP clients.\n" + "label": "LoadBalanceClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "LoadBalanceClient endpoint provides load balancing functionality over multiple HTTP clients.\n" }, - "insertText":"LoadBalanceClient", - "insertTextFormat":"Snippet" + "insertText": "LoadBalanceClient", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketCaller", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a WebSocket caller.\n" + "label": "WebSocketCaller", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a WebSocket caller.\n" }, - "insertText":"WebSocketCaller", - "insertTextFormat":"Snippet" + "insertText": "WebSocketCaller", + "insertTextFormat": "Snippet" }, { - "label":"WebSocketClient", - "kind":"Class", - "detail":"BType", - "documentation":{ - "left":"Represents a WebSocket client endpoint.\n" + "label": "WebSocketClient", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "Represents a WebSocket client endpoint.\n" }, - "insertText":"WebSocketClient", - "insertTextFormat":"Snippet" + "insertText": "WebSocketClient", + "insertTextFormat": "Snippet" }, { - "label":"InboundAuthScheme", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Inbound authentication schemes." + "label": "InboundAuthScheme", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Inbound authentication schemes." }, - "insertText":"InboundAuthScheme", - "insertTextFormat":"Snippet" + "insertText": "InboundAuthScheme", + "insertTextFormat": "Snippet" }, { - "label":"OutboundAuthScheme", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Outbound authentication schemes." + "label": "OutboundAuthScheme", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Outbound authentication schemes." }, - "insertText":"OutboundAuthScheme", - "insertTextFormat":"Snippet" + "insertText": "OutboundAuthScheme", + "insertTextFormat": "Snippet" }, { - "label":"AuthStoreProvider", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Authentication storage providers for BasicAuth scheme." + "label": "CachingPolicy", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Used for configuring the caching behaviour. Setting the `policy` field in the `CacheConfig` record allows\nthe user to control the caching behaviour." }, - "insertText":"AuthStoreProvider", - "insertTextFormat":"Snippet" + "insertText": "CachingPolicy", + "insertTextFormat": "Snippet" }, { - "label":"CachingPolicy", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Used for configuring the caching behaviour. Setting the `policy` field in the `CacheConfig` record allows\nthe user to control the caching behaviour." + "label": "Chunking", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the possible values for the chunking configuration in HTTP services and clients.\n\n`AUTO`: If the payload is less than 8KB, content-length header is set in the outbound request/response,\n otherwise chunking header is set in the outbound request/response\n`ALWAYS`: Always set chunking header in the response\n`NEVER`: Never set the chunking header even if the payload is larger than 8KB in the outbound request/response" }, - "insertText":"CachingPolicy", - "insertTextFormat":"Snippet" + "insertText": "Chunking", + "insertTextFormat": "Snippet" }, { - "label":"Chunking", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the possible values for the chunking configuration in HTTP services and clients.\n\n`AUTO`: If the payload is less than 8KB, content-length header is set in the outbound request/response,\n otherwise chunking header is set in the outbound request/response\n`ALWAYS`: Always set chunking header in the response\n`NEVER`: Never set the chunking header even if the payload is larger than 8KB in the outbound request/response" + "label": "Compression", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Options to compress using gzip or deflate.\n\n`AUTO`: When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the\n outbound request/response accept-encoding/content-encoding option\n`ALWAYS`: Always set accept-encoding/content-encoding in outbound request/response\n`NEVER`: Never set accept-encoding/content-encoding header in outbound request/response" }, - "insertText":"Chunking", - "insertTextFormat":"Snippet" + "insertText": "Compression", + "insertTextFormat": "Snippet" }, { - "label":"Compression", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Options to compress using gzip or deflate.\n\n`AUTO`: When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the\n outbound request/response accept-encoding/content-encoding option\n`ALWAYS`: Always set accept-encoding/content-encoding in outbound request/response\n`NEVER`: Never set accept-encoding/content-encoding header in outbound request/response" + "label": "HttpOperation", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the HTTP operations related to circuit breaker, failover and load balancer.\n\n`FORWARD`: Forward the specified payload\n`GET`: Request a resource\n`POST`: Create a new resource\n`DELETE`: Deletes the specified resource\n`OPTIONS`: Request communication options available\n`PUT`: Replace the target resource\n`PATCH`: Apply partial modification to the resource\n`HEAD`: Identical to `GET` but no resource body should be returned\n`NONE`: No operation should be performed" }, - "insertText":"Compression", - "insertTextFormat":"Snippet" + "insertText": "HttpOperation", + "insertTextFormat": "Snippet" }, { - "label":"HttpOperation", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the HTTP operations related to circuit breaker, failover and load balancer.\n\n`FORWARD`: Forward the specified payload\n`GET`: Request a resource\n`POST`: Create a new resource\n`DELETE`: Deletes the specified resource\n`OPTIONS`: Request communication options available\n`PUT`: Replace the target resource\n`PATCH`: Apply partial modification to the resource\n`HEAD`: Identical to `GET` but no resource body should be returned\n`NONE`: No operation should be performed" + "label": "RedirectCode", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the HTTP redirect codes as a type." }, - "insertText":"HttpOperation", - "insertTextFormat":"Snippet" + "insertText": "RedirectCode", + "insertTextFormat": "Snippet" }, { - "label":"RedirectCode", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the HTTP redirect codes as a type." + "label": "MutualSslStatus", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the possible values for the mutual ssl status.\n\n`passed`: Mutual SSL handshake is succesful.\n`failed`: Mutual SSL handshake has failed." }, - "insertText":"RedirectCode", - "insertTextFormat":"Snippet" + "insertText": "MutualSslStatus", + "insertTextFormat": "Snippet" }, { - "label":"MutualSslStatus", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the possible values for the mutual ssl status.\n\n`passed`: Mutual SSL handshake is succesful.\n`failed`: Mutual SSL handshake has failed." + "label": "CredentialBearer", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Specifies how to send the authentication credentials when exchanging tokens." }, - "insertText":"MutualSslStatus", - "insertTextFormat":"Snippet" + "insertText": "CredentialBearer", + "insertTextFormat": "Snippet" }, { - "label":"CredentialBearer", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Specifies how the authentication credentials should be sent when using the refresh token to refresh the access token" + "label": "OAuth2GrantType", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Specifies the type of the OAuth2 grant type" }, - "insertText":"CredentialBearer", - "insertTextFormat":"Snippet" + "insertText": "OAuth2GrantType", + "insertTextFormat": "Snippet" }, { - "label":"CircuitState", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"A finite type for modeling the states of the Circuit Breaker. The Circuit Breaker starts in the `CLOSED` state.\nIf any failure thresholds are exceeded during execution, the circuit trips and goes to the `OPEN` state. After\nthe specified timeout period expires, the circuit goes to the `HALF_OPEN` state. If the trial request sent while\nin the `HALF_OPEN` state succeeds, the circuit goes back to the `CLOSED` state." + "label": "CircuitState", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "A finite type for modeling the states of the Circuit Breaker. The Circuit Breaker starts in the `CLOSED` state.\nIf any failure thresholds are exceeded during execution, the circuit trips and goes to the `OPEN` state. After\nthe specified timeout period expires, the circuit goes to the `HALF_OPEN` state. If the trial request sent while\nin the `HALF_OPEN` state succeeds, the circuit goes back to the `CLOSED` state." }, - "insertText":"CircuitState", - "insertTextFormat":"Snippet" + "insertText": "CircuitState", + "insertTextFormat": "Snippet" }, { - "label":"KeepAlive", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"Defines the possible values for the keep-alive configuration in service and client endpoints." + "label": "KeepAlive", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Defines the possible values for the keep-alive configuration in service and client endpoints." }, - "insertText":"KeepAlive", - "insertTextFormat":"Snippet" + "insertText": "KeepAlive", + "insertTextFormat": "Snippet" }, { - "label":"RequestMessage", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"The types of messages that are accepted by HTTP `client` when sending out the outbound request." + "label": "RequestMessage", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "The types of messages that are accepted by HTTP `client` when sending out the outbound request." }, - "insertText":"RequestMessage", - "insertTextFormat":"Snippet" + "insertText": "RequestMessage", + "insertTextFormat": "Snippet" }, { - "label":"ResponseMessage", - "kind":"Enum", - "detail":"BType", - "documentation":{ - "left":"The types of messages that are accepted by HTTP `listener` when sending out the outbound response." + "label": "ResponseMessage", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "The types of messages that are accepted by HTTP `listener` when sending out the outbound response." }, - "insertText":"ResponseMessage", - "insertTextFormat":"Snippet" + "insertText": "ResponseMessage", + "insertTextFormat": "Snippet" } ] -} +} \ No newline at end of file diff --git a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json index 40830f8b4876..2faea3334780 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json @@ -12,7 +12,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" } }, "sortText": "121", @@ -26,7 +26,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:Client|error" } }, "sortText": "121", @@ -40,7 +40,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \n(string,map)|error" } }, "sortText": "121", @@ -54,7 +54,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:Response|error" } }, "sortText": "121", @@ -68,7 +68,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:Client|error" } }, "sortText": "121", @@ -82,7 +82,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nstring|error" } }, "sortText": "121", @@ -96,7 +96,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nstring|error" } }, "sortText": "121", @@ -170,25 +170,14 @@ "insertTextFormat": "Snippet" }, { - "label": "ListenerAuthConfig", + "label": "ServiceResourceAuth", "kind": "Class", "detail": "BType", "documentation": { "left": "Configures the authentication scheme for a service or a resource.\n" }, "sortText": "171", - "insertText": "ListenerAuthConfig", - "insertTextFormat": "Snippet" - }, - { - "label": "Authentication", - "kind": "Class", - "detail": "BType", - "documentation": { - "left": "Can be used for enabling/disabling authentication in an HTTP service.\n" - }, - "sortText": "171", - "insertText": "Authentication", + "insertText": "ServiceResourceAuth", "insertTextFormat": "Snippet" }, { @@ -229,7 +218,7 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "Provides configurations for controlling the retry behaviour in failure scenarios.\n" + "left": "Provides configurations for controlling the retrying behavior in failure scenarios.\n" }, "sortText": "171", "insertText": "RetryConfig", @@ -251,7 +240,7 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "Provides configurations for controlling the endpoint\u0027s behaviour in response to HTTP redirect related responses.\n" + "left": "Provides configurations for controlling the endpoint's behaviour in response to HTTP redirect related responses.\n" }, "sortText": "171", "insertText": "FollowRedirects", @@ -269,14 +258,14 @@ "insertTextFormat": "Snippet" }, { - "label": "AuthConfig", + "label": "OutboundAuthConfig", "kind": "Class", "detail": "BType", "documentation": { - "left": "AuthConfig record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" + "left": "The `OutboundAuthConfig` record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" }, "sortText": "171", - "insertText": "AuthConfig", + "insertText": "OutboundAuthConfig", "insertTextFormat": "Snippet" }, { @@ -284,7 +273,7 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "BasicAuthConfig record can be used to configure Basic Authentication used by the HTTP endpoint.\n" + "left": "The `BasicAuthConfig` record can be used to configure Basic Authentication used by the HTTP endpoint.\n" }, "sortText": "171", "insertText": "BasicAuthConfig", @@ -295,18 +284,73 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "OAuth2AuthConfig record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" + "left": "The `OAuth2AuthConfig` record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" }, "sortText": "171", "insertText": "OAuth2AuthConfig", "insertTextFormat": "Snippet" }, + { + "label": "ClientCredentialsGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `ClientCredentialsGrantConfig` record can be used to configue OAuth2 client credentials grant type.\n" + }, + "sortText": "171", + "insertText": "ClientCredentialsGrantConfig", + "insertTextFormat": "Snippet" + }, + { + "label": "PasswordGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `PasswordGrantConfig` record can be used to configue OAuth2 password grant type\n" + }, + "sortText": "171", + "insertText": "PasswordGrantConfig", + "insertTextFormat": "Snippet" + }, + { + "label": "DirectTokenConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenConfig` record configures the access token directly.\n" + }, + "sortText": "171", + "insertText": "DirectTokenConfig", + "insertTextFormat": "Snippet" + }, + { + "label": "RefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `RefreshConfig` record can be used to pass the configurations for refreshing the access token of password grant type.\n" + }, + "sortText": "171", + "insertText": "RefreshConfig", + "insertTextFormat": "Snippet" + }, + { + "label": "DirectTokenRefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenRefreshConfig` record passes the configurations for refreshing the access token for \nthe grant type of the direct token grant type.\n" + }, + "sortText": "171", + "insertText": "DirectTokenRefreshConfig", + "insertTextFormat": "Snippet" + }, { "label": "JwtAuthConfig", "kind": "Class", "detail": "BType", "documentation": { - "left": "JwtAuthConfig record can be used to configure JWT based authentication used by the HTTP endpoint.\n" + "left": "The `JwtAuthConfig` record can be used to configure JWT based authentication used by the HTTP endpoint.\n" }, "sortText": "171", "insertText": "JwtAuthConfig", @@ -389,6 +433,17 @@ "insertText": "MutualSslHandshake", "insertTextFormat": "Snippet" }, + { + "label": "CachedToken", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `CachedToken` stores the values received from the authorization/token server to use them\nfor the latter requests without requesting tokens again.\n" + }, + "sortText": "171", + "insertText": "CachedToken", + "insertTextFormat": "Snippet" + }, { "label": "FailoverConfig", "kind": "Class", @@ -555,36 +610,36 @@ "insertTextFormat": "Snippet" }, { - "label": "ServiceSecureSocket", + "label": "ListenerAuth", "kind": "Class", "detail": "BType", "documentation": { - "left": "Configures the SSL/TLS options to be used for HTTP service.\n" + "left": "Authentication configurations for the listener.\n" }, "sortText": "171", - "insertText": "ServiceSecureSocket", + "insertText": "ListenerAuth", "insertTextFormat": "Snippet" }, { - "label": "AuthCacheConfig", + "label": "ServiceSecureSocket", "kind": "Class", "detail": "BType", "documentation": { - "left": "Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" + "left": "Configures the SSL/TLS options to be used for HTTP service.\n" }, "sortText": "171", - "insertText": "AuthCacheConfig", + "insertText": "ServiceSecureSocket", "insertTextFormat": "Snippet" }, { - "label": "AuthProvider", + "label": "AuthCacheConfig", "kind": "Class", "detail": "BType", "documentation": { - "left": "Configuration for authentication providers.\n" + "left": "Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" }, "sortText": "171", - "insertText": "AuthProvider", + "insertText": "AuthCacheConfig", "insertTextFormat": "Snippet" }, { @@ -598,17 +653,6 @@ "insertText": "WebSocketClientEndpointConfig", "insertTextFormat": "Snippet" }, - { - "label": "AuthHandlerRegistry", - "kind": "Class", - "detail": "BType", - "documentation": { - "left": "Representation of the Http Auth Handler Registry.\n" - }, - "sortText": "171", - "insertText": "AuthHandlerRegistry", - "insertTextFormat": "Snippet" - }, { "label": "AuthnFilter", "kind": "Class", @@ -621,25 +665,14 @@ "insertTextFormat": "Snippet" }, { - "label": "HttpAuthnHandler", + "label": "AuthnHandler", "kind": "Class", "detail": "BType", "documentation": { - "left": "Representation of Authentication handler for HTTP traffic.\n" + "left": "Representation of Authentication handler for HTTP traffic." }, "sortText": "171", - "insertText": "HttpAuthnHandler", - "insertTextFormat": "Snippet" - }, - { - "label": "AuthnHandlerChain", - "kind": "Class", - "detail": "BType", - "documentation": { - "left": "Representation of Authentication handler chain\n" - }, - "sortText": "171", - "insertText": "AuthnHandlerChain", + "insertText": "AuthnHandler", "insertTextFormat": "Snippet" }, { @@ -654,36 +687,36 @@ "insertTextFormat": "Snippet" }, { - "label": "HttpAuthzHandler", + "label": "AuthzHandler", "kind": "Class", "detail": "BType", "documentation": { "left": "Representation of Authorization Handler for HTTP\n" }, "sortText": "171", - "insertText": "HttpAuthzHandler", + "insertText": "AuthzHandler", "insertTextFormat": "Snippet" }, { - "label": "HttpBasicAuthnHandler", + "label": "BasicAuthnHandler", "kind": "Class", "detail": "BType", "documentation": { "left": "Defines Basic Auth handler for HTTP traffic.\n" }, "sortText": "171", - "insertText": "HttpBasicAuthnHandler", + "insertText": "BasicAuthnHandler", "insertTextFormat": "Snippet" }, { - "label": "HttpJwtAuthnHandler", + "label": "JwtAuthnHandler", "kind": "Class", "detail": "BType", "documentation": { "left": "Representation of JWT Auth handler for HTTP traffic\n" }, "sortText": "171", - "insertText": "HttpJwtAuthnHandler", + "insertText": "JwtAuthnHandler", "insertTextFormat": "Snippet" }, { @@ -721,7 +754,7 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "Represents a \u0027future\u0027 that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." + "left": "Represents a 'future' that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." }, "sortText": "171", "insertText": "HttpFuture", @@ -1002,17 +1035,6 @@ "insertText": "OutboundAuthScheme", "insertTextFormat": "Snippet" }, - { - "label": "AuthStoreProvider", - "kind": "Enum", - "detail": "BType", - "documentation": { - "left": "Authentication storage providers for BasicAuth scheme." - }, - "sortText": "171", - "insertText": "AuthStoreProvider", - "insertTextFormat": "Snippet" - }, { "label": "CachingPolicy", "kind": "Enum", @@ -1084,12 +1106,23 @@ "kind": "Enum", "detail": "BType", "documentation": { - "left": "Specifies how the authentication credentials should be sent when using the refresh token to refresh the access token" + "left": "Specifies how to send the authentication credentials when exchanging tokens." }, "sortText": "171", "insertText": "CredentialBearer", "insertTextFormat": "Snippet" }, + { + "label": "OAuth2GrantType", + "kind": "Enum", + "detail": "BType", + "documentation": { + "left": "Specifies the type of the OAuth2 grant type" + }, + "sortText": "171", + "insertText": "OAuth2GrantType", + "insertTextFormat": "Snippet" + }, { "label": "CircuitState", "kind": "Enum", diff --git a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json index bb150d930056..b614cb04abe1 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json @@ -12,7 +12,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" } }, "insertText": "extractBasicAuthHeaderValue(${1:req})", @@ -40,7 +40,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of caching HTTP responses.\n \n \n--- \n**Parameters** \n- _url_ \n The URL of the HTTP endpoint to connect to \n \n- _config_ \n The configurations for the client endpoint associated with the caching client \n \n- _cacheConfig_ \n The configurations for the HTTP cache to be used with the caching client \n \n \n**Return** \nballerina/http:Client|error" } }, "insertText": "createHttpCachingClient(${1:url}, ${2:config}, ${3:cacheConfig})", @@ -68,7 +68,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nParses the given header value to extract its value and parameter map.\n \n \n--- \n**Parameters** \n- _headerValue_ \n The header value \n \n \n**Return** \n(string,map)|error" } }, "insertText": "parseHeader(${1:headerValue})", @@ -96,7 +96,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nThe HEAD remote function implementation of the Circuit Breaker. This wraps the `head()` function of the underlying\nHTTP remote function provider. \n \n--- \n**Parameters** \n- _path_ \n Resource path \n \n- _outRequest_ \n A Request struct \n \n- _requestAction_ \n `HttpOperation` related to the request \n \n- _httpClient_ \n HTTP client which uses to call the relavant functions \n \n \n**Return** \nballerina/http:Response|error" } }, "insertText": "invokeEndpoint(${1:path}, ${2:outRequest}, ${3:requestAction}, ${4:httpClient})", @@ -124,7 +124,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nCreates an HTTP client capable of securing HTTP requests with authentication.\n \n \n--- \n**Parameters** \n- _url_ \n Base URL \n \n- _config_ \n Client endpoint configurations \n \n \n**Return** \nballerina/http:Client|error" } }, "insertText": "createHttpSecureClient(${1:url}, ${2:config})", @@ -152,7 +152,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nEncodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be encoded \n \n- _charset_ \n Charactor set that URL to be encoded in \n \n \n**Return** \nstring|error" } }, "insertText": "encode(${1:url}, ${2:charset})", @@ -180,7 +180,7 @@ "documentation": { "right": { "kind": "markdown", - "value": "markdown**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nballerina/http:" + "value": "**Package:** _ballerina/http_ \n \nDecodes the given URL.\n \n \n--- \n**Parameters** \n- _url_ \n URL to be decoded \n \n- _charset_ \n Charactor set that URL to be decoded from \n \n \n**Return** \nstring|error" } }, "insertText": "decode(${1:url}, ${2:charset})", @@ -352,38 +352,13 @@ ] }, { - "label": "ListenerAuthConfig", + "label": "ServiceResourceAuth", "kind": "Class", "detail": "BType", "documentation": { "left": "Configures the authentication scheme for a service or a resource.\n" }, - "insertText": "ListenerAuthConfig", - "insertTextFormat": "Snippet", - "additionalTextEdits": [ - { - "range": { - "start": { - "line": 0, - "character": 0 - }, - "end": { - "line": 0, - "character": 0 - } - }, - "newText": "import ballerina/http;\n" - } - ] - }, - { - "label": "Authentication", - "kind": "Class", - "detail": "BType", - "documentation": { - "left": "Can be used for enabling/disabling authentication in an HTTP service.\n" - }, - "insertText": "Authentication", + "insertText": "ServiceResourceAuth", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -481,7 +456,7 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "Provides configurations for controlling the retry behaviour in failure scenarios.\n" + "left": "Provides configurations for controlling the retrying behavior in failure scenarios.\n" }, "insertText": "RetryConfig", "insertTextFormat": "Snippet", @@ -531,7 +506,7 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "Provides configurations for controlling the endpoint\u0027s behaviour in response to HTTP redirect related responses.\n" + "left": "Provides configurations for controlling the endpoint's behaviour in response to HTTP redirect related responses.\n" }, "insertText": "FollowRedirects", "insertTextFormat": "Snippet", @@ -577,13 +552,13 @@ ] }, { - "label": "AuthConfig", + "label": "OutboundAuthConfig", "kind": "Class", "detail": "BType", "documentation": { - "left": "AuthConfig record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" + "left": "The `OutboundAuthConfig` record can be used to configure the authentication mechanism used by the HTTP endpoint.\n" }, - "insertText": "AuthConfig", + "insertText": "OutboundAuthConfig", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -606,7 +581,7 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "BasicAuthConfig record can be used to configure Basic Authentication used by the HTTP endpoint.\n" + "left": "The `BasicAuthConfig` record can be used to configure Basic Authentication used by the HTTP endpoint.\n" }, "insertText": "BasicAuthConfig", "insertTextFormat": "Snippet", @@ -631,7 +606,7 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "OAuth2AuthConfig record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" + "left": "The `OAuth2AuthConfig` record can be used to configure OAuth2 based authentication used by the HTTP endpoint.\n" }, "insertText": "OAuth2AuthConfig", "insertTextFormat": "Snippet", @@ -651,12 +626,137 @@ } ] }, + { + "label": "ClientCredentialsGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `ClientCredentialsGrantConfig` record can be used to configue OAuth2 client credentials grant type.\n" + }, + "insertText": "ClientCredentialsGrantConfig", + "insertTextFormat": "Snippet", + "additionalTextEdits": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "import ballerina/http;\n" + } + ] + }, + { + "label": "PasswordGrantConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `PasswordGrantConfig` record can be used to configue OAuth2 password grant type\n" + }, + "insertText": "PasswordGrantConfig", + "insertTextFormat": "Snippet", + "additionalTextEdits": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "import ballerina/http;\n" + } + ] + }, + { + "label": "DirectTokenConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenConfig` record configures the access token directly.\n" + }, + "insertText": "DirectTokenConfig", + "insertTextFormat": "Snippet", + "additionalTextEdits": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "import ballerina/http;\n" + } + ] + }, + { + "label": "RefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `RefreshConfig` record can be used to pass the configurations for refreshing the access token of password grant type.\n" + }, + "insertText": "RefreshConfig", + "insertTextFormat": "Snippet", + "additionalTextEdits": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "import ballerina/http;\n" + } + ] + }, + { + "label": "DirectTokenRefreshConfig", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `DirectTokenRefreshConfig` record passes the configurations for refreshing the access token for \nthe grant type of the direct token grant type.\n" + }, + "insertText": "DirectTokenRefreshConfig", + "insertTextFormat": "Snippet", + "additionalTextEdits": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "import ballerina/http;\n" + } + ] + }, { "label": "JwtAuthConfig", "kind": "Class", "detail": "BType", "documentation": { - "left": "JwtAuthConfig record can be used to configure JWT based authentication used by the HTTP endpoint.\n" + "left": "The `JwtAuthConfig` record can be used to configure JWT based authentication used by the HTTP endpoint.\n" }, "insertText": "JwtAuthConfig", "insertTextFormat": "Snippet", @@ -851,6 +951,31 @@ } ] }, + { + "label": "CachedToken", + "kind": "Class", + "detail": "BType", + "documentation": { + "left": "The `CachedToken` stores the values received from the authorization/token server to use them\nfor the latter requests without requesting tokens again.\n" + }, + "insertText": "CachedToken", + "insertTextFormat": "Snippet", + "additionalTextEdits": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "import ballerina/http;\n" + } + ] + }, { "label": "FailoverConfig", "kind": "Class", @@ -1227,13 +1352,13 @@ ] }, { - "label": "ServiceSecureSocket", + "label": "ListenerAuth", "kind": "Class", "detail": "BType", "documentation": { - "left": "Configures the SSL/TLS options to be used for HTTP service.\n" + "left": "Authentication configurations for the listener.\n" }, - "insertText": "ServiceSecureSocket", + "insertText": "ListenerAuth", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -1252,13 +1377,13 @@ ] }, { - "label": "AuthCacheConfig", + "label": "ServiceSecureSocket", "kind": "Class", "detail": "BType", "documentation": { - "left": "Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" + "left": "Configures the SSL/TLS options to be used for HTTP service.\n" }, - "insertText": "AuthCacheConfig", + "insertText": "ServiceSecureSocket", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -1277,13 +1402,13 @@ ] }, { - "label": "AuthProvider", + "label": "AuthCacheConfig", "kind": "Class", "detail": "BType", "documentation": { - "left": "Configuration for authentication providers.\n" + "left": "Provides a set of configurations for controlling the authorization caching behaviour of the endpoint.\n" }, - "insertText": "AuthProvider", + "insertText": "AuthCacheConfig", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -1326,31 +1451,6 @@ } ] }, - { - "label": "AuthHandlerRegistry", - "kind": "Class", - "detail": "BType", - "documentation": { - "left": "Representation of the Http Auth Handler Registry.\n" - }, - "insertText": "AuthHandlerRegistry", - "insertTextFormat": "Snippet", - "additionalTextEdits": [ - { - "range": { - "start": { - "line": 0, - "character": 0 - }, - "end": { - "line": 0, - "character": 0 - } - }, - "newText": "import ballerina/http;\n" - } - ] - }, { "label": "AuthnFilter", "kind": "Class", @@ -1377,38 +1477,13 @@ ] }, { - "label": "HttpAuthnHandler", + "label": "AuthnHandler", "kind": "Class", "detail": "BType", "documentation": { - "left": "Representation of Authentication handler for HTTP traffic.\n" + "left": "Representation of Authentication handler for HTTP traffic." }, - "insertText": "HttpAuthnHandler", - "insertTextFormat": "Snippet", - "additionalTextEdits": [ - { - "range": { - "start": { - "line": 0, - "character": 0 - }, - "end": { - "line": 0, - "character": 0 - } - }, - "newText": "import ballerina/http;\n" - } - ] - }, - { - "label": "AuthnHandlerChain", - "kind": "Class", - "detail": "BType", - "documentation": { - "left": "Representation of Authentication handler chain\n" - }, - "insertText": "AuthnHandlerChain", + "insertText": "AuthnHandler", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -1452,13 +1527,13 @@ ] }, { - "label": "HttpAuthzHandler", + "label": "AuthzHandler", "kind": "Class", "detail": "BType", "documentation": { "left": "Representation of Authorization Handler for HTTP\n" }, - "insertText": "HttpAuthzHandler", + "insertText": "AuthzHandler", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -1477,13 +1552,13 @@ ] }, { - "label": "HttpBasicAuthnHandler", + "label": "BasicAuthnHandler", "kind": "Class", "detail": "BType", "documentation": { "left": "Defines Basic Auth handler for HTTP traffic.\n" }, - "insertText": "HttpBasicAuthnHandler", + "insertText": "BasicAuthnHandler", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -1502,13 +1577,13 @@ ] }, { - "label": "HttpJwtAuthnHandler", + "label": "JwtAuthnHandler", "kind": "Class", "detail": "BType", "documentation": { "left": "Representation of JWT Auth handler for HTTP traffic\n" }, - "insertText": "HttpJwtAuthnHandler", + "insertText": "JwtAuthnHandler", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -1603,7 +1678,7 @@ "kind": "Class", "detail": "BType", "documentation": { - "left": "Represents a \u0027future\u0027 that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." + "left": "Represents a 'future' that returns as a result of an asynchronous HTTP request submission.\nThis can be used as a reference to fetch the results of the submission." }, "insertText": "HttpFuture", "insertTextFormat": "Snippet", @@ -1949,13 +2024,13 @@ ] }, { - "label": "AuthStoreProvider", + "label": "CachingPolicy", "kind": "Enum", "detail": "BType", "documentation": { - "left": "Authentication storage providers for BasicAuth scheme." + "left": "Used for configuring the caching behaviour. Setting the `policy` field in the `CacheConfig` record allows\nthe user to control the caching behaviour." }, - "insertText": "AuthStoreProvider", + "insertText": "CachingPolicy", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -1974,13 +2049,13 @@ ] }, { - "label": "CachingPolicy", + "label": "Chunking", "kind": "Enum", "detail": "BType", "documentation": { - "left": "Used for configuring the caching behaviour. Setting the `policy` field in the `CacheConfig` record allows\nthe user to control the caching behaviour." + "left": "Defines the possible values for the chunking configuration in HTTP services and clients.\n\n`AUTO`: If the payload is less than 8KB, content-length header is set in the outbound request/response,\n otherwise chunking header is set in the outbound request/response\n`ALWAYS`: Always set chunking header in the response\n`NEVER`: Never set the chunking header even if the payload is larger than 8KB in the outbound request/response" }, - "insertText": "CachingPolicy", + "insertText": "Chunking", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -1999,13 +2074,13 @@ ] }, { - "label": "Chunking", + "label": "Compression", "kind": "Enum", "detail": "BType", "documentation": { - "left": "Defines the possible values for the chunking configuration in HTTP services and clients.\n\n`AUTO`: If the payload is less than 8KB, content-length header is set in the outbound request/response,\n otherwise chunking header is set in the outbound request/response\n`ALWAYS`: Always set chunking header in the response\n`NEVER`: Never set the chunking header even if the payload is larger than 8KB in the outbound request/response" + "left": "Options to compress using gzip or deflate.\n\n`AUTO`: When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the\n outbound request/response accept-encoding/content-encoding option\n`ALWAYS`: Always set accept-encoding/content-encoding in outbound request/response\n`NEVER`: Never set accept-encoding/content-encoding header in outbound request/response" }, - "insertText": "Chunking", + "insertText": "Compression", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -2024,13 +2099,13 @@ ] }, { - "label": "Compression", + "label": "HttpOperation", "kind": "Enum", "detail": "BType", "documentation": { - "left": "Options to compress using gzip or deflate.\n\n`AUTO`: When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the\n outbound request/response accept-encoding/content-encoding option\n`ALWAYS`: Always set accept-encoding/content-encoding in outbound request/response\n`NEVER`: Never set accept-encoding/content-encoding header in outbound request/response" + "left": "Defines the HTTP operations related to circuit breaker, failover and load balancer.\n\n`FORWARD`: Forward the specified payload\n`GET`: Request a resource\n`POST`: Create a new resource\n`DELETE`: Deletes the specified resource\n`OPTIONS`: Request communication options available\n`PUT`: Replace the target resource\n`PATCH`: Apply partial modification to the resource\n`HEAD`: Identical to `GET` but no resource body should be returned\n`NONE`: No operation should be performed" }, - "insertText": "Compression", + "insertText": "HttpOperation", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -2049,13 +2124,13 @@ ] }, { - "label": "HttpOperation", + "label": "RedirectCode", "kind": "Enum", "detail": "BType", "documentation": { - "left": "Defines the HTTP operations related to circuit breaker, failover and load balancer.\n\n`FORWARD`: Forward the specified payload\n`GET`: Request a resource\n`POST`: Create a new resource\n`DELETE`: Deletes the specified resource\n`OPTIONS`: Request communication options available\n`PUT`: Replace the target resource\n`PATCH`: Apply partial modification to the resource\n`HEAD`: Identical to `GET` but no resource body should be returned\n`NONE`: No operation should be performed" + "left": "Defines the HTTP redirect codes as a type." }, - "insertText": "HttpOperation", + "insertText": "RedirectCode", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -2074,13 +2149,13 @@ ] }, { - "label": "RedirectCode", + "label": "MutualSslStatus", "kind": "Enum", "detail": "BType", "documentation": { - "left": "Defines the HTTP redirect codes as a type." + "left": "Defines the possible values for the mutual ssl status.\n\n`passed`: Mutual SSL handshake is succesful.\n`failed`: Mutual SSL handshake has failed." }, - "insertText": "RedirectCode", + "insertText": "MutualSslStatus", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -2099,13 +2174,13 @@ ] }, { - "label": "MutualSslStatus", + "label": "CredentialBearer", "kind": "Enum", "detail": "BType", "documentation": { - "left": "Defines the possible values for the mutual ssl status.\n\n`passed`: Mutual SSL handshake is succesful.\n`failed`: Mutual SSL handshake has failed." + "left": "Specifies how to send the authentication credentials when exchanging tokens." }, - "insertText": "MutualSslStatus", + "insertText": "CredentialBearer", "insertTextFormat": "Snippet", "additionalTextEdits": [ { @@ -2124,13 +2199,13 @@ ] }, { - "label": "CredentialBearer", + "label": "OAuth2GrantType", "kind": "Enum", "detail": "BType", "documentation": { - "left": "Specifies how the authentication credentials should be sent when using the refresh token to refresh the access token" + "left": "Specifies the type of the OAuth2 grant type" }, - "insertText": "CredentialBearer", + "insertText": "OAuth2GrantType", "insertTextFormat": "Snippet", "additionalTextEdits": [ { From 6c0b9b1f2a3adff308fb439e517bd005d1c47e4c Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Sat, 13 Apr 2019 15:50:03 +0530 Subject: [PATCH 11/52] Remove empty record from config store --- .../auth/config_auth_store_provider.bal | 13 --------- .../test-src/config_auth_provider_test.bal | 28 +++++++++---------- .../auth/basic-authn-handler-test.bal | 8 +++--- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal index 4d883c68ad1d..f0a5757fbd32 100644 --- a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal @@ -21,10 +21,6 @@ import ballerina/runtime; const string CONFIG_USER_SECTION = "b7a.users"; -# Represents configurations that required for Config auth store. -public type ConfigAuthStoreProviderConfig record {| -|}; - # Represents Ballerina configuration file based auth store provider. # # + configAuthStoreProviderConfig - Config auth store configurations @@ -32,15 +28,6 @@ public type ConfigAuthStoreProvider object { *AuthProvider; - public ConfigAuthStoreProviderConfig configAuthStoreProviderConfig; - - # Create an Config auth store with the given configurations. - # - # + configAuthProviderConfig - Config auth store configurations - public function __init(ConfigAuthStoreProviderConfig configAuthStoreProviderConfig) { - self.configAuthStoreProviderConfig = configAuthStoreProviderConfig; - } - # Attempts to authenticate with credential. # # + credential - Credential diff --git a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal index 77da6dad7365..d9fcc1fc4867 100644 --- a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal +++ b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal @@ -18,96 +18,96 @@ import ballerina/auth; import ballerina/encoding; function testCreateConfigAuthProvider() returns auth:ConfigAuthStoreProvider { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; return configAuthStoreProvider; } function testAuthenticationOfNonExistingUser() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "amila:abc"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationOfNonExistingPassword() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "isuru:xxy"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthentication() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "isuru:xxx"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationWithEmptyUsername() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = ":xxx"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationWithEmptyPassword() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "isuru:"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationWithEmptyPasswordAndInvalidUsername() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "invalid:"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationWithEmptyUsernameAndEmptyPassword() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = ":"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationSha256() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha256:xxx"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationSha384() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha384:xxx"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationSha512() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha512:xxx"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationPlain() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "plain:plainpassword"; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationSha512Negative() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha512:xxx "; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); } function testAuthenticationPlainNegative() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "plain:plainpassword "; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); diff --git a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal index 535afac4120c..3ea1d70a50d8 100644 --- a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal @@ -2,7 +2,7 @@ import ballerina/auth; import ballerina/http; function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; auth:AuthProvider authProvider = configAuthStoreProvider; http:BasicAuthnHandler handler = new(authProvider); http:Request inRequest = createRequest(); @@ -12,7 +12,7 @@ function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { } function testCanHandleHttpBasicAuth() returns boolean { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; auth:AuthProvider authProvider = configAuthStoreProvider; http:BasicAuthnHandler handler = new(authProvider); http:Request inRequest = createRequest(); @@ -22,7 +22,7 @@ function testCanHandleHttpBasicAuth() returns boolean { } function testHandleHttpBasicAuthFailure() returns boolean { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; auth:AuthProvider authProvider = configAuthStoreProvider; http:BasicAuthnHandler handler = new(authProvider); http:Request inRequest = createRequest(); @@ -32,7 +32,7 @@ function testHandleHttpBasicAuthFailure() returns boolean { } function testHandleHttpBasicAuth() returns boolean { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new({}); + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; auth:AuthProvider authProvider = configAuthStoreProvider; http:BasicAuthnHandler handler = new(authProvider); http:Request inRequest = createRequest(); From d6b6401136c7bfa374ca6c3f149c61496a8e1abe Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Sun, 14 Apr 2019 06:48:15 +0530 Subject: [PATCH 12/52] Fix a bug in accessing authConfig --- stdlib/http/src/main/ballerina/http/auth/utils.bal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/http/src/main/ballerina/http/auth/utils.bal b/stdlib/http/src/main/ballerina/http/auth/utils.bal index 766630b29996..31d5393e1f95 100644 --- a/stdlib/http/src/main/ballerina/http/auth/utils.bal +++ b/stdlib/http/src/main/ballerina/http/auth/utils.bal @@ -109,10 +109,10 @@ function getAuthAnnotation(string annotationModule, string annotationName, refle if (authAnn is reflect:annotationData) { if (annotationName == RESOURCE_ANN_NAME) { HttpResourceConfig resourceConfig = authAnn.value; - return resourceConfig.auth; + return resourceConfig["auth"]; } else if (annotationName == SERVICE_ANN_NAME) { HttpServiceConfig serviceConfig = authAnn.value; - return serviceConfig.auth; + return serviceConfig["auth"]; } } } From 7907e9abdc0fa4100484e29a5a7ba3c91d4509c0 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Sun, 14 Apr 2019 08:41:38 +0530 Subject: [PATCH 13/52] Fix bbe related to auth --- .../secured_client_with_basic_auth.bal | 15 +++++----- .../secured_client_with_jwt_auth.bal | 28 +++++++++--------- .../secured_service_with_basic_auth.bal | 17 ++++++----- .../secured_service_with_jwt.bal | 29 +++++++++---------- 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal b/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal index 8b0e88eaaa24..38124fc2e378 100644 --- a/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal +++ b/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal @@ -1,3 +1,4 @@ +import ballerina/auth; import ballerina/config; import ballerina/http; import ballerina/log; @@ -31,13 +32,13 @@ public function main() { } // Create a basic authentication provider with the relevant configurations. -http:AuthProvider basicAuthProvider = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider = new; +http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); listener http:Listener ep = new(9090, config = { - authProviders: [basicAuthProvider], + auth: { + authnHandlers: [basicAuthProvider] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -48,8 +49,8 @@ listener http:Listener ep = new(9090, config = { @http:ServiceConfig { basePath: "/hello", - authConfig: { - authentication: { enabled: true } + auth: { + enabled: true } } service echo on ep { diff --git a/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal b/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal index f7914a485a76..c594ca3d6e33 100644 --- a/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal +++ b/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal @@ -1,3 +1,4 @@ +import ballerina/auth; import ballerina/http; import ballerina/log; import ballerina/runtime; @@ -38,21 +39,20 @@ public function main() { } // Create a JWT authentication provider with the relevant configurations. -http:AuthProvider jwtAuthProvider = { - scheme: http:JWT_AUTH, - config: { - issuer: "ballerina", - audience: ["ballerina.io"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider = new({ + issuer: "ballerina", + audience: ["ballerina.io"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); listener http:Listener ep = new(9090, config = { - authProviders: [jwtAuthProvider], + auth: { + authnHandlers: [jwtAuthProvider] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -63,8 +63,8 @@ listener http:Listener ep = new(9090, config = { @http:ServiceConfig { basePath: "/hello", - authConfig: { - authentication: { enabled: true } + auth: { + enabled: true } } service echo on ep { diff --git a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal index d39386da5fa6..a2676cc4537c 100644 --- a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal +++ b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal @@ -1,17 +1,18 @@ +import ballerina/auth; import ballerina/http; import ballerina/log; -http:AuthProvider basicAuthProvider = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider = new(); +http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); // The endpoint used here is `http:Listener`, which by default tries to // authenticate and authorize each request. The developer has the option to // override the authentication and authorization at the service level and // resource level. listener http:Listener ep = new(9090, config = { - authProviders: [basicAuthProvider], + auth: { + authnHandlers: [basicAuthProvider] + }, // The secure hello world sample uses https. secureSocket: { keyStore: { @@ -23,8 +24,8 @@ listener http:Listener ep = new(9090, config = { @http:ServiceConfig { basePath: "/hello", - authConfig: { - authentication: { enabled: true }, + auth: { + enabled: true, scopes: ["scope1"] } } @@ -41,7 +42,7 @@ service echo on ep { @http:ResourceConfig { methods: ["GET"], path: "/sayHello", - authConfig: { + auth: { scopes: ["scope2"] } } diff --git a/examples/secured-service-with-jwt/secured_service_with_jwt.bal b/examples/secured-service-with-jwt/secured_service_with_jwt.bal index 473fa409b070..b9dc7e50fba9 100644 --- a/examples/secured-service-with-jwt/secured_service_with_jwt.bal +++ b/examples/secured-service-with-jwt/secured_service_with_jwt.bal @@ -3,24 +3,23 @@ import ballerina/log; // Create a JWT authentication provider with the relevant configuration // parameters. -http:AuthProvider jwtAuthProvider = { - scheme: http:JWT_AUTH, - config: { - issuer:"ballerina", - audience: ["ballerina.io"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider = new({ + issuer: "ballerina", + audience: ["ballerina.io"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); // The endpoint used here is `http:Listener`. The JWT authentication // provider is set to this endpoint using the `authProviders` attribute. The // developer has the option to override the authentication and authorization // at the service and resource levels. listener http:Listener ep = new(9090, config = { - authProviders:[jwtAuthProvider], + auth: { + authnHandlers: [jwtAuthProvider] + }, // The secure hello world sample uses https. secureSocket: { keyStore: { @@ -32,8 +31,8 @@ listener http:Listener ep = new(9090, config = { @http:ServiceConfig { basePath: "/hello", - authConfig: { - authentication: { enabled: true } + auth: { + enabled: true } } // Auth configuration comprises of two parts - authentication & authorization. @@ -48,7 +47,7 @@ service echo on ep { @http:ResourceConfig { methods: ["GET"], path: "/sayHello", - authConfig: { + auth: { scopes: ["hello"] } } From c6ccc7e914b1fff0f95b8851ec0038cc6b817925 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Sun, 14 Apr 2019 08:41:55 +0530 Subject: [PATCH 14/52] Fix a bug in ldap authentication --- .../main/java/org/ballerinalang/auth/ldap/LdapConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/auth/src/main/java/org/ballerinalang/auth/ldap/LdapConstants.java b/stdlib/auth/src/main/java/org/ballerinalang/auth/ldap/LdapConstants.java index ec61e9b2c01f..aeab73c30e3d 100644 --- a/stdlib/auth/src/main/java/org/ballerinalang/auth/ldap/LdapConstants.java +++ b/stdlib/auth/src/main/java/org/ballerinalang/auth/ldap/LdapConstants.java @@ -56,7 +56,7 @@ public class LdapConstants { public static final String LDAP_CONFIGURATION = "ldapConfiguration"; public static final String LDAP_CONNECTION_SOURCE = "connectionSource"; public static final String LDAP_CONNECTION_CONTEXT = "connectionContext"; - public static final String LDAP_AUTH_PROVIDER_CONFIG = "ldapAuthProviderConfig"; + public static final String LDAP_AUTH_PROVIDER_CONFIG = "ldapAuthStoreProviderConfig"; public static final String ENDPOINT_INSTANCE_ID = "instanceId"; public static final String SECURE_AUTH_STORE_CONFIG = "secureClientSocket"; From f4afe69eab1986952544fb9a726b99259f875c19 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Sun, 14 Apr 2019 08:42:24 +0530 Subject: [PATCH 15/52] Fix integration tests related to auth --- ...config_inheritance_auth_disabling_test.bal | 19 +++--- .../02_authn_config_inheritance_test.bal | 19 +++--- .../03_authz_config_inheritance_test.bal | 17 ++--- .../04_resource_level_auth_config_test.bal | 15 ++--- .../05_service_level_auth_config_test.bal | 15 ++--- .../07_auth_test_without_annotations.bal | 11 ++-- .../08_authn_with_multiple_providers.bal | 49 ++++++++------- .../09_authn_with_different_scopes.bal | 28 +++++---- .../10_token_propagation_disabled_test.bal | 36 ++++++----- .../11_token_propagation_basic_auth_test.bal | 48 +++++++------- ..._secure_service_wrong_provider_id_test.bal | 20 +++--- .../13_authn_with_expired_certificate.bal | 26 ++++---- ..._certificate_with_no_expiry_validation.bal | 28 +++++---- .../15_token_propagation_jwt_test.bal | 63 ++++++++++--------- ...6_token_propagation_jwt_reissuing_test.bal | 63 ++++++++++--------- ...ropagation_jwt_reissuing_negative_test.bal | 51 ++++++++------- .../ldap_auth_store_authorization_test.bal | 20 +++--- .../authservices/ldap_auth_store_test.bal | 22 +++---- .../advanced_services/01_websub_publisher.bal | 11 ++-- 19 files changed, 293 insertions(+), 268 deletions(-) diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_auth_disabling_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_auth_disabling_test.bal index d951e7fd5a65..bf610ccc3943 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_auth_disabling_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_auth_disabling_test.bal @@ -14,15 +14,16 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider01 = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider01 = new; +http:BasicAuthnHandler basicAuthnHandler01 = new(basicAuthProvider01); listener http:Listener listener01 = new(9090, config = { - authProviders: [basicAuthProvider01], + auth: { + authnHandlers: [basicAuthnHandler01] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -33,8 +34,8 @@ listener http:Listener listener01 = new(9090, config = { @http:ServiceConfig { basePath: "/echo", - authConfig: { - authentication: { enabled: true }, + auth: { + enabled: true, scopes: ["xxx", "aaa"] } } @@ -43,8 +44,8 @@ service echo01 on listener01 { @http:ResourceConfig { methods: ["GET"], path: "/test", - authConfig: { - authentication: { enabled: false } + auth: { + enabled: false } } resource function echo(http:Caller caller, http:Request req) { diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authn_config_inheritance_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authn_config_inheritance_test.bal index 620280c2bcf0..e328b59d5302 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authn_config_inheritance_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authn_config_inheritance_test.bal @@ -14,15 +14,16 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider02 = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider02 = new; +http:BasicAuthnHandler basicAuthnHandler02 = new(basicAuthProvider02); listener http:Listener listener02 = new(9091, config = { - authProviders: [basicAuthProvider02], + auth: { + authnHandlers: [basicAuthnHandler02] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -33,8 +34,8 @@ listener http:Listener listener02 = new(9091, config = { @http:ServiceConfig { basePath: "/echo", - authConfig: { - authentication: { enabled: false }, + auth: { + enabled: false, scopes: ["xxx", "aaa"] } } @@ -43,8 +44,8 @@ service echo02 on listener02 { @http:ResourceConfig { methods: ["GET"], path: "/test", - authConfig: { - authentication: { enabled: true } + auth: { + enabled: true } } resource function echo(http:Caller caller, http:Request req) { diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_authz_config_inheritance_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_authz_config_inheritance_test.bal index 153f7d68fc38..6cd8910715d7 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_authz_config_inheritance_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_authz_config_inheritance_test.bal @@ -14,15 +14,16 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider03 = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider03 = new; +http:BasicAuthnHandler basicAuthnHandler03 = new(basicAuthProvider03); listener http:Listener listener03 = new(9092, config = { - authProviders: [basicAuthProvider03], + auth: { + authnHandlers: [basicAuthnHandler03] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -33,8 +34,8 @@ listener http:Listener listener03 = new(9092, config = { @http:ServiceConfig { basePath: "/echo", - authConfig: { - authentication: { enabled: true }, + auth: { + enabled: true, scopes: ["xxx"] } } @@ -43,7 +44,7 @@ service echo03 on listener03 { @http:ResourceConfig { methods: ["GET"], path: "/test", - authConfig: { + auth: { scopes: ["scope2", "scope4"] } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_resource_level_auth_config_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_resource_level_auth_config_test.bal index 327e28429c90..ab1274e2f3f4 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_resource_level_auth_config_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_resource_level_auth_config_test.bal @@ -14,15 +14,16 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider04 = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider04 = new; +http:BasicAuthnHandler basicAuthnHandler04 = new(basicAuthProvider04); listener http:Listener listener04 = new(9093, config = { - authProviders: [basicAuthProvider04], + auth: { + authnHandlers: [basicAuthnHandler04] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -39,8 +40,8 @@ service echo04 on listener04 { @http:ResourceConfig { methods: ["GET"], path: "/test", - authConfig: { - authentication: { enabled: true }, + auth: { + enabled: true, scopes: ["scope2"] } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_service_level_auth_config_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_service_level_auth_config_test.bal index 269a04210053..5d58e0f40e26 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_service_level_auth_config_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_service_level_auth_config_test.bal @@ -14,15 +14,16 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider05 = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider05 = new; +http:BasicAuthnHandler basicAuthnHandler05 = new(basicAuthProvider05); listener http:Listener listener05 = new(9094, config = { - authProviders: [basicAuthProvider05], + auth: { + authnHandlers: [basicAuthnHandler05] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -33,8 +34,8 @@ listener http:Listener listener05 = new(9094, config = { @http:ServiceConfig { basePath: "/echo", - authConfig: { - authentication: { enabled: true }, + auth: { + enabled: true, scopes: ["scope2"] } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_auth_test_without_annotations.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_auth_test_without_annotations.bal index 5146e9666cca..ada0ab8b489c 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_auth_test_without_annotations.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_auth_test_without_annotations.bal @@ -14,15 +14,16 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider07 = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider07 = new; +http:BasicAuthnHandler basicAuthnHandler07 = new(basicAuthProvider07); listener http:Listener listener07 = new(9098, config = { - authProviders: [basicAuthProvider07], + auth: { + authnHandlers: [basicAuthnHandler07] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_multiple_providers.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_multiple_providers.bal index cd24caa1e195..c11329c10447 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_multiple_providers.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_multiple_providers.bal @@ -14,36 +14,37 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider jwtAuthProvider1 = { - scheme: http:JWT_AUTH, - config: { - issuer: "example1", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider08_1 = new({ + issuer: "example1", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; - -http:AuthProvider jwtAuthProvider2 = { - scheme: http:JWT_AUTH, - config: { - issuer: "example2", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +}); + +auth:JWTAuthProvider jwtAuthProvider08_2 = new({ + issuer: "example2", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + + +http:JwtAuthnHandler jwtAuthnHandler08_1 = new(jwtAuthProvider08_1); +http:JwtAuthnHandler jwtAuthnHandler08_2 = new(jwtAuthProvider08_2); listener http:Listener listener08 = new(9099, config = { - authProviders: [jwtAuthProvider1, jwtAuthProvider2], + auth: { + authnHandlers: [jwtAuthnHandler08_1, jwtAuthnHandler08_2] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_different_scopes.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_different_scopes.bal index 9686322d6fe2..b8fbd24dae3d 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_different_scopes.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_different_scopes.bal @@ -14,23 +14,25 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider jwtAuthProvider3 = { - scheme: http:JWT_AUTH, - config: { - issuer: "ballerina", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider09 = new({ + issuer: "ballerina", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler09 = new(jwtAuthProvider09); listener http:Listener listener09 = new(9100, config = { - authProviders: [jwtAuthProvider3], + auth: { + authnHandlers: [jwtAuthnHandler09] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -40,7 +42,7 @@ listener http:Listener listener09 = new(9100, config = { }); @http:ServiceConfig { - authConfig: { + auth: { scopes: ["test-scope"] } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal index 8557754cf98e..5954701aeada 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal @@ -14,16 +14,17 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; // token propagation is set to false by default -http:AuthProvider basicAuthProvider10 = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider10 = new; +http:BasicAuthnHandler basicAuthnHandler10 = new(basicAuthProvider10); listener http:Listener listener10_1 = new(9190, config = { - authProviders: [basicAuthProvider10], + auth: { + authnHandlers: [basicAuthnHandler10] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -56,21 +57,22 @@ service passthroughService on listener10_1 { } } -http:AuthProvider jwtAuthProvider10 = { - scheme: http:JWT_AUTH, - config: { - issuer: "ballerina", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider10 = new({ + issuer: "ballerina", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler10 = new(jwtAuthProvider10); listener http:Listener listener10_2 = new(9195, config = { - authProviders: [jwtAuthProvider10], + auth: { + authnHandlers: [jwtAuthnHandler10] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal index d70b363102ba..180b2a26774e 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal @@ -14,15 +14,16 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider11 = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider11 = new; +http:BasicAuthnHandler basicAuthnHandler11 = new(basicAuthProvider11); listener http:Listener listener11 = new(9192, config = { - authProviders: [basicAuthProvider11], + auth: { + authnHandlers: [basicAuthnHandler11] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -70,28 +71,29 @@ service passthroughService03 on listener11 { } } -http:AuthProvider jwtAuthProvider03 = { - scheme: http:JWT_AUTH, - config: { - issuer: "ballerina", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider11 = new({ + issuer: "ballerina", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler11 = new(jwtAuthProvider11); listener http:Listener listener2 = new(9193, config = { - authProviders: [jwtAuthProvider03], - secureSocket: { - keyStore: { - path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", - password: "ballerina" - } + auth: { + authnHandlers: [jwtAuthnHandler11] + }, + secureSocket: { + keyStore: { + path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", + password: "ballerina" } - }); + } +}); @http:ServiceConfig { basePath: "/nyseStock" } service nyseStockQuote03 on listener2 { diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_secure_service_wrong_provider_id_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_secure_service_wrong_provider_id_test.bal index e3f4fa4dc043..afc18dcf86db 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_secure_service_wrong_provider_id_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_secure_service_wrong_provider_id_test.bal @@ -14,16 +14,18 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider12 = { - id: "basic1", - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider12_1 = new; +auth:ConfigAuthStoreProvider basicAuthProvider12_2 = new; +http:BasicAuthnHandler basicAuthnHandler12_1 = new(basicAuthProvider12_1); +http:BasicAuthnHandler basicAuthnHandler12_2 = new(basicAuthProvider12_2); listener http:Listener listener12 = new(9194, config = { - authProviders: [basicAuthProvider12], + auth: { + authnHandlers: [basicAuthnHandler12_1] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -34,9 +36,9 @@ listener http:Listener listener12 = new(9194, config = { @http:ServiceConfig { basePath: "/echo", - authConfig: { - authProviders: ["basic2"], - authentication: { enabled: true }, + auth: { + authnHandlers: [basicAuthnHandler12_2], + enabled: true, scopes: ["scope2"] } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_authn_with_expired_certificate.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_authn_with_expired_certificate.bal index 7536deff3093..5693c3882f22 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_authn_with_expired_certificate.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_authn_with_expired_certificate.bal @@ -14,23 +14,25 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider jwtAuthProvider4 = { - scheme: http:JWT_AUTH, - config: { - issuer:"ballerina", - audience: ["ballerina.io"], - certificateAlias: "cert", - trustStore: { - path: "../../../src/test/resources/auth/testtruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider13 = new({ + issuer:"ballerina", + audience: ["ballerina.io"], + certificateAlias: "cert", + trustStore: { + path: "../../../src/test/resources/auth/testtruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler13 = new(jwtAuthProvider13); listener http:Listener listener13 = new(9101, config = { - authProviders:[jwtAuthProvider4], + auth: { + authnHandlers: [jwtAuthnHandler13] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_authn_with_expired_certificate_with_no_expiry_validation.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_authn_with_expired_certificate_with_no_expiry_validation.bal index d8849466ef23..e5a9963c3d1b 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_authn_with_expired_certificate_with_no_expiry_validation.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_authn_with_expired_certificate_with_no_expiry_validation.bal @@ -14,24 +14,26 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider jwtAuthProvider14 = { - scheme: http:JWT_AUTH, - config: { - issuer:"ballerina", - audience: ["ballerina.io"], - certificateAlias: "cert", - validateCertificate: false, - trustStore: { - path: "../../../src/test/resources/auth/testtruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider14 = new({ + issuer:"ballerina", + audience: ["ballerina.io"], + certificateAlias: "cert", + validateCertificate: false, + trustStore: { + path: "../../../src/test/resources/auth/testtruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler14 = new(jwtAuthProvider14); listener http:Listener listener14 = new(9102, config = { - authProviders:[jwtAuthProvider14], + auth: { + authnHandlers: [jwtAuthnHandler14] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_token_propagation_jwt_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_token_propagation_jwt_test.bal index 779da3c35038..9cd7a026f6d8 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_token_propagation_jwt_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_token_propagation_jwt_test.bal @@ -14,23 +14,25 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider15 = { - scheme: http:JWT_AUTH, - config: { - issuer: "example1", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider15_1 = new({ + issuer: "example1", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler15_1 = new(jwtAuthProvider15_1); listener http:Listener listener15_1 = new(9103, config = { - authProviders: [basicAuthProvider15], + auth: { + authnHandlers: [jwtAuthnHandler15_1] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -66,28 +68,29 @@ service passthroughService15 on listener15_1 { } } -http:AuthProvider jwtAuthProvider15 = { - scheme: http:JWT_AUTH, - config: { - issuer: "example1", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider15_2 = new({ + issuer: "example1", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler15_2 = new(jwtAuthProvider15_2); listener http:Listener listener15_2 = new(9104, config = { - authProviders: [jwtAuthProvider15], - secureSocket: { - keyStore: { - path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", - password: "ballerina" - } + auth: { + authnHandlers: [jwtAuthnHandler15_2] + }, + secureSocket: { + keyStore: { + path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", + password: "ballerina" } - }); + } +}); @http:ServiceConfig { basePath: "/nyseStock" } service nyseStockQuote15 on listener15_2 { diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_token_propagation_jwt_reissuing_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_token_propagation_jwt_reissuing_test.bal index f906a3f513e1..ff4fbd4bd67a 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_token_propagation_jwt_reissuing_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_token_propagation_jwt_reissuing_test.bal @@ -14,23 +14,25 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider16 = { - scheme: http:JWT_AUTH, - config: { - issuer: "example1", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider16_1 = new({ + issuer: "example1", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler16_1 = new(jwtAuthProvider16_1); listener http:Listener listener16_1 = new(9105, config = { - authProviders: [basicAuthProvider16], + auth: { + authnHandlers: [jwtAuthnHandler16_1] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -78,28 +80,29 @@ service passthroughService16 on listener16_1 { } } -http:AuthProvider jwtAuthProvider16 = { - scheme: http:JWT_AUTH, - config: { - issuer: "example2", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider16_2 = new({ + issuer: "example2", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler16_2 = new(jwtAuthProvider16_2); listener http:Listener listener16_2 = new(9106, config = { - authProviders: [jwtAuthProvider16], - secureSocket: { - keyStore: { - path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", - password: "ballerina" - } + auth: { + authnHandlers: [jwtAuthnHandler16_2] + }, + secureSocket: { + keyStore: { + path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", + password: "ballerina" } - }); + } +}); @http:ServiceConfig { basePath: "/nyseStock" } service nyseStockQuote16 on listener16_2 { diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_token_propagation_jwt_reissuing_negative_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_token_propagation_jwt_reissuing_negative_test.bal index 25e3d7f1b580..70957d228069 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_token_propagation_jwt_reissuing_negative_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_token_propagation_jwt_reissuing_negative_test.bal @@ -14,23 +14,25 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/http; -http:AuthProvider basicAuthProvider17 = { - scheme: http:JWT_AUTH, - config: { - issuer: "example1", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider17_1 = new({ + issuer: "example1", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler17_1 = new(jwtAuthProvider17_1); listener http:Listener listener17_1 = new(9107, config = { - authProviders: [basicAuthProvider17], + auth: { + authnHandlers: [jwtAuthnHandler17_1] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -78,21 +80,22 @@ service passthroughService17 on listener17_1 { } } -http:AuthProvider jwtAuthProvider17 = { - scheme: http:JWT_AUTH, - config: { - issuer: "example2aaaaaaaaaaaaaa", - audience: ["ballerina"], - certificateAlias: "ballerina", - trustStore: { - path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", - password: "ballerina" - } +auth:JWTAuthProvider jwtAuthProvider17_2 = new({ + issuer: "example2aaaaaaaaaaaaaa", + audience: ["ballerina"], + certificateAlias: "ballerina", + trustStore: { + path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", + password: "ballerina" } -}; +}); + +http:JwtAuthnHandler jwtAuthnHandler17_2 = new(jwtAuthProvider17_2); listener http:Listener listener17_2 = new(9108, config = { - authProviders: [jwtAuthProvider17], + auth: { + authnHandlers: [jwtAuthnHandler17_2] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_authorization_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_authorization_test.bal index 93690ba79585..e0abe792c258 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_authorization_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_authorization_test.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -auth:LdapAuthProviderConfig ldapConfig = { +auth:LdapAuthStoreProviderConfig ldapConfig01 = { domainName: "ballerina.io", connectionURL: "ldap://localhost:9389", connectionName: "uid=admin,ou=system", @@ -40,15 +40,13 @@ auth:LdapAuthProviderConfig ldapConfig = { retryAttempts: 3 }; -http:AuthProvider authProvider = { - id: "basic02", - scheme: http:BASIC_AUTH, - authStoreProvider: http:LDAP_AUTH_STORE, - config: ldapConfig -}; +auth:LdapAuthStoreProvider ldapAuthStoreProvider01 = new(ldapConfig01, "ldap01"); +http:BasicAuthnHandler ldapAuthnHandler01 = new(ldapAuthStoreProvider01); listener http:Listener authEP = new(9097, config = { - authProviders: [authProvider], + auth: { + authnHandlers: [ldapAuthnHandler01] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -59,8 +57,8 @@ listener http:Listener authEP = new(9097, config = { @http:ServiceConfig { basePath: "/auth", - authConfig: { - authentication: { enabled: true } + auth: { + enabled: true } } service authService on authEP { @@ -68,7 +66,7 @@ service authService on authEP { @http:ResourceConfig { methods: ["GET"], path: "/failAuthz", - authConfig: { + auth: { scopes: ["admin", "support"] } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_test.bal index d7345455f0fd..518dd4545c34 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_test.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -auth:LdapAuthProviderConfig ldapAuthProviderConfig = { +auth:LdapAuthStoreProviderConfig ldapConfig02 = { domainName: "ballerina.io", connectionURL: "ldap://localhost:9389", connectionName: "uid=admin,ou=system", @@ -40,15 +40,13 @@ auth:LdapAuthProviderConfig ldapAuthProviderConfig = { retryAttempts: 3 }; -http:AuthProvider basicAuthProvider = { - id: "basic01", - scheme: http:BASIC_AUTH, - authStoreProvider: http:LDAP_AUTH_STORE, - config: ldapAuthProviderConfig -}; +auth:LdapAuthStoreProvider ldapAuthStoreProvider02 = new(ldapConfig02, "ldap01"); +http:BasicAuthnHandler ldapAuthnHandler02 = new(ldapAuthStoreProvider02); listener http:Listener ep = new(9096, config = { - authProviders: [basicAuthProvider], + auth: { + authnHandlers: [ldapAuthnHandler02] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -59,8 +57,8 @@ listener http:Listener ep = new(9096, config = { @http:ServiceConfig { basePath: "/ldapAuth", - authConfig: { - authentication: { enabled: true } + auth: { + enabled: true } } service helloService on ep { @@ -76,7 +74,7 @@ service helloService on ep { @http:ResourceConfig { methods: ["GET"], path: "/enableAuthz", - authConfig: { + auth: { scopes: ["test"] } } @@ -87,7 +85,7 @@ service helloService on ep { @http:ResourceConfig { methods: ["GET"], path: "/failAuthz", - authConfig: { + auth: { scopes: ["admin", "support"] } } diff --git a/tests/ballerina-integration-test/src/test/resources/websub/advanced_services/01_websub_publisher.bal b/tests/ballerina-integration-test/src/test/resources/websub/advanced_services/01_websub_publisher.bal index 2979a914953d..4aabab988c0e 100644 --- a/tests/ballerina-integration-test/src/test/resources/websub/advanced_services/01_websub_publisher.bal +++ b/tests/ballerina-integration-test/src/test/resources/websub/advanced_services/01_websub_publisher.bal @@ -14,6 +14,7 @@ // specific language governing permissions and limitations // under the License. +import ballerina/auth; import ballerina/h2; import ballerina/http; import ballerina/io; @@ -25,13 +26,13 @@ const string WEBSUB_PERSISTENCE_TOPIC_ONE = "http://one.persistence.topic.com"; const string WEBSUB_PERSISTENCE_TOPIC_TWO = "http://two.persistence.topic.com"; const string WEBSUB_TOPIC_ONE = "http://one.websub.topic.com"; -http:AuthProvider basicAuthProvider = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider = new; +http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); http:ServiceEndpointConfiguration hubListenerConfig = { - authProviders: [basicAuthProvider], + auth: { + authnHandlers: [basicAuthnHandler] + }, secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", From d5ac9ffba88ac81b2b1a4242193a594219074325 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Sun, 14 Apr 2019 16:27:30 +0530 Subject: [PATCH 16/52] Fix checkstyles --- .../org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java b/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java index a6893377620c..97d55580c0ae 100644 --- a/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java +++ b/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java @@ -25,7 +25,6 @@ import org.ballerinalang.model.values.BBoolean; import org.ballerinalang.model.values.BMap; import org.ballerinalang.model.values.BValue; -import org.ballerinalang.model.values.BValueArray; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; From a091591f94d9432b978acadb193443765a02eb64 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Sun, 14 Apr 2019 19:10:21 +0530 Subject: [PATCH 17/52] Fix a bug in authn filter engagement --- stdlib/http/src/main/ballerina/http/auth/authn_filter.bal | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal index 8fcaaa99ad9f..701a66bc5620 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal @@ -39,9 +39,11 @@ public type AuthnFilter object { var resourceAuthConfig = getServiceResourceAuthConfig(context); var resourceAuthHandlers = resourceAuthConfig["authnHandlers"]; if (resourceAuthHandlers is AuthnHandler[]) { - authenticated = handleAuthnRequest(resourceAuthHandlers, request); - } else { - authenticated = handleAuthnRequest(self.authnHandlers, request); + if (resourceAuthHandlers.length() > 0) { + authenticated = handleAuthnRequest(resourceAuthHandlers, request); + } else { + authenticated = handleAuthnRequest(self.authnHandlers, request); + } } return isAuthnSuccessful(caller, authenticated); } From cdffc8845c20d1e8052823883671eda7db1d4efa Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Sun, 14 Apr 2019 19:10:42 +0530 Subject: [PATCH 18/52] Fix a bug in bbe related to auth --- .../secured_service_with_basic_auth.bal | 15 +++++++------ .../secured_service_with_jwt.bal | 22 ++++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal index a2676cc4537c..b9c3f64418c0 100644 --- a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal +++ b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal @@ -2,7 +2,9 @@ import ballerina/auth; import ballerina/http; import ballerina/log; -auth:ConfigAuthStoreProvider basicAuthProvider = new(); +// Create a Basic authentication handler with the relevant configuration +// parameters. +auth:ConfigAuthStoreProvider basicAuthProvider = new; http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); // The endpoint used here is `http:Listener`, which by default tries to @@ -25,13 +27,12 @@ listener http:Listener ep = new(9090, config = { @http:ServiceConfig { basePath: "/hello", auth: { - enabled: true, scopes: ["scope1"] } } // Auth configuration comprises of two parts - authentication & authorization. -// Authentication can be enabled by setting the `authentication:{enabled:true}` -// annotation attribute. +// Authentication can be disabled by setting the `enabled: flag` annotation +// attribute, if needed. // Authorization is based on scopes, where a scope maps to one or more groups. // For a user to access a resource, the user should be in the same groups as // the scope. @@ -48,9 +49,9 @@ service echo on ep { } // The authentication and authorization settings can be overridden at // resource level. - // The hello resource would inherit the `authentication:{enabled:true}` - // flag from the service level, and override the scope defined in the - // service level (i.e., scope1) with scope2. + // The hello resource would inherit the `enabled: true` flag from the + // service level which is set automatically, and override the scope + // defined in the service level (i.e., scope1) with scope2. resource function hello(http:Caller caller, http:Request req) { error? result = caller->respond("Hello, World!!!"); if (result is error) { diff --git a/examples/secured-service-with-jwt/secured_service_with_jwt.bal b/examples/secured-service-with-jwt/secured_service_with_jwt.bal index b9dc7e50fba9..32bdc5f4c060 100644 --- a/examples/secured-service-with-jwt/secured_service_with_jwt.bal +++ b/examples/secured-service-with-jwt/secured_service_with_jwt.bal @@ -1,3 +1,4 @@ +import ballerina/auth; import ballerina/http; import ballerina/log; @@ -12,13 +13,17 @@ auth:JWTAuthProvider jwtAuthProvider = new({ password: "ballerina" } }); + +// Create a JWT authentication handler with the created JWT auth provider +http:JwtAuthnHandler jwtAuthnHandler = new(jwtAuthProvider); + // The endpoint used here is `http:Listener`. The JWT authentication -// provider is set to this endpoint using the `authProviders` attribute. The +// handler is set to this endpoint using the `authnHandlers` attribute. The // developer has the option to override the authentication and authorization // at the service and resource levels. listener http:Listener ep = new(9090, config = { auth: { - authnHandlers: [jwtAuthProvider] + authnHandlers: [jwtAuthnHandler] }, // The secure hello world sample uses https. secureSocket: { @@ -30,14 +35,10 @@ listener http:Listener ep = new(9090, config = { }); @http:ServiceConfig { - basePath: "/hello", - auth: { - enabled: true - } + basePath: "/hello" } // Auth configuration comprises of two parts - authentication & authorization. -// Authentication can be enabled by setting the `authentication:{enabled:true}` -// flag. +// Authentication can be disabled by setting the `enabled: false` flag, if needed. // Authorization is based on scopes, where a scope maps to one or more groups. // For a user to access a resource, the user should be in the same groups as // the scope. @@ -53,8 +54,9 @@ service echo on ep { } // The authentication and authorization settings can be overridden at // resource level. - // The hello resource would inherit the `authentication:{enabled:true}` flag - // from the service level, and define `hello` as the scope for the resource. + // The hello resource would inherit the `enabled: true` flag from the + // service level which is set automatically, and define `hello` as the + // scope for the resource. resource function hello(http:Caller caller, http:Request req) { error? result = caller->respond("Hello, World!!!"); if (result is error) { From 5c4109381ef86002c24ff4c6344e076a3cfe70c4 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Mon, 15 Apr 2019 15:12:20 +0530 Subject: [PATCH 19/52] Improve authn and authz logic --- .../main/ballerina/http/auth/authn_filter.bal | 11 +- .../main/ballerina/http/auth/authz_filter.bal | 16 +-- .../src/main/ballerina/http/auth/utils.bal | 116 ++++++++++++++---- 3 files changed, 105 insertions(+), 38 deletions(-) diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal index 701a66bc5620..d5dd51a308f0 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal @@ -36,12 +36,11 @@ public type AuthnFilter object { # + return - True if the filter succeeds public function filterRequest(Caller caller, Request request, FilterContext context) returns boolean { boolean authenticated = true; - var resourceAuthConfig = getServiceResourceAuthConfig(context); - var resourceAuthHandlers = resourceAuthConfig["authnHandlers"]; - if (resourceAuthHandlers is AuthnHandler[]) { - if (resourceAuthHandlers.length() > 0) { - authenticated = handleAuthnRequest(resourceAuthHandlers, request); - } else { + var authnHandlers = getAuthnHandlers(context); + if (authnHandlers is AuthnHandler[]) { + authenticated = handleAuthnRequest(authnHandlers, request); + } else { + if (authnHandlers) { authenticated = handleAuthnRequest(self.authnHandlers, request); } } diff --git a/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal index abec0928aae4..5de58725d104 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal @@ -40,15 +40,15 @@ public type AuthzFilter object { # + return - A flag to indicate if the request flow should be continued(true) or aborted(false), a code and a message public function filterRequest(Caller caller, Request request, FilterContext context) returns boolean { boolean authorized = true; - var resourceAuthConfig = getServiceResourceAuthConfig(context); - var resourceInboundScopes = resourceAuthConfig["scopes"]; - if (resourceInboundScopes is string[]) { - authorized = handleAuthzRequest(self.authzHandler, request, context, resourceInboundScopes); + var scopes = getScopes(context); + if (scopes is string[]) { + authorized = handleAuthzRequest(self.authzHandler, request, context, scopes); } else { - // scopes are not defined, no need to authorize - var scopes = self.scopes; - if (scopes is string[]) { - authorized = handleAuthzRequest(self.authzHandler, request, context, scopes); + if (scopes) { + var selfScopes = self.scopes; + if (selfScopes is string[]) { + authorized = handleAuthzRequest(self.authzHandler, request, context, selfScopes); + } } } return isAuthzSuccessful(caller, authorized); diff --git a/stdlib/http/src/main/ballerina/http/auth/utils.bal b/stdlib/http/src/main/ballerina/http/auth/utils.bal index 31d5393e1f95..749901c44d5c 100644 --- a/stdlib/http/src/main/ballerina/http/auth/utils.bal +++ b/stdlib/http/src/main/ballerina/http/auth/utils.bal @@ -60,33 +60,105 @@ public function extractBasicAuthHeaderValue(Request req) returns string? { } } -# Tries to retrieve the annotation value for authentication hierarchically - first from the resource level and then +# Tries to retrieve the authentication handlers hierarchically - first from the resource level and then # from the service level, if it is not there in the resource level. # # + context - `FilterContext` instance -# + return - `ServiceResourceAuth` instance if its defined, else nil -function getServiceResourceAuthConfig(FilterContext context) returns ServiceResourceAuth? { - // get authn details from the resource level - ServiceResourceAuth? resourceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, RESOURCE_ANN_NAME, - reflect:getResourceAnnotations(context.serviceRef, context.resourceName)); - ServiceResourceAuth? serviceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, SERVICE_ANN_NAME, - reflect:getServiceAnnotations(context.serviceRef)); - // check if authentication is enabled - boolean resourceSecured = isServiceResourceSecured(resourceLevelAuthAnn, serviceLevelAuthAnn); +# + return - Authentication handlers or whether it is needed to engage listener level handlers or not +function getAuthnHandlers(FilterContext context) returns AuthnHandler[]|boolean { + ServiceResourceAuth? resourceLevelAuthAnn; + ServiceResourceAuth? serviceLevelAuthAnn; + (resourceLevelAuthAnn, serviceLevelAuthAnn) = getServiceResourceAuthConfig(context); + + // check if authentication is enabled for resource and service + boolean resourceSecured = isServiceResourceSecured(resourceLevelAuthAnn); + boolean serviceSecured = isServiceResourceSecured(serviceLevelAuthAnn); + // if resource is not secured, no need to check further if (!resourceSecured) { - return (); + return false; } + // check if auth providers are given at resource level + if (resourceLevelAuthAnn is ServiceResourceAuth) { + var resourceAuthHandlers = resourceLevelAuthAnn["authnHandlers"]; + if (resourceAuthHandlers is AuthnHandler[]) { + if (resourceAuthHandlers.length() > 0) { + return resourceAuthHandlers; + } + } + } + + // if service is not secured, no need to check further + if (!serviceSecured) { + return true; + } + // no auth providers found in resource level, try in service level + if (serviceLevelAuthAnn is ServiceResourceAuth) { + var serviceAuthHandlers = serviceLevelAuthAnn["authnHandlers"]; + if (serviceAuthHandlers is AuthnHandler[]) { + if (serviceAuthHandlers.length() > 0) { + return serviceAuthHandlers; + } + } + } + return true; +} +# Tries to retrieve the authorization scopes hierarchically - first from the resource level and then +# from the service level, if it is not there in the resource level. +# +# + context - `FilterContext` instance +# + return - Authorization scopes or whether it is needed to engage listener level scopes or not +function getScopes(FilterContext context) returns string[]|boolean { + ServiceResourceAuth? resourceLevelAuthAnn; + ServiceResourceAuth? serviceLevelAuthAnn; + (resourceLevelAuthAnn, serviceLevelAuthAnn) = getServiceResourceAuthConfig(context); + + // check if authentication is enabled for resource and service + boolean resourceSecured = isServiceResourceSecured(resourceLevelAuthAnn); + boolean serviceSecured = isServiceResourceSecured(serviceLevelAuthAnn); + + // if resource is not secured, no need to check further + if (!resourceSecured) { + return false; + } // check if auth providers are given at resource level if (resourceLevelAuthAnn is ServiceResourceAuth) { - return resourceLevelAuthAnn; - } else { - // no auth providers found in resource level, try in service level - if (serviceLevelAuthAnn is ServiceResourceAuth) { - return serviceLevelAuthAnn; + var resourceScopes = resourceLevelAuthAnn["scopes"]; + if (resourceScopes is string[]) { + if (resourceScopes.length() > 0) { + return resourceScopes; + } + } + } + + // if service is not secured, no need to check further + if (!serviceSecured) { + return true; + } + // no auth providers found in resource level, try in service level + if (serviceLevelAuthAnn is ServiceResourceAuth) { + var serviceScopes = serviceLevelAuthAnn["scopes"]; + if (serviceScopes is string[]) { + if (serviceScopes.length() > 0) { + return serviceScopes; + } } } + return true; +} + +# Retrieve the authentication annotation value for resource level and service level. +# +# + context - `FilterContext` instance +# + return - Resource level and service level authentication annotations +function getServiceResourceAuthConfig(FilterContext context) returns (ServiceResourceAuth?, ServiceResourceAuth?) { + // get authn details from the resource level + ServiceResourceAuth? resourceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, RESOURCE_ANN_NAME, + reflect:getResourceAnnotations(context.serviceRef, context.resourceName)); + ServiceResourceAuth? serviceLevelAuthAnn = getAuthAnnotation(ANN_MODULE, SERVICE_ANN_NAME, + reflect:getServiceAnnotations(context.serviceRef)); + return (resourceLevelAuthAnn, serviceLevelAuthAnn); } # Retrieves and return the auth annotation with the given module name, annotation name and annotation data. @@ -119,16 +191,12 @@ function getAuthAnnotation(string annotationModule, string annotationName, refle # Check for the service or the resource is secured by evaluating the enabled flag configured by the user. # -# + resourceLevelAuthAnn - Resource level auth annotations -# + serviceLevelAuthAnn - Service level auth annotations +# + serviceResourceAuth - Service or resource auth annotation # + return - Whether the service or resource secured or not -function isServiceResourceSecured(ServiceResourceAuth? resourceLevelAuthAnn, - ServiceResourceAuth? serviceLevelAuthAnn) returns boolean { +function isServiceResourceSecured(ServiceResourceAuth? serviceResourceAuth) returns boolean { boolean secured = true; - if (resourceLevelAuthAnn is ServiceResourceAuth) { - secured = resourceLevelAuthAnn.enabled; - } else if (serviceLevelAuthAnn is ServiceResourceAuth) { - secured = serviceLevelAuthAnn.enabled; + if (serviceResourceAuth is ServiceResourceAuth) { + secured = serviceResourceAuth.enabled; } return secured; } From 92ed38a60b83a4369d691e9d0cdba660f9de898b Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Mon, 15 Apr 2019 15:13:48 +0530 Subject: [PATCH 20/52] Fix integration tests related to auth --- .../ballerinalang/test/auth/AuthBaseTest.java | 2 +- ...AuthnConfigInheritanceAuthDisableTest.java | 57 ------ .../test/auth/AuthnConfigInheritanceTest.java | 110 +++++++++++- ...ava => AuthnWithMultipleHandlersTest.java} | 12 +- .../auth/AuthnWithoutHTTPAnnotationsTest.java | 6 +- .../test/auth/AuthzCacheTest.java | 8 +- .../test/auth/AuthzConfigInheritanceTest.java | 100 ++++++++--- .../test/auth/LdapAuthStoreTest.java | 4 +- .../test/auth/ResourceLevelAuthTest.java | 2 +- .../SecureClientWrongAuthProviderTest.java | 47 ----- .../test/auth/ServiceLevelAuthnTest.java | 10 +- .../test/auth/TokenPropagationTest.java | 4 +- .../auth/authclients/oauth-client.bal | 28 +-- ...l => 01_authn_config_inheritance_test.bal} | 48 +++++- .../02_authn_config_inheritance_test.bal | 54 ------ .../02_authz_config_inheritance_test.bal | 162 ++++++++++++++++++ ...=> 03_resource_level_auth_config_test.bal} | 12 +- ... => 04_service_level_auth_config_test.bal} | 21 ++- ...05_auth_test_without_annotations_test.bal} | 20 +-- ...al => 06_authn_with_multiple_handlers.bal} | 19 +- .../07_auth_test_without_annotations.bal | 40 ----- ...> 07_authn_with_different_scopes_test.bal} | 13 +- ...8_authn_with_expired_certificate_test.bal} | 15 +- ...certificate_with_no_expiry_validation.bal} | 15 +- .../10_token_propagation_disabled_test.bal | 10 +- .../11_token_propagation_basic_auth_test.bal | 10 +- ..._secure_service_wrong_provider_id_test.bal | 54 ------ ....bal => 12_token_propagation_jwt_test.bal} | 24 +-- ..._token_propagation_jwt_reissuing_test.bal} | 24 +-- ...opagation_jwt_reissuing_negative_test.bal} | 24 +-- ...e_test.bal => 15_ldap_auth_store_test.bal} | 2 +- ....bal => 16_ldap_auth_store_authz_test.bal} | 2 +- ...uth-service.bal => mock-oauth-service.bal} | 2 +- .../src/test/resources/auth/ballerina.conf | 4 +- .../src/test/resources/testng.xml | 12 +- 35 files changed, 535 insertions(+), 442 deletions(-) delete mode 100644 tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceAuthDisableTest.java rename tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/{AuthnWithMultipleProvidersTest.java => AuthnWithMultipleHandlersTest.java} (96%) delete mode 100644 tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/SecureClientWrongAuthProviderTest.java rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{01_authn_config_inheritance_auth_disabling_test.bal => 01_authn_config_inheritance_test.bal} (58%) delete mode 100644 tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authn_config_inheritance_test.bal create mode 100644 tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authz_config_inheritance_test.bal rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{03_authz_config_inheritance_test.bal => 03_resource_level_auth_config_test.bal} (85%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{04_resource_level_auth_config_test.bal => 04_service_level_auth_config_test.bal} (78%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{05_service_level_auth_config_test.bal => 05_auth_test_without_annotations_test.bal} (73%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{08_authn_with_multiple_providers.bal => 06_authn_with_multiple_handlers.bal} (74%) delete mode 100644 tests/ballerina-integration-test/src/test/resources/auth/authservices/07_auth_test_without_annotations.bal rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{09_authn_with_different_scopes.bal => 07_authn_with_different_scopes_test.bal} (78%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{13_authn_with_expired_certificate.bal => 08_authn_with_expired_certificate_test.bal} (76%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{14_authn_with_expired_certificate_with_no_expiry_validation.bal => 09_authn_with_expired_certificate_with_no_expiry_validation.bal} (77%) delete mode 100644 tests/ballerina-integration-test/src/test/resources/auth/authservices/12_secure_service_wrong_provider_id_test.bal rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{15_token_propagation_jwt_test.bal => 12_token_propagation_jwt_test.bal} (79%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{16_token_propagation_jwt_reissuing_test.bal => 13_token_propagation_jwt_reissuing_test.bal} (82%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{17_token_propagation_jwt_reissuing_negative_test.bal => 14_token_propagation_jwt_reissuing_negative_test.bal} (82%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{ldap_auth_store_test.bal => 15_ldap_auth_store_test.bal} (98%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{ldap_auth_store_authorization_test.bal => 16_ldap_auth_store_authz_test.bal} (97%) rename tests/ballerina-integration-test/src/test/resources/auth/authservices/{06_mock-oauth-service.bal => mock-oauth-service.bal} (99%) diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java index 98b99f90f3b3..68153a4b8c99 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java @@ -37,7 +37,7 @@ public class AuthBaseTest extends BaseTest { @BeforeGroups(value = "auth-test", alwaysRun = true) public void start() throws Exception { int[] requiredPorts = new int[]{9090, 9091, 9092, 9093, 9094, 9095, 9096, 9097, 9098, 9099, 9100, 9101, 9102, - 9103, 9104, 9105, 9106, 9107, 9108, 9190, 9191, 9192, 9193, 9194, 9195, 9196}; + 9103, 9104, 9105, 9106, 9107, 9108, 9109, 9110, 9195, 9196}; embeddedDirectoryServer = new EmbeddedDirectoryServer(); embeddedDirectoryServer.startLdapServer(9389); diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceAuthDisableTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceAuthDisableTest.java deleted file mode 100644 index d87e4c394ce3..000000000000 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceAuthDisableTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.ballerinalang.test.auth; - -import org.ballerinalang.test.context.Constant; -import org.ballerinalang.test.util.HttpResponse; -import org.ballerinalang.test.util.HttpsClientRequest; -import org.testng.Assert; -import org.testng.annotations.Test; - -import java.util.HashMap; -import java.util.Map; - -/** - * Test cases for disabling authorization scenarios. - * - * @since 0.970.0 - */ -@Test(groups = "auth-test") -public class AuthnConfigInheritanceAuthDisableTest extends AuthBaseTest { - - private final int servicePort = Constant.DEFAULT_HTTP_PORT; - - @Test(description = "non secured resource test case with no auth headers") - public void testResourceLevelAuthDisableWithNoAuthHeaders() throws Exception { - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), - serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); - } - - @Test(description = "non secured resource test case") - public void testResourceLevelAuthDisable() throws Exception { - Map headersMap = new HashMap<>(); - headersMap.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), - headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); - } -} diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java index a40f4b99a81d..6f3cddf15480 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java @@ -27,30 +27,122 @@ import java.util.Map; /** - * Test cases for authorization config inheritance scenarios. + * Test cases for authentication config inheritance scenarios. */ @Test(groups = "auth-test") public class AuthnConfigInheritanceTest extends AuthBaseTest { - private final int servicePort = 9091; + private final int servicePort = 9090; - @Test(description = "invalid scope test case") - public void testAuthzFailureWithInheritedConfigs() throws Exception { + @Test(description = "Secured resource, secured service test case with no auth headers") + public void testNoAuthHeaders1() throws Exception { + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test1"), + serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + } + + @Test(description = "Non secured resource, secured service test case with no auth headers") + public void testNoAuthHeaders2() throws Exception { + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test2"), + serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Secured resource, non secured service test case with no auth headers") + public void testNoAuthHeaders3() throws Exception { + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test1"), + serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + } + + @Test(description = "Non secured resource, non secured service test case with no auth headers") + public void testNoAuthHeaders4() throws Exception { + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test2"), + serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Secured resource, secured service test case with valid auth headers") + public void testValidAuthHeaders1() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Non secured resource, secured service test case with valid auth headers") + public void testValidAuthHeaders2() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Secured resource, non secured service test case with valid auth headers") + public void testValidAuthHeaders3() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test1"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); } - @Test(description = "Authn and authz failure test case") - public void testAuthFailureWithInheritedConfigs() throws Exception { + @Test(description = "Non secured resource, non secured service test case with valid auth headers") + public void testValidAuthHeaders4() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Secured resource, secured service test case with invalid auth headers") + public void testInvalidAuthHeaders1() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test1"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); } + + @Test(description = "Non secured resource, secured service test case with invalid auth headers") + public void testInvalidAuthHeaders2() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Secured resource, non secured service test case with invalid auth headers") + public void testInvalidAuthHeaders3() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + } + + @Test(description = "Non secured resource, non secured service test case with invalid auth headers") + public void testInvalidAuthHeaders4() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleProvidersTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java similarity index 96% rename from tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleProvidersTest.java rename to tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java index f43bf8413157..11dcc08d5333 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleProvidersTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java @@ -34,9 +34,9 @@ * @since 0.983.0 */ @Test(groups = "auth-test") -public class AuthnWithMultipleProvidersTest extends AuthBaseTest { +public class AuthnWithMultipleHandlersTest extends AuthBaseTest { - private final int servicePort = 9099; + private final int servicePort = 9095; @Test(description = "Authn success test case with example1 issuer") public void testAuthSuccessWithExample1Issuer() throws Exception { @@ -64,7 +64,7 @@ public void testAuthSuccessWithExample1Issuer() throws Exception { "PiSX1FR-nIUTcJ9anaoQVEKo3OpkIPzd_4_95CpHXF1MaW18ww5h_NShQnUrN7myrBfc-UbHsqC1YEBAM2M-3NMs8jjgcZHfZ1J" + "jomZCjd5eUXz8R5Vl46uAlSbFAmxAfY1T-31qUB93eCL2iJfDc70OK2txohryntw9h-OePwQULJN0EiwpoI60HQFFlgC1g_crPI" + "DakBTiEITrbO3OzrNeCQFBN-Ji4BTXq97TulCIRNneDLCUBSRE1A"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo8/test8"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); @@ -96,7 +96,7 @@ public void testAuthSuccessWithExample2Issuer() throws Exception { "m8qovBmVzzd7vDdgvpvRuNhmFmcv63Jc9KjyoBiA_BDjFy9oTTzP35-PRuekQ0xy3gGjcgqhPcQtmLOyeTUbMhcrpGLB-fYp4x" + "9OqRo5ZNtMrm0aOuMj-VbKACc2vBdju5gu_nEtxBGeFWVHd_9l7OqNUTibmFzEV34GXP8rvVl73JZnp5tJesH-GXArsCjvSj1Q" + "pvcLBUiAaXFeXPb9t4iHFugJzHY68eQQZcxyIxWVyj2eNV4HmBjvqVLQuA"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo8/test8"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); @@ -128,7 +128,7 @@ public void testAuthFailWithExample3Issuer() throws Exception { "yph3T7JzHGEXGCEXDmACywj58pnVKISsSb5tR8pDaidh-XRrCwE2hXB4X2_3fi9-Mn2U3ZFVb2q8-W9V9bmI1KJK-ALdKFuYu" + "Z9BzIq3YfZNyqAyFaQo9TFYhqNRvDbBsfdmjAfcj_SlYfSmbmTMG2FCahr9Tq_S3pMbh3S_6ii1-OqTGUukFdz1c08F5SvIZ9" + "t1xdW40dCnDrSR6urqVGys0Zg_Ru0mnPg4dU2JPuwDLuKzj4KzWXShZ2Il5Ol-IA"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo8/test8"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); @@ -158,7 +158,7 @@ public void testAuthFailWithExample1IssuerAndInvalidAudience() throws Exception "BAF35RJVepnoCq5ctdrgzcpYI3B8MSa07Sn00oEpSelzRK3SHPEglzGzOaG2GDWN2N2-TGF2IVSH1Bn3ovjFXsirh_uJZ9kbn" + "QhqrnZ2NIIjKaRa8y9RKtvwq3XnEvej2Ki7ddnx5AGSPXkiJ5AZBNtA5sRwEvJiffsff9tmJvI909Atf66WVylaFyP4e6E_Us" + "roxJPVxncPTRuewApF-RpXPKdheVEqQ4w"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo8/test8"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java index 016c59836c5d..8fb0d0f6f0c9 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java @@ -37,14 +37,14 @@ @Test(groups = "auth-test") public class AuthnWithoutHTTPAnnotationsTest extends AuthBaseTest { - private final int servicePort = 9098; + private final int servicePort = 9094; @Test(description = "Authn and authz success test case") public void testAuthSuccess() throws Exception { Map headers = new HashMap<>(); headers.put(HttpHeaderNames.CONTENT_TYPE.toString(), TestConstant.CONTENT_TYPE_TEXT_PLAIN); headers.put("Authorization", "Basic aXN1cnU6eHh4"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo7/test7"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); @@ -55,7 +55,7 @@ public void testAuthnFailure() throws Exception { Map headers = new HashMap<>(); headers.put(HttpHeaderNames.CONTENT_TYPE.toString(), TestConstant.CONTENT_TYPE_TEXT_PLAIN); headers.put("Authorization", "Basic aW52YWxpZFVzZXI6YWJj"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo7/test7"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java index 941ccc28ba0e..d589f9e479c9 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java @@ -36,7 +36,7 @@ @Test(groups = "auth-test") public class AuthzCacheTest extends AuthBaseTest { - private final int servicePort = 9100; + private final int servicePort = 9096; @Test(description = "Authn success test case with example1 issuer") public void testAuthCache() throws Exception { @@ -64,7 +64,7 @@ public void testAuthCache() throws Exception { "l2aawDBFag_4GJhRd__AxjZemCqAdKs-cqX-JNSWnB8m7cBfA9LOH-y2dmowNqv4VeMuuxKriMe9w-7YpnRPJrs-HIxLMgOdJa" + "YsFHEPL1wWDvlpt53wDjCveYw4OgD39S5g-pcemGUflVUMoKB3nti1qjzcIb6nDKdqQiAbnSN2UKEVLXQpZX5WUKe5SuFlKnS9" + "z1BbKC2z79eMe15yx8asas3krgJyKVNISUWlgPWvKHxyfh_RoQYgWPn-rhng1_P8Ag"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo9/test9"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); @@ -93,7 +93,7 @@ public void testAuthCache() throws Exception { "XichRv_y7_VuY-WTm7QBtR5tqpBVAI59SezTE9NqxCIy-ol4RE7rQ7plOr2y80NNQfoWE6PCwsjFNc2v_FdXzR6ADvsnNZbRu" + "Z2nhnTpkDkdmgDOyonw4YZPG275ZQCRTJEjyUKnF4yEm9c2cwCtbOVzdThtzuJEmEcrRHAre7zZX857R2ZKo84TZ8Tes3maGY" + "dpwoUnOy9aseNB8iy0AAPQwf1MkpbgCUJFGLAWHAQsUBJXPpCPGMKVJ5CYzFiPC_bX_pUrzrXOJw"); - response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo9/test9"), + response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); @@ -122,7 +122,7 @@ public void testAuthCache() throws Exception { "eO9Kt3EIJHU4njheptz7Qfep_sEyYdq3CvQI5bKxUZw4bA-87AxTv_tFpSAbiBpGhD0rmhYAfkXF7QsWplDts_xFRhMmxHEsel" + "RKMg4F9-iX3HQYouJoRzyDJTETyzxC2vFE0FaCxVDrrs5B2KU3YB-etkPUWDFgzaoV13SaHxPBhj-f5arlfRaDk2XtbNnchHgs" + "LbLux8FaxyAglgRoDNgBgaCynbhUYAUnpr2JSx72FN8J0CJB5f31EMmmd4FukTtv-8w"); - response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo9/test9"), + response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java index 83bcc60ada3d..ddd8d32ce91a 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java @@ -32,35 +32,95 @@ @Test(groups = "auth-test") public class AuthzConfigInheritanceTest extends AuthBaseTest { - private final int servicePort = 9092; + private final int servicePort = 9091; - @Test(description = "Authn and authz success test case") - public void testAuthSuccessWithInheritedAuthzConfigs() throws Exception { - Map headers = new HashMap<>(); - headers.put("Authorization", "Basic aXN1cnU6eHh4"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance - .getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); + @Test(description = "Service level valid scopes and resource level valid scopes test case") + public void testValidAuthHeaders1() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test1"), + headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); } - @Test(description = "Authn success and authz failure test case") - public void testAuthzFailureWithInheritedAuthzConfigs() throws Exception { - Map headers = new HashMap<>(); - headers.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance - .getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); + @Test(description = "Service level valid scopes and resource level invalid scopes test case") + public void testValidAuthHeaders2() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test2"), + headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); } - @Test(description = "Authn and authz failure test case") - public void testAuthFailureWithInheritedAuthzConfigs() throws Exception { - Map headers = new HashMap<>(); - headers.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance - .getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); + @Test(description = "Service level valid scopes and resource level scopes not given test case") + public void testValidAuthHeaders3() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test3"), + headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Service level invalid scopes and resource level valid scopes test case") + public void testValidAuthHeaders4() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Service level invalid scopes and resource level invalid scopes test case") + public void testValidAuthHeaders5() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Service level invalid scopes and resource level scopes not given test case") + public void testValidAuthHeaders6() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test3"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Service level scopes not given and resource level valid scopes test case") + public void testValidAuthHeaders7() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo3/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Service level scopes not given and resource level invalid scopes test case") + public void testValidAuthHeaders8() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo3/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Service level scopes not given and resource level scopes not given test case") + public void testValidAuthHeaders9() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo3/test3"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java index 101316cda2f4..2a896a8b2632 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java @@ -34,8 +34,8 @@ @Test(groups = "auth-test") public class LdapAuthStoreTest extends AuthBaseTest { - private final int servicePort = 9096; - private final int authzServicePort = 9097; + private final int servicePort = 9109; + private final int authzServicePort = 9110; @Test(description = "Test authenticate and authorize request against ldap auth store") public void testAuthenticationWithInvalidCredentials() throws Exception { diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java index 0dd0e90fbc77..ac810629c2c1 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java @@ -32,7 +32,7 @@ @Test(groups = "auth-test") public class ResourceLevelAuthTest extends AuthBaseTest { - private final int servicePort = 9093; + private final int servicePort = 9092; @Test(description = "Authn and authz success test case") public void testAuthSuccessWithResourceLevelConfigs() throws Exception { diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/SecureClientWrongAuthProviderTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/SecureClientWrongAuthProviderTest.java deleted file mode 100644 index 4be28764b5ab..000000000000 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/SecureClientWrongAuthProviderTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.ballerinalang.test.auth; - -import io.netty.handler.codec.http.HttpHeaderNames; -import org.ballerinalang.test.util.HttpResponse; -import org.ballerinalang.test.util.HttpsClientRequest; -import org.ballerinalang.test.util.TestConstant; -import org.testng.Assert; -import org.testng.annotations.Test; - -import java.util.HashMap; -import java.util.Map; - -/** - * Test cases for verifying wrong auth provider for a service. - */ -@Test(groups = "auth-test") -public class SecureClientWrongAuthProviderTest extends AuthBaseTest { - - @Test(description = "Authn failure with wrong auth provider") - public void testAuthSuccess() throws Exception { - Map headers = new HashMap<>(); - headers.put(HttpHeaderNames.CONTENT_TYPE.toString(), TestConstant.CONTENT_TYPE_TEXT_PLAIN); - headers.put("Authorization", "Basic aXN1cnU6eHh4"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9194, "echo/test"), headers, - serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); - } -} diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java index 705e24501d49..7d2bd3fb2920 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java @@ -32,9 +32,9 @@ @Test(groups = "auth-test") public class ServiceLevelAuthnTest extends AuthBaseTest { - private final int servicePort = 9094; - private final int servicePortForExpiredCertificateTest = 9101; - private final int servicePortForExpiredCertificateTestWithNoExpiryValidation = 9102; + private final int servicePort = 9093; + private final int servicePortForExpiredCertificateTest = 9097; + private final int servicePortForExpiredCertificateTestWithNoExpiryValidation = 9098; @Test(description = "Auth with JWT signed with expired trusted certificate") public void testAuthnWithJWTSignedWithExpiredTrustedCertificate() throws Exception { @@ -61,7 +61,7 @@ public void testAuthnWithJWTSignedWithExpiredTrustedCertificate() throws Excepti "18xqUzweCRL-DLAAYwjbzGQ56ekbEdAg02sFco4aozOyt8OUDwS9cH_JlhUn2JEHmVKaatljEnfgRc8fOW6Y5IJ7dOPp7ra5e" + "00sk7JwYY8wKaZWxAGSgRpWgTY6C4XRjGIsR5ZWQdXCAnV27idGDrtR2uG4YQwCWUCzA"); HttpResponse response = HttpsClientRequest.doGet(serverInstance - .getServiceURLHttps(servicePortForExpiredCertificateTest, "echo13/test13"), + .getServiceURLHttps(servicePortForExpiredCertificateTest, "echo/test"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); @@ -93,7 +93,7 @@ public void testAuthnWithJWTSignedWithExpiredTrustedCertificateWithNoExpiryValid "00sk7JwYY8wKaZWxAGSgRpWgTY6C4XRjGIsR5ZWQdXCAnV27idGDrtR2uG4YQwCWUCzA"); HttpResponse response = HttpsClientRequest.doGet(serverInstance .getServiceURLHttps(servicePortForExpiredCertificateTestWithNoExpiryValidation, - "echo14/test14"), headersMap, serverInstance.getServerHome()); + "echo/test"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java index 47031054df05..25a3881aa5b7 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java @@ -36,7 +36,7 @@ public class TokenPropagationTest extends AuthBaseTest { public void testTokenPropagationWithBasicAuthInbound() throws Exception { Map headers = new HashMap<>(); headers.put("Authorization", "Basic aXN1cnU6eHh4"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9192, "passthrough"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9101, "passthrough"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); @@ -46,7 +46,7 @@ public void testTokenPropagationWithBasicAuthInbound() throws Exception { public void testWithoutTokenPropagation() throws Exception { Map headers = new HashMap<>(); headers.put("Authorization", "Basic aXN1cnU6eHh4"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9190, "passthrough"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9099, "passthrough"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authclients/oauth-client.bal b/tests/ballerina-integration-test/src/test/resources/auth/authclients/oauth-client.bal index 23acbe0cd214..89de5239cb23 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authclients/oauth-client.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authclients/oauth-client.bal @@ -17,7 +17,7 @@ import ballerina/http; // Test the client credentials grant type with valid credentials -http:Client clientEP1 = new("https://localhost:9095", config = { +http:Client clientEP1 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -33,7 +33,7 @@ http:Client clientEP1 = new("https://localhost:9095", config = { }); // Test the client credentials grant type with invalid client credentials -http:Client clientEP2 = new("https://localhost:9095", config = { +http:Client clientEP2 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -49,7 +49,7 @@ http:Client clientEP2 = new("https://localhost:9095", config = { }); // Test the client credentials grant type with a post-body bearer and valid credentials -http:Client clientEP3 = new("https://localhost:9095", config = { +http:Client clientEP3 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -66,7 +66,7 @@ http:Client clientEP3 = new("https://localhost:9095", config = { }); // Test the client credentials grant type with a post-body bearer and invalid credentials -http:Client clientEP4 = new("https://localhost:9095", config = { +http:Client clientEP4 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -83,7 +83,7 @@ http:Client clientEP4 = new("https://localhost:9095", config = { }); // Test the password grant type with valid credentials -http:Client clientEP5 = new("https://localhost:9095", config = { +http:Client clientEP5 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -101,7 +101,7 @@ http:Client clientEP5 = new("https://localhost:9095", config = { }); // Test the password grant type with valid credentials and a valid refresh config -http:Client clientEP6 = new("https://localhost:9095", config = { +http:Client clientEP6 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -123,7 +123,7 @@ http:Client clientEP6 = new("https://localhost:9095", config = { }); // Test the password grant type with an invalid username, password, and a valid refresh config -http:Client clientEP7 = new("https://localhost:9095", config = { +http:Client clientEP7 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -145,7 +145,7 @@ http:Client clientEP7 = new("https://localhost:9095", config = { }); // Test the password grant type with a bearer without credentials and a valid username and password -http:Client clientEP8 = new("https://localhost:9095", config = { +http:Client clientEP8 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -162,7 +162,7 @@ http:Client clientEP8 = new("https://localhost:9095", config = { }); // Test the direct token mode with valid credentials and without a refresh config -http:Client clientEP9 = new("https://localhost:9095", config = { +http:Client clientEP9 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -175,7 +175,7 @@ http:Client clientEP9 = new("https://localhost:9095", config = { }); // Test the direct token mode with an invalid access token and without a refresh config -http:Client clientEP10 = new("https://localhost:9095", config = { +http:Client clientEP10 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -188,7 +188,7 @@ http:Client clientEP10 = new("https://localhost:9095", config = { }); // Test the direct token mode with an invalid access token and a valid refresh config -http:Client clientEP11 = new("https://localhost:9095", config = { +http:Client clientEP11 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -208,7 +208,7 @@ http:Client clientEP11 = new("https://localhost:9095", config = { }); // Test the direct token mode (with the retrying request set as false) with an invalid access token and without a refresh config -http:Client clientEP12 = new("https://localhost:9095", config = { +http:Client clientEP12 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -222,7 +222,7 @@ http:Client clientEP12 = new("https://localhost:9095", config = { }); // Test the direct token mode (with the retrying request set as false) with an invalid access token and a valid refresh config -http:Client clientEP13 = new("https://localhost:9095", config = { +http:Client clientEP13 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { @@ -243,7 +243,7 @@ http:Client clientEP13 = new("https://localhost:9095", config = { }); // Test the direct token mode with an invalid access token and an invalid refresh config -http:Client clientEP14 = new("https://localhost:9095", config = { +http:Client clientEP14 = new("https://localhost:9195", config = { auth: { scheme: http:OAUTH2, config: { diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_auth_disabling_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_test.bal similarity index 58% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_auth_disabling_test.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_test.bal index bf610ccc3943..c708c4d61ad3 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_auth_disabling_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/01_authn_config_inheritance_test.bal @@ -33,23 +33,59 @@ listener http:Listener listener01 = new(9090, config = { }); @http:ServiceConfig { - basePath: "/echo", + basePath: "/echo1", auth: { - enabled: true, - scopes: ["xxx", "aaa"] + enabled: true } } -service echo01 on listener01 { +service echo01_1 on listener01 { + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true + } + } + resource function test1(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } @http:ResourceConfig { methods: ["GET"], - path: "/test", auth: { enabled: false } } - resource function echo(http:Caller caller, http:Request req) { + resource function test2(http:Caller caller, http:Request req) { checkpanic caller->respond(()); } } +@http:ServiceConfig { + basePath: "/echo2", + auth: { + enabled: false + } +} +service echo01_2 on listener01 { + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true + } + } + resource function test1(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: false + } + } + resource function test2(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } +} diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authn_config_inheritance_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authn_config_inheritance_test.bal deleted file mode 100644 index e328b59d5302..000000000000 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authn_config_inheritance_test.bal +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/auth; -import ballerina/http; - -auth:ConfigAuthStoreProvider basicAuthProvider02 = new; -http:BasicAuthnHandler basicAuthnHandler02 = new(basicAuthProvider02); - -listener http:Listener listener02 = new(9091, config = { - auth: { - authnHandlers: [basicAuthnHandler02] - }, - secureSocket: { - keyStore: { - path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", - password: "ballerina" - } - } -}); - -@http:ServiceConfig { - basePath: "/echo", - auth: { - enabled: false, - scopes: ["xxx", "aaa"] - } -} -service echo02 on listener02 { - - @http:ResourceConfig { - methods: ["GET"], - path: "/test", - auth: { - enabled: true - } - } - resource function echo(http:Caller caller, http:Request req) { - checkpanic caller->respond(()); - } -} diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authz_config_inheritance_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authz_config_inheritance_test.bal new file mode 100644 index 000000000000..1ad916b02809 --- /dev/null +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authz_config_inheritance_test.bal @@ -0,0 +1,162 @@ +// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// +// WSO2 Inc. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/auth; +import ballerina/http; + +auth:ConfigAuthStoreProvider basicAuthProvider02 = new; +http:BasicAuthnHandler basicAuthnHandler02 = new(basicAuthProvider02); + +listener http:Listener listener02 = new(9091, config = { + auth: { + authnHandlers: [basicAuthnHandler02], + scopes: ["scope1"] + }, + secureSocket: { + keyStore: { + path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", + password: "ballerina" + } + } +}); + +@http:ServiceConfig { + basePath: "/echo1", + auth: { + enabled: true, + scopes: ["scope3"] + } +} +service echo02_1 on listener02 { + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true, + scopes: ["scope1", "scope2"] + } + } + resource function test1(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true, + scopes: ["scope3", "scope4"] + } + } + resource function test2(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } + + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true + } + } + resource function test3(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } +} + +@http:ServiceConfig { + basePath: "/echo2", + auth: { + enabled: true, + scopes: ["scope4"] + } +} +service echo02_2 on listener02 { + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true, + scopes: ["scope1", "scope2"] + } + } + resource function test1(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true, + scopes: ["scope3", "scope4"] + } + } + resource function test2(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } + + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true + } + } + resource function test3(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } +} + +@http:ServiceConfig { + basePath: "/echo3", + auth: { + enabled: true + } +} +service echo02_3 on listener02 { + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true, + scopes: ["scope1", "scope2"] + } + } + resource function test1(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true, + scopes: ["scope3", "scope4"] + } + } + resource function test2(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } + + + @http:ResourceConfig { + methods: ["GET"], + auth: { + enabled: true + } + } + resource function test3(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } +} diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_authz_config_inheritance_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_resource_level_auth_config_test.bal similarity index 85% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/03_authz_config_inheritance_test.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/03_resource_level_auth_config_test.bal index 6cd8910715d7..768c476bc9b0 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_authz_config_inheritance_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_resource_level_auth_config_test.bal @@ -33,22 +33,18 @@ listener http:Listener listener03 = new(9092, config = { }); @http:ServiceConfig { - basePath: "/echo", - auth: { - enabled: true, - scopes: ["xxx"] - } + basePath: "/echo" } service echo03 on listener03 { @http:ResourceConfig { methods: ["GET"], - path: "/test", auth: { - scopes: ["scope2", "scope4"] + enabled: true, + scopes: ["scope4"] } } - resource function echo(http:Caller caller, http:Request req) { + resource function test(http:Caller caller, http:Request req) { checkpanic caller->respond(()); } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_resource_level_auth_config_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_service_level_auth_config_test.bal similarity index 78% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/04_resource_level_auth_config_test.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/04_service_level_auth_config_test.bal index ab1274e2f3f4..d11a1eac73d1 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_resource_level_auth_config_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_service_level_auth_config_test.bal @@ -33,19 +33,26 @@ listener http:Listener listener04 = new(9093, config = { }); @http:ServiceConfig { - basePath: "/echo" + basePath: "/echo", + auth: { + enabled: true, + scopes: ["scope2"] + } } service echo04 on listener04 { + @http:ResourceConfig { + methods: ["GET"] + } + resource function test(http:Caller caller, http:Request req) { + checkpanic caller->respond(()); + } + @http:ResourceConfig { methods: ["GET"], - path: "/test", - auth: { - enabled: true, - scopes: ["scope2"] - } + path: "/path/{id}" } - resource function echo(http:Caller caller, http:Request req) { + resource function path(http:Caller caller, http:Request req, string id) { checkpanic caller->respond(()); } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_service_level_auth_config_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_auth_test_without_annotations_test.bal similarity index 73% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/05_service_level_auth_config_test.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/05_auth_test_without_annotations_test.bal index 5d58e0f40e26..49b80be39c06 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_service_level_auth_config_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_auth_test_without_annotations_test.bal @@ -33,27 +33,11 @@ listener http:Listener listener05 = new(9094, config = { }); @http:ServiceConfig { - basePath: "/echo", - auth: { - enabled: true, - scopes: ["scope2"] - } + basePath: "/echo" } service echo05 on listener05 { - @http:ResourceConfig { - methods: ["GET"], - path: "/test" - } - resource function echo(http:Caller caller, http:Request req) { - checkpanic caller->respond(()); - } - - @http:ResourceConfig { - methods: ["GET"], - path: "/path/{id}" - } - resource function path(http:Caller caller, http:Request req, string id) { + resource function test(http:Caller caller, http:Request req) { checkpanic caller->respond(()); } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_multiple_providers.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/06_authn_with_multiple_handlers.bal similarity index 74% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_multiple_providers.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/06_authn_with_multiple_handlers.bal index c11329c10447..01f9ec9c6937 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_multiple_providers.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/06_authn_with_multiple_handlers.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -auth:JWTAuthProvider jwtAuthProvider08_1 = new({ +auth:JWTAuthProvider jwtAuthProvider06_1 = new({ issuer: "example1", audience: ["ballerina"], certificateAlias: "ballerina", @@ -27,7 +27,7 @@ auth:JWTAuthProvider jwtAuthProvider08_1 = new({ } }); -auth:JWTAuthProvider jwtAuthProvider08_2 = new({ +auth:JWTAuthProvider jwtAuthProvider06_2 = new({ issuer: "example2", audience: ["ballerina"], certificateAlias: "ballerina", @@ -38,12 +38,12 @@ auth:JWTAuthProvider jwtAuthProvider08_2 = new({ }); -http:JwtAuthnHandler jwtAuthnHandler08_1 = new(jwtAuthProvider08_1); -http:JwtAuthnHandler jwtAuthnHandler08_2 = new(jwtAuthProvider08_2); +http:JwtAuthnHandler jwtAuthnHandler06_1 = new(jwtAuthProvider06_1); +http:JwtAuthnHandler jwtAuthnHandler06_2 = new(jwtAuthProvider06_2); -listener http:Listener listener08 = new(9099, config = { +listener http:Listener listener06 = new(9095, config = { auth: { - authnHandlers: [jwtAuthnHandler08_1, jwtAuthnHandler08_2] + authnHandlers: [jwtAuthnHandler06_1, jwtAuthnHandler06_2] }, secureSocket: { keyStore: { @@ -53,9 +53,12 @@ listener http:Listener listener08 = new(9099, config = { } }); -service echo8 on listener08 { +@http:ServiceConfig { + basePath: "/echo" +} +service echo06 on listener06 { - resource function test8(http:Caller caller, http:Request req) { + resource function test(http:Caller caller, http:Request req) { checkpanic caller->respond(()); } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_auth_test_without_annotations.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_auth_test_without_annotations.bal deleted file mode 100644 index ada0ab8b489c..000000000000 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_auth_test_without_annotations.bal +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/auth; -import ballerina/http; - -auth:ConfigAuthStoreProvider basicAuthProvider07 = new; -http:BasicAuthnHandler basicAuthnHandler07 = new(basicAuthProvider07); - -listener http:Listener listener07 = new(9098, config = { - auth: { - authnHandlers: [basicAuthnHandler07] - }, - secureSocket: { - keyStore: { - path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", - password: "ballerina" - } - } -}); - -service echo7 on listener07 { - - resource function test7(http:Caller caller, http:Request req) { - checkpanic caller->respond(()); - } -} diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_different_scopes.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_authn_with_different_scopes_test.bal similarity index 78% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_different_scopes.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/07_authn_with_different_scopes_test.bal index b8fbd24dae3d..7939c4166b07 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_different_scopes.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_authn_with_different_scopes_test.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -auth:JWTAuthProvider jwtAuthProvider09 = new({ +auth:JWTAuthProvider jwtAuthProvider07 = new({ issuer: "ballerina", audience: ["ballerina"], certificateAlias: "ballerina", @@ -27,11 +27,11 @@ auth:JWTAuthProvider jwtAuthProvider09 = new({ } }); -http:JwtAuthnHandler jwtAuthnHandler09 = new(jwtAuthProvider09); +http:JwtAuthnHandler jwtAuthnHandler07 = new(jwtAuthProvider07); -listener http:Listener listener09 = new(9100, config = { +listener http:Listener listener07 = new(9096, config = { auth: { - authnHandlers: [jwtAuthnHandler09] + authnHandlers: [jwtAuthnHandler07] }, secureSocket: { keyStore: { @@ -42,13 +42,14 @@ listener http:Listener listener09 = new(9100, config = { }); @http:ServiceConfig { + basePath: "/echo", auth: { scopes: ["test-scope"] } } -service echo9 on listener09 { +service echo07 on listener07 { - resource function test9(http:Caller caller, http:Request req) { + resource function test(http:Caller caller, http:Request req) { checkpanic caller->respond(()); } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_authn_with_expired_certificate.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_expired_certificate_test.bal similarity index 76% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/13_authn_with_expired_certificate.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_expired_certificate_test.bal index 5693c3882f22..bff30103cfc3 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_authn_with_expired_certificate.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_expired_certificate_test.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -auth:JWTAuthProvider jwtAuthProvider13 = new({ +auth:JWTAuthProvider jwtAuthProvider08 = new({ issuer:"ballerina", audience: ["ballerina.io"], certificateAlias: "cert", @@ -27,11 +27,11 @@ auth:JWTAuthProvider jwtAuthProvider13 = new({ } }); -http:JwtAuthnHandler jwtAuthnHandler13 = new(jwtAuthProvider13); +http:JwtAuthnHandler jwtAuthnHandler08 = new(jwtAuthProvider08); -listener http:Listener listener13 = new(9101, config = { +listener http:Listener listener08 = new(9097, config = { auth: { - authnHandlers: [jwtAuthnHandler13] + authnHandlers: [jwtAuthnHandler08] }, secureSocket: { keyStore: { @@ -41,9 +41,12 @@ listener http:Listener listener13 = new(9101, config = { } }); -service echo13 on listener13 { +@http:ServiceConfig { + basePath: "/echo" +} +service echo08 on listener08 { - resource function test13 (http:Caller caller, http:Request req) { + resource function test(http:Caller caller, http:Request req) { checkpanic caller -> respond(()); } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_authn_with_expired_certificate_with_no_expiry_validation.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_expired_certificate_with_no_expiry_validation.bal similarity index 77% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/14_authn_with_expired_certificate_with_no_expiry_validation.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_expired_certificate_with_no_expiry_validation.bal index e5a9963c3d1b..f7e965ef2bd5 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_authn_with_expired_certificate_with_no_expiry_validation.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_expired_certificate_with_no_expiry_validation.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -auth:JWTAuthProvider jwtAuthProvider14 = new({ +auth:JWTAuthProvider jwtAuthProvider09 = new({ issuer:"ballerina", audience: ["ballerina.io"], certificateAlias: "cert", @@ -28,11 +28,11 @@ auth:JWTAuthProvider jwtAuthProvider14 = new({ } }); -http:JwtAuthnHandler jwtAuthnHandler14 = new(jwtAuthProvider14); +http:JwtAuthnHandler jwtAuthnHandler09 = new(jwtAuthProvider09); -listener http:Listener listener14 = new(9102, config = { +listener http:Listener listener09 = new(9098, config = { auth: { - authnHandlers: [jwtAuthnHandler14] + authnHandlers: [jwtAuthnHandler09] }, secureSocket: { keyStore: { @@ -42,9 +42,12 @@ listener http:Listener listener14 = new(9102, config = { } }); -service echo14 on listener14 { +@http:ServiceConfig { + basePath: "/echo" +} +service echo09 on listener09 { - resource function test14 (http:Caller caller, http:Request req) { + resource function test(http:Caller caller, http:Request req) { checkpanic caller -> respond(()); } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal index 5954701aeada..7269bf3a70b7 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal @@ -21,7 +21,7 @@ import ballerina/http; auth:ConfigAuthStoreProvider basicAuthProvider10 = new; http:BasicAuthnHandler basicAuthnHandler10 = new(basicAuthProvider10); -listener http:Listener listener10_1 = new(9190, config = { +listener http:Listener listener10_1 = new(9099, config = { auth: { authnHandlers: [basicAuthnHandler10] }, @@ -34,10 +34,10 @@ listener http:Listener listener10_1 = new(9190, config = { }); // client will not propagate JWT -http:Client nyseEP = new("https://localhost:9195"); +http:Client nyseEP = new("https://localhost:9100"); @http:ServiceConfig { basePath: "/passthrough" } -service passthroughService on listener10_1 { +service passthroughService10 on listener10_1 { @http:ResourceConfig { methods: ["GET"], @@ -69,7 +69,7 @@ auth:JWTAuthProvider jwtAuthProvider10 = new({ http:JwtAuthnHandler jwtAuthnHandler10 = new(jwtAuthProvider10); -listener http:Listener listener10_2 = new(9195, config = { +listener http:Listener listener10_2 = new(9100, config = { auth: { authnHandlers: [jwtAuthnHandler10] }, @@ -82,7 +82,7 @@ listener http:Listener listener10_2 = new(9195, config = { }); @http:ServiceConfig { basePath: "/nyseStock" } -service nyseStockQuote on listener10_2 { +service nyseStockQuote10 on listener10_2 { @http:ResourceConfig { methods: ["GET"], diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal index 180b2a26774e..b6f47ab7c78b 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal @@ -20,7 +20,7 @@ import ballerina/http; auth:ConfigAuthStoreProvider basicAuthProvider11 = new; http:BasicAuthnHandler basicAuthnHandler11 = new(basicAuthProvider11); -listener http:Listener listener11 = new(9192, config = { +listener http:Listener listener11_1 = new(9101, config = { auth: { authnHandlers: [basicAuthnHandler11] }, @@ -32,7 +32,7 @@ listener http:Listener listener11 = new(9192, config = { } }); -http:Client nyseEP03 = new("https://localhost:9193", config = { +http:Client nyseEP03 = new("https://localhost:9102", config = { auth: { scheme: http:JWT_AUTH, config: { @@ -51,7 +51,7 @@ http:Client nyseEP03 = new("https://localhost:9193", config = { }); @http:ServiceConfig { basePath: "/passthrough" } -service passthroughService03 on listener11 { +service passthroughService11 on listener11_1 { @http:ResourceConfig { methods: ["GET"], @@ -83,7 +83,7 @@ auth:JWTAuthProvider jwtAuthProvider11 = new({ http:JwtAuthnHandler jwtAuthnHandler11 = new(jwtAuthProvider11); -listener http:Listener listener2 = new(9193, config = { +listener http:Listener listener11_2 = new(9102, config = { auth: { authnHandlers: [jwtAuthnHandler11] }, @@ -96,7 +96,7 @@ listener http:Listener listener2 = new(9193, config = { }); @http:ServiceConfig { basePath: "/nyseStock" } -service nyseStockQuote03 on listener2 { +service nyseStockQuote11 on listener11_2 { @http:ResourceConfig { methods: ["GET"], diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_secure_service_wrong_provider_id_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_secure_service_wrong_provider_id_test.bal deleted file mode 100644 index afc18dcf86db..000000000000 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_secure_service_wrong_provider_id_test.bal +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/auth; -import ballerina/http; - -auth:ConfigAuthStoreProvider basicAuthProvider12_1 = new; -auth:ConfigAuthStoreProvider basicAuthProvider12_2 = new; -http:BasicAuthnHandler basicAuthnHandler12_1 = new(basicAuthProvider12_1); -http:BasicAuthnHandler basicAuthnHandler12_2 = new(basicAuthProvider12_2); - -listener http:Listener listener12 = new(9194, config = { - auth: { - authnHandlers: [basicAuthnHandler12_1] - }, - secureSocket: { - keyStore: { - path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", - password: "ballerina" - } - } -}); - -@http:ServiceConfig { - basePath: "/echo", - auth: { - authnHandlers: [basicAuthnHandler12_2], - enabled: true, - scopes: ["scope2"] - } -} -service echo12 on listener12 { - - @http:ResourceConfig { - methods: ["GET"], - path: "/test" - } - resource function echo(http:Caller caller, http:Request req) { - checkpanic caller->respond(()); - } -} \ No newline at end of file diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_token_propagation_jwt_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_token_propagation_jwt_test.bal similarity index 79% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/15_token_propagation_jwt_test.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/12_token_propagation_jwt_test.bal index 9cd7a026f6d8..70442ff804a7 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_token_propagation_jwt_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_token_propagation_jwt_test.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -auth:JWTAuthProvider jwtAuthProvider15_1 = new({ +auth:JWTAuthProvider jwtAuthProvider12_1 = new({ issuer: "example1", audience: ["ballerina"], certificateAlias: "ballerina", @@ -27,11 +27,11 @@ auth:JWTAuthProvider jwtAuthProvider15_1 = new({ } }); -http:JwtAuthnHandler jwtAuthnHandler15_1 = new(jwtAuthProvider15_1); +http:JwtAuthnHandler jwtAuthnHandler12_1 = new(jwtAuthProvider12_1); -listener http:Listener listener15_1 = new(9103, config = { +listener http:Listener listener12_1 = new(9103, config = { auth: { - authnHandlers: [jwtAuthnHandler15_1] + authnHandlers: [jwtAuthnHandler12_1] }, secureSocket: { keyStore: { @@ -41,21 +41,21 @@ listener http:Listener listener15_1 = new(9103, config = { } }); -http:Client nyseEP15 = new("https://localhost:9104", config = { +http:Client nyseEP12 = new("https://localhost:9104", config = { auth: { scheme: http:JWT_AUTH } }); @http:ServiceConfig { basePath: "/passthrough" } -service passthroughService15 on listener15_1 { +service passthroughService12 on listener12_1 { @http:ResourceConfig { methods: ["GET"], path: "/" } resource function passthrough(http:Caller caller, http:Request clientRequest) { - var response = nyseEP15->get("/nyseStock/stocks", message = untaint clientRequest); + var response = nyseEP12->get("/nyseStock/stocks", message = untaint clientRequest); if (response is http:Response) { checkpanic caller->respond(response); } else { @@ -68,7 +68,7 @@ service passthroughService15 on listener15_1 { } } -auth:JWTAuthProvider jwtAuthProvider15_2 = new({ +auth:JWTAuthProvider jwtAuthProvider12_2 = new({ issuer: "example1", audience: ["ballerina"], certificateAlias: "ballerina", @@ -78,11 +78,11 @@ auth:JWTAuthProvider jwtAuthProvider15_2 = new({ } }); -http:JwtAuthnHandler jwtAuthnHandler15_2 = new(jwtAuthProvider15_2); +http:JwtAuthnHandler jwtAuthnHandler12_2 = new(jwtAuthProvider12_2); -listener http:Listener listener15_2 = new(9104, config = { +listener http:Listener listener12_2 = new(9104, config = { auth: { - authnHandlers: [jwtAuthnHandler15_2] + authnHandlers: [jwtAuthnHandler12_2] }, secureSocket: { keyStore: { @@ -93,7 +93,7 @@ listener http:Listener listener15_2 = new(9104, config = { }); @http:ServiceConfig { basePath: "/nyseStock" } -service nyseStockQuote15 on listener15_2 { +service nyseStockQuote12 on listener12_2 { @http:ResourceConfig { methods: ["GET"], diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_token_propagation_jwt_reissuing_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_token_propagation_jwt_reissuing_test.bal similarity index 82% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/16_token_propagation_jwt_reissuing_test.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/13_token_propagation_jwt_reissuing_test.bal index ff4fbd4bd67a..2358635e7972 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_token_propagation_jwt_reissuing_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_token_propagation_jwt_reissuing_test.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -auth:JWTAuthProvider jwtAuthProvider16_1 = new({ +auth:JWTAuthProvider jwtAuthProvider13_1 = new({ issuer: "example1", audience: ["ballerina"], certificateAlias: "ballerina", @@ -27,11 +27,11 @@ auth:JWTAuthProvider jwtAuthProvider16_1 = new({ } }); -http:JwtAuthnHandler jwtAuthnHandler16_1 = new(jwtAuthProvider16_1); +http:JwtAuthnHandler jwtAuthnHandler13_1 = new(jwtAuthProvider13_1); -listener http:Listener listener16_1 = new(9105, config = { +listener http:Listener listener13_1 = new(9105, config = { auth: { - authnHandlers: [jwtAuthnHandler16_1] + authnHandlers: [jwtAuthnHandler13_1] }, secureSocket: { keyStore: { @@ -41,7 +41,7 @@ listener http:Listener listener16_1 = new(9105, config = { } }); -http:Client nyseEP16 = new("https://localhost:9106", config = { +http:Client nyseEP13 = new("https://localhost:9106", config = { auth: { scheme: http:JWT_AUTH, config: { @@ -60,14 +60,14 @@ http:Client nyseEP16 = new("https://localhost:9106", config = { }); @http:ServiceConfig { basePath: "/passthrough" } -service passthroughService16 on listener16_1 { +service passthroughService13 on listener13_1 { @http:ResourceConfig { methods: ["GET"], path: "/" } resource function passthrough(http:Caller caller, http:Request clientRequest) { - var response = nyseEP16->get("/nyseStock/stocks", message = untaint clientRequest); + var response = nyseEP13->get("/nyseStock/stocks", message = untaint clientRequest); if (response is http:Response) { checkpanic caller->respond(response); } else { @@ -80,7 +80,7 @@ service passthroughService16 on listener16_1 { } } -auth:JWTAuthProvider jwtAuthProvider16_2 = new({ +auth:JWTAuthProvider jwtAuthProvider13_2 = new({ issuer: "example2", audience: ["ballerina"], certificateAlias: "ballerina", @@ -90,11 +90,11 @@ auth:JWTAuthProvider jwtAuthProvider16_2 = new({ } }); -http:JwtAuthnHandler jwtAuthnHandler16_2 = new(jwtAuthProvider16_2); +http:JwtAuthnHandler jwtAuthnHandler13_2 = new(jwtAuthProvider13_2); -listener http:Listener listener16_2 = new(9106, config = { +listener http:Listener listener13_2 = new(9106, config = { auth: { - authnHandlers: [jwtAuthnHandler16_2] + authnHandlers: [jwtAuthnHandler13_2] }, secureSocket: { keyStore: { @@ -105,7 +105,7 @@ listener http:Listener listener16_2 = new(9106, config = { }); @http:ServiceConfig { basePath: "/nyseStock" } -service nyseStockQuote16 on listener16_2 { +service nyseStockQuote13 on listener13_2 { @http:ResourceConfig { methods: ["GET"], diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_token_propagation_jwt_reissuing_negative_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_token_propagation_jwt_reissuing_negative_test.bal similarity index 82% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/17_token_propagation_jwt_reissuing_negative_test.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/14_token_propagation_jwt_reissuing_negative_test.bal index 70957d228069..22fd72a3e1e1 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_token_propagation_jwt_reissuing_negative_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_token_propagation_jwt_reissuing_negative_test.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -auth:JWTAuthProvider jwtAuthProvider17_1 = new({ +auth:JWTAuthProvider jwtAuthProvider14_1 = new({ issuer: "example1", audience: ["ballerina"], certificateAlias: "ballerina", @@ -27,11 +27,11 @@ auth:JWTAuthProvider jwtAuthProvider17_1 = new({ } }); -http:JwtAuthnHandler jwtAuthnHandler17_1 = new(jwtAuthProvider17_1); +http:JwtAuthnHandler jwtAuthnHandler14_1 = new(jwtAuthProvider14_1); -listener http:Listener listener17_1 = new(9107, config = { +listener http:Listener listener14_1 = new(9107, config = { auth: { - authnHandlers: [jwtAuthnHandler17_1] + authnHandlers: [jwtAuthnHandler14_1] }, secureSocket: { keyStore: { @@ -41,7 +41,7 @@ listener http:Listener listener17_1 = new(9107, config = { } }); -http:Client nyseEP17 = new("https://localhost:9108", config = { +http:Client nyseEP14 = new("https://localhost:9108", config = { auth: { scheme: http:JWT_AUTH, config: { @@ -60,14 +60,14 @@ http:Client nyseEP17 = new("https://localhost:9108", config = { }); @http:ServiceConfig { basePath: "/passthrough" } -service passthroughService17 on listener17_1 { +service passthroughService14 on listener14_1 { @http:ResourceConfig { methods: ["GET"], path: "/" } resource function passthrough(http:Caller caller, http:Request clientRequest) { - var response = nyseEP17->get("/nyseStock/stocks", message = untaint clientRequest); + var response = nyseEP14->get("/nyseStock/stocks", message = untaint clientRequest); if (response is http:Response) { checkpanic caller->respond(response); } else { @@ -80,7 +80,7 @@ service passthroughService17 on listener17_1 { } } -auth:JWTAuthProvider jwtAuthProvider17_2 = new({ +auth:JWTAuthProvider jwtAuthProvider14_2 = new({ issuer: "example2aaaaaaaaaaaaaa", audience: ["ballerina"], certificateAlias: "ballerina", @@ -90,11 +90,11 @@ auth:JWTAuthProvider jwtAuthProvider17_2 = new({ } }); -http:JwtAuthnHandler jwtAuthnHandler17_2 = new(jwtAuthProvider17_2); +http:JwtAuthnHandler jwtAuthnHandler14_2 = new(jwtAuthProvider14_2); -listener http:Listener listener17_2 = new(9108, config = { +listener http:Listener listener14_2 = new(9108, config = { auth: { - authnHandlers: [jwtAuthnHandler17_2] + authnHandlers: [jwtAuthnHandler14_2] }, secureSocket: { keyStore: { @@ -105,7 +105,7 @@ listener http:Listener listener17_2 = new(9108, config = { }); @http:ServiceConfig { basePath: "/nyseStock" } -service nyseStockQuote17 on listener17_2 { +service nyseStockQuote14 on listener14_2 { @http:ResourceConfig { methods: ["GET"], diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_ldap_auth_store_test.bal similarity index 98% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_test.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/15_ldap_auth_store_test.bal index 518dd4545c34..d06bfbb60c11 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_ldap_auth_store_test.bal @@ -43,7 +43,7 @@ auth:LdapAuthStoreProviderConfig ldapConfig02 = { auth:LdapAuthStoreProvider ldapAuthStoreProvider02 = new(ldapConfig02, "ldap01"); http:BasicAuthnHandler ldapAuthnHandler02 = new(ldapAuthStoreProvider02); -listener http:Listener ep = new(9096, config = { +listener http:Listener ep = new(9109, config = { auth: { authnHandlers: [ldapAuthnHandler02] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_authorization_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_ldap_auth_store_authz_test.bal similarity index 97% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_authorization_test.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/16_ldap_auth_store_authz_test.bal index e0abe792c258..50feef3562a6 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/ldap_auth_store_authorization_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_ldap_auth_store_authz_test.bal @@ -43,7 +43,7 @@ auth:LdapAuthStoreProviderConfig ldapConfig01 = { auth:LdapAuthStoreProvider ldapAuthStoreProvider01 = new(ldapConfig01, "ldap01"); http:BasicAuthnHandler ldapAuthnHandler01 = new(ldapAuthStoreProvider01); -listener http:Listener authEP = new(9097, config = { +listener http:Listener authEP = new(9110, config = { auth: { authnHandlers: [ldapAuthnHandler01] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/06_mock-oauth-service.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/mock-oauth-service.bal similarity index 99% rename from tests/ballerina-integration-test/src/test/resources/auth/authservices/06_mock-oauth-service.bal rename to tests/ballerina-integration-test/src/test/resources/auth/authservices/mock-oauth-service.bal index 152360fa17e5..a29022bb0b06 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/06_mock-oauth-service.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/mock-oauth-service.bal @@ -369,7 +369,7 @@ function addToAccessTokenStore(string accessToken) { //The API endpoint, which is responsible for processing the request after validating the access token in the authorization header. // The token should be listed in the accessTokenStore, which keeps the tokens issued by the mock OAuth2 server. -listener http:Listener apiEndpoint = new(9095, config = { +listener http:Listener apiEndpoint = new(9195, config = { secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", diff --git a/tests/ballerina-integration-test/src/test/resources/auth/ballerina.conf b/tests/ballerina-integration-test/src/test/resources/auth/ballerina.conf index 31cf435f1d6b..d27ffee93685 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/ballerina.conf +++ b/tests/ballerina-integration-test/src/test/resources/auth/ballerina.conf @@ -2,8 +2,8 @@ ["b7a.users.isuru"] password="xxx" -scopes="scope2" +scopes="scope4" ["b7a.users.ishara"] password="abc" -scopes="scope1" +scopes="scope1,scope2,scope3" diff --git a/tests/ballerina-integration-test/src/test/resources/testng.xml b/tests/ballerina-integration-test/src/test/resources/testng.xml index eae8e09e66ab..9c4c01ad6f48 100644 --- a/tests/ballerina-integration-test/src/test/resources/testng.xml +++ b/tests/ballerina-integration-test/src/test/resources/testng.xml @@ -102,17 +102,15 @@ - + + + + + - - - - - - From 5af73b8ef687e5cad3859c4f4361384166245cbd Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Mon, 15 Apr 2019 16:27:57 +0530 Subject: [PATCH 21/52] Fix a bug in bbe --- .../secured_client_with_basic_auth.bal | 4 ++-- .../secured_client_with_jwt_auth.bal | 8 ++++++-- .../secured_service_with_basic_auth.bal | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal b/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal index 38124fc2e378..3c7939d6d737 100644 --- a/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal +++ b/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal @@ -31,13 +31,13 @@ public function main() { } } -// Create a basic authentication provider with the relevant configurations. +// Create a basic authentication handler with the relevant configurations. auth:ConfigAuthStoreProvider basicAuthProvider = new; http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); listener http:Listener ep = new(9090, config = { auth: { - authnHandlers: [basicAuthProvider] + authnHandlers: [basicAuthnHandler] }, secureSocket: { keyStore: { diff --git a/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal b/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal index c594ca3d6e33..acbc1e3affcb 100644 --- a/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal +++ b/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal @@ -38,7 +38,8 @@ public function main() { } } -// Create a JWT authentication provider with the relevant configurations. +// Create a JWT authentication provider with the relevant configuration +// parameters. auth:JWTAuthProvider jwtAuthProvider = new({ issuer: "ballerina", audience: ["ballerina.io"], @@ -49,9 +50,12 @@ auth:JWTAuthProvider jwtAuthProvider = new({ } }); +// Create a JWT authentication handler with the created JWT auth provider +http:JwtAuthnHandler jwtAuthnHandler = new(jwtAuthProvider); + listener http:Listener ep = new(9090, config = { auth: { - authnHandlers: [jwtAuthProvider] + authnHandlers: [jwtAuthnHandler] }, secureSocket: { keyStore: { diff --git a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal index b9c3f64418c0..5e419620c5f2 100644 --- a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal +++ b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal @@ -13,7 +13,7 @@ http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); // resource level. listener http:Listener ep = new(9090, config = { auth: { - authnHandlers: [basicAuthProvider] + authnHandlers: [basicAuthnHandler] }, // The secure hello world sample uses https. secureSocket: { From 078b2ce22d6a2d2751e9140d24b7e9bbfafab6c2 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Wed, 17 Apr 2019 10:21:55 +0530 Subject: [PATCH 22/52] Fix lang server test cases --- .../source/testgen/module2/services.bal | 46 +++++++++---------- .../testGenerationForServicesNegative.json | 4 +- .../defExpressionConnectorInit.json | 6 +-- .../resources/definition/sources/defFl17.bal | 17 +++---- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/language-server/modules/langserver-core/src/test/resources/command/source/testgen/module2/services.bal b/language-server/modules/langserver-core/src/test/resources/command/source/testgen/module2/services.bal index 9f92d6b7c5e3..dec1205bb269 100644 --- a/language-server/modules/langserver-core/src/test/resources/command/source/testgen/module2/services.bal +++ b/language-server/modules/langserver-core/src/test/resources/command/source/testgen/module2/services.bal @@ -1,6 +1,6 @@ +import ballerina/auth; import ballerina/http; import ballerina/io; -import ballerina/websub; service httpService on new http:Listener(9090) { resource function sayHello(http:Caller caller, http:Request request) { @@ -32,32 +32,32 @@ service wssService on securedListener2 { } } -http:AuthProvider basicAuthProvider = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +auth:ConfigAuthStoreProvider basicAuthProvider1 = new; +auth:ConfigAuthStoreProvider basicAuthProvider2 = new; -http:AuthProvider basicAuthProvider2 = { - scheme: http:BASIC_AUTH, - authStoreProvider: http:CONFIG_AUTH_STORE -}; +http:BasicAuthnHandler basicAuthnHandler1 = new(basicAuthProvider1); +http:BasicAuthnHandler basicAuthnHandler2 = new(basicAuthProvider2); listener http:Listener securedListener = new(9090, config = { - authProviders: [basicAuthProvider], - secureSocket: { - keyStore: { - path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", - password: "ballerina" + auth: { + authnHandlers: [basicAuthnHandler1] + }, + secureSocket: { + keyStore: { + path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", + password: "ballerina" + } } - } -}); + }); listener http:WebSocketListener securedListener2 = new(9090, config = { - authProviders: [basicAuthProvider], - secureSocket: { - keyStore: { - path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", - password: "ballerina" + auth: { + authnHandlers: [basicAuthnHandler2] + }, + secureSocket: { + keyStore: { + path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", + password: "ballerina" + } } - } -}); + }); diff --git a/language-server/modules/langserver-core/src/test/resources/command/testGenerationForServicesNegative.json b/language-server/modules/langserver-core/src/test/resources/command/testGenerationForServicesNegative.json index 544e5801c09f..ef6282b38404 100644 --- a/language-server/modules/langserver-core/src/test/resources/command/testGenerationForServicesNegative.json +++ b/language-server/modules/langserver-core/src/test/resources/command/testGenerationForServicesNegative.json @@ -2,8 +2,8 @@ "cases": [ { "arguments": { - "node.line": 34, - "node.column": 20 + "node.line": 35, + "node.column": 30 }, "expected": { "imports": [], diff --git a/language-server/modules/langserver-core/src/test/resources/definition/expected/expression/defExpressionConnectorInit.json b/language-server/modules/langserver-core/src/test/resources/definition/expected/expression/defExpressionConnectorInit.json index 15386f51c572..1c1885f0c9a7 100644 --- a/language-server/modules/langserver-core/src/test/resources/definition/expected/expression/defExpressionConnectorInit.json +++ b/language-server/modules/langserver-core/src/test/resources/definition/expected/expression/defExpressionConnectorInit.json @@ -3,7 +3,7 @@ "file": "defFl17.bal" }, "position": { - "line": 17, + "line": 15, "character": 43 }, "result": [ @@ -11,11 +11,11 @@ "uri": "defFl17.bal", "range": { "start": { - "line": 2, + "line": 3, "character": 4 }, "end": { - "line": 2, + "line": 3, "character": 8 } } diff --git a/language-server/modules/langserver-core/src/test/resources/definition/sources/defFl17.bal b/language-server/modules/langserver-core/src/test/resources/definition/sources/defFl17.bal index 44be82a3c0e8..7c37053d7066 100644 --- a/language-server/modules/langserver-core/src/test/resources/definition/sources/defFl17.bal +++ b/language-server/modules/langserver-core/src/test/resources/definition/sources/defFl17.bal @@ -1,12 +1,10 @@ +import ballerina/auth; import ballerina/http; int port = 9090; -http:AuthProvider basicAuthProvider = { - id: "", - scheme: "BASIC_AUTH", - authStoreProvider: "CONFIG_AUTH_STORE" -}; +auth:ConfigAuthStoreProvider basicAuthProvider = new; +http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); http:ServiceSecureSocket secureSocket = { keyStore: { @@ -15,6 +13,9 @@ http:ServiceSecureSocket secureSocket = { } }; -listener http:Listener apiListener = new(port, config = { authProviders: [basicAuthProvider], - secureSocket: secureSocket }); - +listener http:Listener apiListener = new(port, config = { + auth: { + authnHandlers: [basicAuthnHandler] + }, + secureSocket: secureSocket + }); From 09f77b614f3f89e84673185584a8a72b7a206940 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Wed, 17 Apr 2019 14:13:59 +0530 Subject: [PATCH 23/52] Fix lang server test cases --- .../expected/expression/defExpressionNamedArgs.json | 10 +++++----- .../src/test/resources/definition/sources/defFl17.bal | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/language-server/modules/langserver-core/src/test/resources/definition/expected/expression/defExpressionNamedArgs.json b/language-server/modules/langserver-core/src/test/resources/definition/expected/expression/defExpressionNamedArgs.json index 39dc36101acc..183efa75e821 100644 --- a/language-server/modules/langserver-core/src/test/resources/definition/expected/expression/defExpressionNamedArgs.json +++ b/language-server/modules/langserver-core/src/test/resources/definition/expected/expression/defExpressionNamedArgs.json @@ -4,19 +4,19 @@ }, "position": { "line": 17, - "character": 83 + "character": 30 }, "result": [ { "uri": "defFl17.bal", "range": { "start": { - "line": 4, - "character": 18 + "line": 6, + "character": 23 }, "end": { - "line": 4, - "character": 35 + "line": 6, + "character": 40 } } } diff --git a/language-server/modules/langserver-core/src/test/resources/definition/sources/defFl17.bal b/language-server/modules/langserver-core/src/test/resources/definition/sources/defFl17.bal index 7c37053d7066..3d0cbd218db9 100644 --- a/language-server/modules/langserver-core/src/test/resources/definition/sources/defFl17.bal +++ b/language-server/modules/langserver-core/src/test/resources/definition/sources/defFl17.bal @@ -14,8 +14,8 @@ http:ServiceSecureSocket secureSocket = { }; listener http:Listener apiListener = new(port, config = { - auth: { - authnHandlers: [basicAuthnHandler] - }, - secureSocket: secureSocket - }); + auth: { + authnHandlers: [basicAuthnHandler] + }, + secureSocket: secureSocket +}); From 33c4e47bf6ffba351170cd671e5b189ebdf6723d Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Wed, 17 Apr 2019 14:37:55 +0530 Subject: [PATCH 24/52] Update markdown file of auth module --- stdlib/auth/src/main/ballerina/auth/Module.md | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/stdlib/auth/src/main/ballerina/auth/Module.md b/stdlib/auth/src/main/ballerina/auth/Module.md index ed0ac46d2e51..9502dd523bac 100644 --- a/stdlib/auth/src/main/ballerina/auth/Module.md +++ b/stdlib/auth/src/main/ballerina/auth/Module.md @@ -1,23 +1,22 @@ ## Module Overview -This module provides a set of default authentication store providers that can be extended to create new authentication store providers. +This module provides a set of default authentication providers that can be extended to create new authentication providers. -### Authentication Store Provider +### Authentication Provider -An authentication store provider defines an authentication scheme that could be used to protect endpoints. The `auth:AuthStoreProvider` type acts as the interface for all the authentication providers. Any type of implementation, such as LDAP, JDBC, and file based, should be object-wise similar. +An authentication provider defines an authentication scheme that could be used to protect endpoints. The `auth:AuthStoreProvider` type acts as the interface for all the authentication providers. Any type of implementation, such as LDAP, JDBC, and file based, should be object-wise similar. -By default, there are three implementations of the `auth:AuthStoreProvider`. They are; the auth:ConfigAuthStoreProvider, - which authenticates based on usernames and passwords stored in a configuration file, the auth:JWTAuthProvider, which - authenticates by validating a JWT, and finally the auth:LdapAuthStoreProvider, which authenticates based on the user +By default, there are three implementations of the `auth:AuthProvider`. They are; the `auth:ConfigAuthStoreProvider`, + which authenticates based on usernames and passwords stored in a configuration file; the `auth:JWTAuthProvider`, which + authenticates by validating a JWT; and finally the `auth:LdapAuthStoreProvider`, which authenticates based on the user credentials stored in an active directory or an LDAP. -When creating a new authentication provider, there are two functions that need to be implemented. +When creating a new authentication provider, there is a function that need to be implemented. - `authenticate` : Authenticates the user based on a credential, which can be username/password, or a token such as JWT. -- `getScopes` : Provides the scopes associated with the user. Scopes are primarily permissions that are required to access a protected resource. ### Config Auth Store Provider -`ConfigAuthStoreProvider` is an implementation of the `AuthStoreProvider` interface, which uses the Ballerina configuration file +`auth:ConfigAuthStoreProvider` is an implementation of the `auth:AuthProvider` interface, which uses the Ballerina configuration file to store usernames, passwords, scopes and the relevant associations. A user is denoted by a section in the configuration file. The password and the scopes assigned to the user are denoted @@ -29,7 +28,10 @@ A user is denoted by a section in the configuration file. The password and the s scopes="" ``` - ### LDAP Auth Store Provider +### LDAP Auth Store Provider -`LdapAuthStoreProvider` is another implementation of the `AuthStoreProvider` interface, which connects to an active -directory or an LDAP to retrieve the necessary user information to perform authentication and authorization. +`auth:LdapAuthStoreProvider` is another implementation of the `auth:AuthProvider` interface, which connects to an active directory or an LDAP to retrieve the necessary user information to perform authentication and authorization. + +### JWT Auth Provider + +`auth:JWTAuthProvider` is another implementation of the `auth:AuthProvider` interface, which authenticate by validating a JWT. From 20b7585e1257a1831a7cdd274f24c7060b14003b Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 18 Apr 2019 14:08:20 +0530 Subject: [PATCH 25/52] Improve integration tests --- .../ballerinalang/test/auth/AuthBaseTest.java | 2 +- .../auth/AuthnWithMultipleHandlersTest.java | 2 +- .../auth/AuthnWithoutHTTPAnnotationsTest.java | 2 +- .../test/auth/AuthzCacheTest.java | 2 +- .../test/auth/AuthzConfigInheritanceTest.java | 238 +++++++++++++++--- .../test/auth/LdapAuthStoreTest.java | 4 +- .../test/auth/ResourceLevelAuthTest.java | 2 +- .../test/auth/ServiceLevelAuthnTest.java | 36 ++- .../test/auth/TokenPropagationTest.java | 10 +- .../02_authz_config_inheritance_test.bal | 33 ++- .../03_resource_level_auth_config_test.bal | 2 +- .../04_service_level_auth_config_test.bal | 12 +- .../05_auth_test_without_annotations_test.bal | 2 +- .../06_authn_with_multiple_handlers.bal | 2 +- .../07_authn_with_different_scopes_test.bal | 2 +- ...08_authn_with_expired_certificate_test.bal | 2 +- ..._certificate_with_no_expiry_validation.bal | 2 +- .../10_token_propagation_disabled_test.bal | 6 +- .../11_token_propagation_basic_auth_test.bal | 6 +- .../12_token_propagation_jwt_test.bal | 6 +- ...3_token_propagation_jwt_reissuing_test.bal | 6 +- ...ropagation_jwt_reissuing_negative_test.bal | 6 +- .../authservices/15_ldap_auth_store_test.bal | 2 +- .../16_ldap_auth_store_authz_test.bal | 2 +- 24 files changed, 309 insertions(+), 80 deletions(-) diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java index 68153a4b8c99..d4e452a9e5b3 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java @@ -37,7 +37,7 @@ public class AuthBaseTest extends BaseTest { @BeforeGroups(value = "auth-test", alwaysRun = true) public void start() throws Exception { int[] requiredPorts = new int[]{9090, 9091, 9092, 9093, 9094, 9095, 9096, 9097, 9098, 9099, 9100, 9101, 9102, - 9103, 9104, 9105, 9106, 9107, 9108, 9109, 9110, 9195, 9196}; + 9103, 9104, 9105, 9106, 9107, 9108, 9109, 9110, 9111, 9112, 9195, 9196}; embeddedDirectoryServer = new EmbeddedDirectoryServer(); embeddedDirectoryServer.startLdapServer(9389); diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java index 11dcc08d5333..0e722e36253c 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java @@ -36,7 +36,7 @@ @Test(groups = "auth-test") public class AuthnWithMultipleHandlersTest extends AuthBaseTest { - private final int servicePort = 9095; + private final int servicePort = 9097; @Test(description = "Authn success test case with example1 issuer") public void testAuthSuccessWithExample1Issuer() throws Exception { diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java index 8fb0d0f6f0c9..6452d388d694 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java @@ -37,7 +37,7 @@ @Test(groups = "auth-test") public class AuthnWithoutHTTPAnnotationsTest extends AuthBaseTest { - private final int servicePort = 9094; + private final int servicePort = 9096; @Test(description = "Authn and authz success test case") public void testAuthSuccess() throws Exception { diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java index d589f9e479c9..4a77dbb67ef7 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java @@ -36,7 +36,7 @@ @Test(groups = "auth-test") public class AuthzCacheTest extends AuthBaseTest { - private final int servicePort = 9096; + private final int servicePort = 9098; @Test(description = "Authn success test case with example1 issuer") public void testAuthCache() throws Exception { diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java index ddd8d32ce91a..74bc71707441 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java @@ -32,93 +32,275 @@ @Test(groups = "auth-test") public class AuthzConfigInheritanceTest extends AuthBaseTest { - private final int servicePort = 9091; + private final int servicePort1 = 9091; + private final int servicePort2 = 9092; + private final int servicePort3 = 9093; - @Test(description = "Service level valid scopes and resource level valid scopes test case") - public void testValidAuthHeaders1() throws Exception { + @Test(description = "Listener - valid scopes, service - valid scopes and resource - valid scopes") + public void testValidScopesAtListener1() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test1"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo1/test1"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); } - @Test(description = "Service level valid scopes and resource level invalid scopes test case") - public void testValidAuthHeaders2() throws Exception { + @Test(description = "Listener - valid scopes, service - valid scopes and resource - invalid scopes") + public void testValidScopesAtListener2() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test2"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo1/test2"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); } - @Test(description = "Service level valid scopes and resource level scopes not given test case") - public void testValidAuthHeaders3() throws Exception { + @Test(description = "Listener - valid scopes, service - valid scopes and resource - scopes not given") + public void testValidScopesAtListener3() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test3"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo1/test3"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); } - @Test(description = "Service level invalid scopes and resource level valid scopes test case") - public void testValidAuthHeaders4() throws Exception { + @Test(description = "Listener - valid scopes, service - invalid scopes and resource - valid scopes") + public void testValidScopesAtListener4() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test1"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo2/test1"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); } - @Test(description = "Service level invalid scopes and resource level invalid scopes test case") - public void testValidAuthHeaders5() throws Exception { + @Test(description = "Listener - valid scopes, service - invalid scopes and resource - invalid scopes") + public void testValidScopesAtListener5() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test2"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo2/test2"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); } - @Test(description = "Service level invalid scopes and resource level scopes not given test case") - public void testValidAuthHeaders6() throws Exception { + @Test(description = "Listener - valid scopes, service - invalid scopes and resource - scopes not given") + public void testValidScopesAtListener6() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test3"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo2/test3"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); } - @Test(description = "Service level scopes not given and resource level valid scopes test case") - public void testValidAuthHeaders7() throws Exception { + @Test(description = "Listener - valid scopes, service - scopes not given and resource - valid scopes") + public void testValidScopesAtListener7() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo3/test1"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo3/test1"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); } - @Test(description = "Service level scopes not given and resource level invalid scopes test case") - public void testValidAuthHeaders8() throws Exception { + @Test(description = "Listener - valid scopes, service - scopes not given and resource - invalid scopes") + public void testValidScopesAtListener8() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo3/test2"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo3/test2"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); } - @Test(description = "Service level scopes not given and resource level scopes not given test case") - public void testValidAuthHeaders9() throws Exception { + @Test(description = "Listener - valid scopes, service - scopes not given and resource - scopes not given") + public void testValidScopesAtListener9() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo3/test3"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo3/test3"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Listener - invalid scopes, service - valid scopes and resource - valid scopes") + public void testInValidScopesAtListener1() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo1/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Listener - invalid scopes, service - valid scopes and resource - invalid scopes") + public void testInValidScopesAtListener2() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo1/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Listener - invalid scopes, service - valid scopes and resource - scopes not given") + public void testInValidScopesAtListener3() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo1/test3"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Listener - invalid scopes, service - invalid scopes and resource - valid scopes") + public void testInValidScopesAtListener4() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo2/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Listener - invalid scopes, service - invalid scopes and resource - invalid scopes") + public void testInValidScopesAtListener5() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo2/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Listener - invalid scopes, service - invalid scopes and resource - scopes not given") + public void testInValidScopesAtListener6() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo2/test3"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Listener - invalid scopes, service - scopes not given and resource - valid scopes") + public void testInValidScopesAtListener7() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo3/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Listener - invalid scopes, service - scopes not given and resource - invalid scopes") + public void testInValidScopesAtListener8() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo3/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Listener - invalid scopes, service - scopes not given and resource - scopes not given") + public void testInValidScopesAtListener9() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo3/test3"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Listener - scopes not given, service - valid scopes and resource - valid scopes") + public void testNotGivenScopesAtListener1() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo1/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Listener - scopes not given, service - valid scopes and resource - invalid scopes") + public void testNotGivenScopesAtListener2() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo1/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Listener - scopes not given, service - valid scopes and resource - scopes not given") + public void testNotGivenScopesAtListener3() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo1/test3"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Listener - scopes not given, service - invalid scopes and resource - valid scopes") + public void testNotGivenScopesAtListener4() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo2/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Listener - scopes not given, service - invalid scopes and resource - invalid scopes") + public void testNotGivenScopesAtListener5() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo2/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Listener - scopes not given, service - invalid scopes and resource - scopes not given") + public void testNotGivenScopesAtListener6() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo2/test3"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Listener - scopes not given, service - scopes not given and resource - valid scopes") + public void testNotGivenScopesAtListener7() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo3/test1"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Listener - scopes not given, service - scopes not given and resource - invalid scopes") + public void testNotGivenScopesAtListener8() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo3/test2"), + headersMap, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Listener - scopes not given, service - scopes not given and resource - scopes not given") + public void testNotGivenScopesAtListener9() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo3/test3"), headersMap, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java index 2a896a8b2632..dc4c623087e5 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java @@ -34,8 +34,8 @@ @Test(groups = "auth-test") public class LdapAuthStoreTest extends AuthBaseTest { - private final int servicePort = 9109; - private final int authzServicePort = 9110; + private final int servicePort = 9111; + private final int authzServicePort = 9112; @Test(description = "Test authenticate and authorize request against ldap auth store") public void testAuthenticationWithInvalidCredentials() throws Exception { diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java index ac810629c2c1..604422c4526a 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java @@ -32,7 +32,7 @@ @Test(groups = "auth-test") public class ResourceLevelAuthTest extends AuthBaseTest { - private final int servicePort = 9092; + private final int servicePort = 9094; @Test(description = "Authn and authz success test case") public void testAuthSuccessWithResourceLevelConfigs() throws Exception { diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java index 7d2bd3fb2920..5eade76a7305 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java @@ -32,9 +32,39 @@ @Test(groups = "auth-test") public class ServiceLevelAuthnTest extends AuthBaseTest { - private final int servicePort = 9093; - private final int servicePortForExpiredCertificateTest = 9097; - private final int servicePortForExpiredCertificateTestWithNoExpiryValidation = 9098; + private final int servicePort = 9095; + private final int servicePortForExpiredCertificateTest = 9099; + private final int servicePortForExpiredCertificateTestWithNoExpiryValidation = 9100; + + @Test(description = "Authn and authz success test case") + public void testAuthSuccessWithServiceLevelConfigs() throws Exception { + Map headers = new HashMap<>(); + headers.put("Authorization", "Basic aXN1cnU6eHh4"); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), + headers, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + @Test(description = "Authn success and authz failure test case") + public void testAuthzFailureWithServiceLevelConfigs() throws Exception { + Map headers = new HashMap<>(); + headers.put("Authorization", "Basic aXNoYXJhOmFiYw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), + headers, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } + + @Test(description = "Authn and authz failure test case") + public void testAuthFailureWithServiceLevelConfigs() throws Exception { + Map headers = new HashMap<>(); + headers.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), + headers, serverInstance.getServerHome()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + } @Test(description = "Auth with JWT signed with expired trusted certificate") public void testAuthnWithJWTSignedWithExpiredTrustedCertificate() throws Exception { diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java index 25a3881aa5b7..5392f42199e6 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java @@ -36,7 +36,7 @@ public class TokenPropagationTest extends AuthBaseTest { public void testTokenPropagationWithBasicAuthInbound() throws Exception { Map headers = new HashMap<>(); headers.put("Authorization", "Basic aXN1cnU6eHh4"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9101, "passthrough"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9103, "passthrough"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); @@ -46,7 +46,7 @@ public void testTokenPropagationWithBasicAuthInbound() throws Exception { public void testWithoutTokenPropagation() throws Exception { Map headers = new HashMap<>(); headers.put("Authorization", "Basic aXN1cnU6eHh4"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9099, "passthrough"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9101, "passthrough"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); @@ -63,7 +63,7 @@ public void testTokenPropagationWithJwtAuthInbound() throws Exception { "ksSeIT9McZxjPiSX1FR-nIUTcJ9anaoQVEKo3OpkIPzd_4_95CpHXF1MaW18ww5h_NShQnUrN7myrBfc-UbHsqC1YEBAM2M-" + "3NMs8jjgcZHfZ1JjomZCjd5eUXz8R5Vl46uAlSbFAmxAfY1T-31qUB93eCL2iJfDc70OK2txohryntw9h-OePwQULJN0Eiwp" + "oI60HQFFlgC1g_crPIDakBTiEITrbO3OzrNeCQFBN-Ji4BTXq97TulCIRNneDLCUBSRE1A"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9103, "passthrough"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9105, "passthrough"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); @@ -80,7 +80,7 @@ public void testTokenPropagationWithJwtAuthInboundAndTokenReissuing() throws Exc "ksSeIT9McZxjPiSX1FR-nIUTcJ9anaoQVEKo3OpkIPzd_4_95CpHXF1MaW18ww5h_NShQnUrN7myrBfc-UbHsqC1YEBAM2M-" + "3NMs8jjgcZHfZ1JjomZCjd5eUXz8R5Vl46uAlSbFAmxAfY1T-31qUB93eCL2iJfDc70OK2txohryntw9h-OePwQULJN0Eiwp" + "oI60HQFFlgC1g_crPIDakBTiEITrbO3OzrNeCQFBN-Ji4BTXq97TulCIRNneDLCUBSRE1A"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9105, "passthrough"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9107, "passthrough"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); @@ -97,7 +97,7 @@ public void testTokenPropagationWithJwtAuthInboundAndTokenReissuingNegative() th "ksSeIT9McZxjPiSX1FR-nIUTcJ9anaoQVEKo3OpkIPzd_4_95CpHXF1MaW18ww5h_NShQnUrN7myrBfc-UbHsqC1YEBAM2M-" + "3NMs8jjgcZHfZ1JjomZCjd5eUXz8R5Vl46uAlSbFAmxAfY1T-31qUB93eCL2iJfDc70OK2txohryntw9h-OePwQULJN0Eiwp" + "oI60HQFFlgC1g_crPIDakBTiEITrbO3OzrNeCQFBN-Ji4BTXq97TulCIRNneDLCUBSRE1A"); - HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9107, "passthrough"), + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9109, "passthrough"), headers, serverInstance.getServerHome()); Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authz_config_inheritance_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authz_config_inheritance_test.bal index 1ad916b02809..f6f918877606 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authz_config_inheritance_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/02_authz_config_inheritance_test.bal @@ -20,7 +20,7 @@ import ballerina/http; auth:ConfigAuthStoreProvider basicAuthProvider02 = new; http:BasicAuthnHandler basicAuthnHandler02 = new(basicAuthProvider02); -listener http:Listener listener02 = new(9091, config = { +listener http:Listener listener02_1 = new(9091, config = { auth: { authnHandlers: [basicAuthnHandler02], scopes: ["scope1"] @@ -33,6 +33,31 @@ listener http:Listener listener02 = new(9091, config = { } }); +listener http:Listener listener02_2 = new(9092, config = { + auth: { + authnHandlers: [basicAuthnHandler02], + scopes: ["scope4"] + }, + secureSocket: { + keyStore: { + path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", + password: "ballerina" + } + } +}); + +listener http:Listener listener02_3 = new(9093, config = { + auth: { + authnHandlers: [basicAuthnHandler02] + }, + secureSocket: { + keyStore: { + path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", + password: "ballerina" + } + } +}); + @http:ServiceConfig { basePath: "/echo1", auth: { @@ -40,7 +65,7 @@ listener http:Listener listener02 = new(9091, config = { scopes: ["scope3"] } } -service echo02_1 on listener02 { +service echo02_1 on listener02_1, listener02_2, listener02_3 { @http:ResourceConfig { methods: ["GET"], @@ -83,7 +108,7 @@ service echo02_1 on listener02 { scopes: ["scope4"] } } -service echo02_2 on listener02 { +service echo02_2 on listener02_1, listener02_2, listener02_3 { @http:ResourceConfig { methods: ["GET"], @@ -125,7 +150,7 @@ service echo02_2 on listener02 { enabled: true } } -service echo02_3 on listener02 { +service echo02_3 on listener02_1, listener02_2, listener02_3 { @http:ResourceConfig { methods: ["GET"], diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_resource_level_auth_config_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_resource_level_auth_config_test.bal index 768c476bc9b0..d6e87b8775f6 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_resource_level_auth_config_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/03_resource_level_auth_config_test.bal @@ -20,7 +20,7 @@ import ballerina/http; auth:ConfigAuthStoreProvider basicAuthProvider03 = new; http:BasicAuthnHandler basicAuthnHandler03 = new(basicAuthProvider03); -listener http:Listener listener03 = new(9092, config = { +listener http:Listener listener03 = new(9094, config = { auth: { authnHandlers: [basicAuthnHandler03] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_service_level_auth_config_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_service_level_auth_config_test.bal index d11a1eac73d1..5891dc3ffdc0 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_service_level_auth_config_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/04_service_level_auth_config_test.bal @@ -20,7 +20,7 @@ import ballerina/http; auth:ConfigAuthStoreProvider basicAuthProvider04 = new; http:BasicAuthnHandler basicAuthnHandler04 = new(basicAuthProvider04); -listener http:Listener listener04 = new(9093, config = { +listener http:Listener listener04 = new(9095, config = { auth: { authnHandlers: [basicAuthnHandler04] }, @@ -36,7 +36,7 @@ listener http:Listener listener04 = new(9093, config = { basePath: "/echo", auth: { enabled: true, - scopes: ["scope2"] + scopes: ["scope4"] } } service echo04 on listener04 { @@ -47,12 +47,4 @@ service echo04 on listener04 { resource function test(http:Caller caller, http:Request req) { checkpanic caller->respond(()); } - - @http:ResourceConfig { - methods: ["GET"], - path: "/path/{id}" - } - resource function path(http:Caller caller, http:Request req, string id) { - checkpanic caller->respond(()); - } } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_auth_test_without_annotations_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_auth_test_without_annotations_test.bal index 49b80be39c06..96263ae35269 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_auth_test_without_annotations_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/05_auth_test_without_annotations_test.bal @@ -20,7 +20,7 @@ import ballerina/http; auth:ConfigAuthStoreProvider basicAuthProvider05 = new; http:BasicAuthnHandler basicAuthnHandler05 = new(basicAuthProvider05); -listener http:Listener listener05 = new(9094, config = { +listener http:Listener listener05 = new(9096, config = { auth: { authnHandlers: [basicAuthnHandler05] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/06_authn_with_multiple_handlers.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/06_authn_with_multiple_handlers.bal index 01f9ec9c6937..03dc47034b23 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/06_authn_with_multiple_handlers.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/06_authn_with_multiple_handlers.bal @@ -41,7 +41,7 @@ auth:JWTAuthProvider jwtAuthProvider06_2 = new({ http:JwtAuthnHandler jwtAuthnHandler06_1 = new(jwtAuthProvider06_1); http:JwtAuthnHandler jwtAuthnHandler06_2 = new(jwtAuthProvider06_2); -listener http:Listener listener06 = new(9095, config = { +listener http:Listener listener06 = new(9097, config = { auth: { authnHandlers: [jwtAuthnHandler06_1, jwtAuthnHandler06_2] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_authn_with_different_scopes_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_authn_with_different_scopes_test.bal index 7939c4166b07..8bc5102d958a 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_authn_with_different_scopes_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/07_authn_with_different_scopes_test.bal @@ -29,7 +29,7 @@ auth:JWTAuthProvider jwtAuthProvider07 = new({ http:JwtAuthnHandler jwtAuthnHandler07 = new(jwtAuthProvider07); -listener http:Listener listener07 = new(9096, config = { +listener http:Listener listener07 = new(9098, config = { auth: { authnHandlers: [jwtAuthnHandler07] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_expired_certificate_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_expired_certificate_test.bal index bff30103cfc3..407f86518139 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_expired_certificate_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/08_authn_with_expired_certificate_test.bal @@ -29,7 +29,7 @@ auth:JWTAuthProvider jwtAuthProvider08 = new({ http:JwtAuthnHandler jwtAuthnHandler08 = new(jwtAuthProvider08); -listener http:Listener listener08 = new(9097, config = { +listener http:Listener listener08 = new(9099, config = { auth: { authnHandlers: [jwtAuthnHandler08] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_expired_certificate_with_no_expiry_validation.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_expired_certificate_with_no_expiry_validation.bal index f7e965ef2bd5..099ad8308467 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_expired_certificate_with_no_expiry_validation.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/09_authn_with_expired_certificate_with_no_expiry_validation.bal @@ -30,7 +30,7 @@ auth:JWTAuthProvider jwtAuthProvider09 = new({ http:JwtAuthnHandler jwtAuthnHandler09 = new(jwtAuthProvider09); -listener http:Listener listener09 = new(9098, config = { +listener http:Listener listener09 = new(9100, config = { auth: { authnHandlers: [jwtAuthnHandler09] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal index 7269bf3a70b7..0e8d4052e0b1 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/10_token_propagation_disabled_test.bal @@ -21,7 +21,7 @@ import ballerina/http; auth:ConfigAuthStoreProvider basicAuthProvider10 = new; http:BasicAuthnHandler basicAuthnHandler10 = new(basicAuthProvider10); -listener http:Listener listener10_1 = new(9099, config = { +listener http:Listener listener10_1 = new(9101, config = { auth: { authnHandlers: [basicAuthnHandler10] }, @@ -34,7 +34,7 @@ listener http:Listener listener10_1 = new(9099, config = { }); // client will not propagate JWT -http:Client nyseEP = new("https://localhost:9100"); +http:Client nyseEP = new("https://localhost:9102"); @http:ServiceConfig { basePath: "/passthrough" } service passthroughService10 on listener10_1 { @@ -69,7 +69,7 @@ auth:JWTAuthProvider jwtAuthProvider10 = new({ http:JwtAuthnHandler jwtAuthnHandler10 = new(jwtAuthProvider10); -listener http:Listener listener10_2 = new(9100, config = { +listener http:Listener listener10_2 = new(9102, config = { auth: { authnHandlers: [jwtAuthnHandler10] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal index b6f47ab7c78b..f21b59d21a92 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/11_token_propagation_basic_auth_test.bal @@ -20,7 +20,7 @@ import ballerina/http; auth:ConfigAuthStoreProvider basicAuthProvider11 = new; http:BasicAuthnHandler basicAuthnHandler11 = new(basicAuthProvider11); -listener http:Listener listener11_1 = new(9101, config = { +listener http:Listener listener11_1 = new(9103, config = { auth: { authnHandlers: [basicAuthnHandler11] }, @@ -32,7 +32,7 @@ listener http:Listener listener11_1 = new(9101, config = { } }); -http:Client nyseEP03 = new("https://localhost:9102", config = { +http:Client nyseEP03 = new("https://localhost:9104", config = { auth: { scheme: http:JWT_AUTH, config: { @@ -83,7 +83,7 @@ auth:JWTAuthProvider jwtAuthProvider11 = new({ http:JwtAuthnHandler jwtAuthnHandler11 = new(jwtAuthProvider11); -listener http:Listener listener11_2 = new(9102, config = { +listener http:Listener listener11_2 = new(9104, config = { auth: { authnHandlers: [jwtAuthnHandler11] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_token_propagation_jwt_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_token_propagation_jwt_test.bal index 70442ff804a7..8590a8cee4ec 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_token_propagation_jwt_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/12_token_propagation_jwt_test.bal @@ -29,7 +29,7 @@ auth:JWTAuthProvider jwtAuthProvider12_1 = new({ http:JwtAuthnHandler jwtAuthnHandler12_1 = new(jwtAuthProvider12_1); -listener http:Listener listener12_1 = new(9103, config = { +listener http:Listener listener12_1 = new(9105, config = { auth: { authnHandlers: [jwtAuthnHandler12_1] }, @@ -41,7 +41,7 @@ listener http:Listener listener12_1 = new(9103, config = { } }); -http:Client nyseEP12 = new("https://localhost:9104", config = { +http:Client nyseEP12 = new("https://localhost:9106", config = { auth: { scheme: http:JWT_AUTH } @@ -80,7 +80,7 @@ auth:JWTAuthProvider jwtAuthProvider12_2 = new({ http:JwtAuthnHandler jwtAuthnHandler12_2 = new(jwtAuthProvider12_2); -listener http:Listener listener12_2 = new(9104, config = { +listener http:Listener listener12_2 = new(9106, config = { auth: { authnHandlers: [jwtAuthnHandler12_2] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_token_propagation_jwt_reissuing_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_token_propagation_jwt_reissuing_test.bal index 2358635e7972..90f6294600e7 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_token_propagation_jwt_reissuing_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/13_token_propagation_jwt_reissuing_test.bal @@ -29,7 +29,7 @@ auth:JWTAuthProvider jwtAuthProvider13_1 = new({ http:JwtAuthnHandler jwtAuthnHandler13_1 = new(jwtAuthProvider13_1); -listener http:Listener listener13_1 = new(9105, config = { +listener http:Listener listener13_1 = new(9107, config = { auth: { authnHandlers: [jwtAuthnHandler13_1] }, @@ -41,7 +41,7 @@ listener http:Listener listener13_1 = new(9105, config = { } }); -http:Client nyseEP13 = new("https://localhost:9106", config = { +http:Client nyseEP13 = new("https://localhost:9108", config = { auth: { scheme: http:JWT_AUTH, config: { @@ -92,7 +92,7 @@ auth:JWTAuthProvider jwtAuthProvider13_2 = new({ http:JwtAuthnHandler jwtAuthnHandler13_2 = new(jwtAuthProvider13_2); -listener http:Listener listener13_2 = new(9106, config = { +listener http:Listener listener13_2 = new(9108, config = { auth: { authnHandlers: [jwtAuthnHandler13_2] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_token_propagation_jwt_reissuing_negative_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_token_propagation_jwt_reissuing_negative_test.bal index 22fd72a3e1e1..669dc02edd9d 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_token_propagation_jwt_reissuing_negative_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/14_token_propagation_jwt_reissuing_negative_test.bal @@ -29,7 +29,7 @@ auth:JWTAuthProvider jwtAuthProvider14_1 = new({ http:JwtAuthnHandler jwtAuthnHandler14_1 = new(jwtAuthProvider14_1); -listener http:Listener listener14_1 = new(9107, config = { +listener http:Listener listener14_1 = new(9109, config = { auth: { authnHandlers: [jwtAuthnHandler14_1] }, @@ -41,7 +41,7 @@ listener http:Listener listener14_1 = new(9107, config = { } }); -http:Client nyseEP14 = new("https://localhost:9108", config = { +http:Client nyseEP14 = new("https://localhost:9110", config = { auth: { scheme: http:JWT_AUTH, config: { @@ -92,7 +92,7 @@ auth:JWTAuthProvider jwtAuthProvider14_2 = new({ http:JwtAuthnHandler jwtAuthnHandler14_2 = new(jwtAuthProvider14_2); -listener http:Listener listener14_2 = new(9108, config = { +listener http:Listener listener14_2 = new(9110, config = { auth: { authnHandlers: [jwtAuthnHandler14_2] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_ldap_auth_store_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_ldap_auth_store_test.bal index d06bfbb60c11..99bdf52d48d9 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_ldap_auth_store_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/15_ldap_auth_store_test.bal @@ -43,7 +43,7 @@ auth:LdapAuthStoreProviderConfig ldapConfig02 = { auth:LdapAuthStoreProvider ldapAuthStoreProvider02 = new(ldapConfig02, "ldap01"); http:BasicAuthnHandler ldapAuthnHandler02 = new(ldapAuthStoreProvider02); -listener http:Listener ep = new(9109, config = { +listener http:Listener ep = new(9111, config = { auth: { authnHandlers: [ldapAuthnHandler02] }, diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_ldap_auth_store_authz_test.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_ldap_auth_store_authz_test.bal index 50feef3562a6..6cc69c3d1381 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_ldap_auth_store_authz_test.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/16_ldap_auth_store_authz_test.bal @@ -43,7 +43,7 @@ auth:LdapAuthStoreProviderConfig ldapConfig01 = { auth:LdapAuthStoreProvider ldapAuthStoreProvider01 = new(ldapConfig01, "ldap01"); http:BasicAuthnHandler ldapAuthnHandler01 = new(ldapAuthStoreProvider01); -listener http:Listener authEP = new(9110, config = { +listener http:Listener authEP = new(9112, config = { auth: { authnHandlers: [ldapAuthnHandler01] }, From c6029609dd8700db81073d7b3d00cce389af4199 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 25 Apr 2019 10:37:38 +0530 Subject: [PATCH 26/52] Refactor auth unit tests --- .../test-src/auth/basic-authn-handler-test.bal | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal index 3ea1d70a50d8..5a845541e06c 100644 --- a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal @@ -3,8 +3,7 @@ import ballerina/http; function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; - auth:AuthProvider authProvider = configAuthStoreProvider; - http:BasicAuthnHandler handler = new(authProvider); + http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); string basicAuthHeaderValue = "123Basic xxxxxx"; inRequest.setHeader("123Authorization", basicAuthHeaderValue); @@ -13,8 +12,7 @@ function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { function testCanHandleHttpBasicAuth() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; - auth:AuthProvider authProvider = configAuthStoreProvider; - http:BasicAuthnHandler handler = new(authProvider); + http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); string basicAuthHeaderValue = "Basic xxxxxx"; inRequest.setHeader("Authorization", basicAuthHeaderValue); @@ -23,8 +21,7 @@ function testCanHandleHttpBasicAuth() returns boolean { function testHandleHttpBasicAuthFailure() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; - auth:AuthProvider authProvider = configAuthStoreProvider; - http:BasicAuthnHandler handler = new(authProvider); + http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); string basicAuthHeaderValue = "Basic YW1pbGE6cHFy"; inRequest.setHeader("Authorization", basicAuthHeaderValue); @@ -33,8 +30,7 @@ function testHandleHttpBasicAuthFailure() returns boolean { function testHandleHttpBasicAuth() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; - auth:AuthProvider authProvider = configAuthStoreProvider; - http:BasicAuthnHandler handler = new(authProvider); + http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); string basicAuthHeaderValue = "Basic aXN1cnU6eHh4"; inRequest.setHeader("Authorization", basicAuthHeaderValue); From 31e48204645d9c59a0a6fc4ec1f15f1480ec0a89 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 25 Apr 2019 10:44:15 +0530 Subject: [PATCH 27/52] Fix testng of auth integration tests --- .../src/test/resources/testng.xml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/ballerina-integration-test/src/test/resources/testng.xml b/tests/ballerina-integration-test/src/test/resources/testng.xml index c358316f214b..7d0e3a80ab64 100644 --- a/tests/ballerina-integration-test/src/test/resources/testng.xml +++ b/tests/ballerina-integration-test/src/test/resources/testng.xml @@ -102,17 +102,15 @@ - + + + + + - - - - - - From 81492d7e364ae908d9314d28e305bd8eed2ccece Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 25 Apr 2019 12:01:35 +0530 Subject: [PATCH 28/52] Refactor code for review suggestions --- .../secured_service_with_basic_auth.bal | 2 +- .../auth/config_auth_store_provider.bal | 2 +- .../main/ballerina/auth/jwt_auth_provider.bal | 3 +- .../auth/ldap_auth_store_provider.bal | 2 +- stdlib/auth/src/main/ballerina/auth/utils.bal | 3 +- .../stdlib/auth/ConfigAuthProviderTest.java | 49 +++++++++---------- .../test-src/config_auth_provider_test.bal | 42 +++++++--------- 7 files changed, 46 insertions(+), 57 deletions(-) diff --git a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal index 5e419620c5f2..0e90591f913a 100644 --- a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal +++ b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal @@ -31,7 +31,7 @@ listener http:Listener ep = new(9090, config = { } } // Auth configuration comprises of two parts - authentication & authorization. -// Authentication can be disabled by setting the `enabled: flag` annotation +// Authentication can be disabled by setting the `enabled: false` annotation // attribute, if needed. // Authorization is based on scopes, where a scope maps to one or more groups. // For a user to access a resource, the user should be in the same groups as diff --git a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal index 96ddb5da4d8a..9c9f603bd6e5 100644 --- a/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/config_auth_store_provider.bal @@ -29,7 +29,7 @@ public type ConfigAuthStoreProvider object { # Attempts to authenticate with credential. # # + credential - Credential - # + return - True if authentication is a success, else false or `error` occured while extracting credentials + # + return - `true` if authentication is successful, otherwise `false` or `error` occured while extracting credentials public function authenticate(string credential) returns boolean|error { if (credential == EMPTY_STRING) { return false; diff --git a/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal b/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal index d574b0dbe187..71a8487416db 100644 --- a/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/jwt_auth_provider.bal @@ -38,8 +38,7 @@ public type JWTAuthProvider object { # Authenticate with a jwt token. # # + jwtToken - Jwt token extracted from the authentication header - # + return - True if authentication is successful, false otherwise. - # If an error occur during authentication, the error will be returned. + # + return - `true` if authentication is successful, othewise `false` or `error` occured during jwt validation public function authenticate(string jwtToken) returns boolean|error { if (self.jwtAuthProviderConfig.jwtCache.hasKey(jwtToken)) { var payload = authenticateFromCache(self.jwtAuthProviderConfig, jwtToken); diff --git a/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal b/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal index 9a4a6fe0c416..2281903cc1f9 100644 --- a/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal +++ b/stdlib/auth/src/main/ballerina/auth/ldap_auth_store_provider.bal @@ -98,7 +98,7 @@ public type LdapAuthStoreProvider object { # Authenticate with username and password. # # + credential - Credential value - # + return - True if authentication is a success, else false or `error` occured while extracting credentials + # + return - `true` if authentication is successful, otherwise `false` or `error` occured while extracting credentials public function authenticate(string credential) returns boolean|error { if (credential == EMPTY_STRING) { return false; diff --git a/stdlib/auth/src/main/ballerina/auth/utils.bal b/stdlib/auth/src/main/ballerina/auth/utils.bal index 1a01b8f1dd46..120f4cfee3bb 100644 --- a/stdlib/auth/src/main/ballerina/auth/utils.bal +++ b/stdlib/auth/src/main/ballerina/auth/utils.bal @@ -45,7 +45,8 @@ function extractUsernameAndPassword(string credential) returns (string, string)| string decodedHeaderValue = encoding:byteArrayToString(check encoding:decodeBase64(credential)); string[] decodedCredentials = decodedHeaderValue.split(":"); if (decodedCredentials.length() != 2) { - error err = error(AUTH_ERROR_CODE, {message: "Incorrect credential format. Format should be username:password" }); + error err = error(AUTH_ERROR_CODE, + { message: "Incorrect credential format. Format should be username:password" }); return err; } else { return (decodedCredentials[0], decodedCredentials[1]); diff --git a/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java b/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java index 97d55580c0ae..90cddeb4c946 100644 --- a/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java +++ b/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/ConfigAuthProviderTest.java @@ -79,97 +79,94 @@ public void testCreateConfigAuthProvider() { @Test(description = "Test case for authenticating non-existing user") public void testAuthenticationOfNonExistingUser() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationOfNonExistingUser"); - Assert.assertNotNull(returns); - Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertFailureOfResults(returns); } @Test(description = "Test case for authenticating with invalid password") public void testAuthenticationOfNonExistingPassword() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationOfNonExistingPassword"); - Assert.assertNotNull(returns); - Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertFailureOfResults(returns); } @Test(description = "Test case for successful authentication") public void testAuthentication() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthentication"); - Assert.assertNotNull(returns); - Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertSuccessOfResults(returns); } @Test(description = "Test case for unsuccessful authentication when username is empty") public void testAuthenticationWithEmptyUsername() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationWithEmptyUsername"); - Assert.assertNotNull(returns); - Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertFailureOfResults(returns); } @Test(description = "Test case for unsuccessful authentication when password is empty") public void testAuthenticationWithEmptyPassword() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationWithEmptyPassword"); - Assert.assertNotNull(returns); - Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertFailureOfResults(returns); } @Test(description = "Test case for unsuccessful authentication when password is empty and username is invalid") public void testAuthenticationWithEmptyPasswordAndInvalidUsername() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationWithEmptyPasswordAndInvalidUsername"); - Assert.assertNotNull(returns); - Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertFailureOfResults(returns); } @Test(description = "Test case for unsuccessful authentication when username and password are empty") public void testAuthenticationWithEmptyUsernameAndEmptyPassword() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationWithEmptyUsernameAndEmptyPassword"); - Assert.assertNotNull(returns); - Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertFailureOfResults(returns); } @Test(description = "Test case for successful authentication with sha-256 hashed password") public void testAuthenticationSha256() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationSha256"); - Assert.assertNotNull(returns); - Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertSuccessOfResults(returns); } @Test(description = "Test case for successful authentication with sha-384 hashed password") public void testAuthenticationSha384() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationSha384"); - Assert.assertNotNull(returns); - Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertSuccessOfResults(returns); } @Test(description = "Test case for successful authentication with sha-512 hashed password") public void testAuthenticationSha512() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationSha512"); - Assert.assertNotNull(returns); - Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertSuccessOfResults(returns); } @Test(description = "Test case for successful authentication with plain text password") public void testAuthenticationPlain() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationPlain"); - Assert.assertNotNull(returns); - Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertSuccessOfResults(returns); } @Test(description = "Test case for unsuccessful authentication with sha-512 hashed password, using invalid " + "password") public void testAuthenticationSha512Negative() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationSha512Negative"); - Assert.assertNotNull(returns); - Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertFailureOfResults(returns); } @Test(description = "Test case for unsuccessful authentication with plain text password, using invalid password") public void testAuthenticationPlainNegative() { BValue[] returns = BRunUtil.invoke(compileResult, "testAuthenticationPlainNegative"); - Assert.assertNotNull(returns); - Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + assertFailureOfResults(returns); } @AfterClass public void tearDown() throws IOException { Files.deleteIfExists(secretCopyPath); } + + private void assertSuccessOfResults(BValue[] returns) { + Assert.assertNotNull(returns); + Assert.assertTrue(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + } + + private void assertFailureOfResults(BValue[] returns) { + Assert.assertNotNull(returns); + Assert.assertFalse(returns[0] instanceof BBoolean && ((BBoolean) returns[0]).booleanValue()); + } } diff --git a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal index d9fcc1fc4867..768ea7600b59 100644 --- a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal +++ b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal @@ -25,90 +25,82 @@ function testCreateConfigAuthProvider() returns auth:ConfigAuthStoreProvider { function testAuthenticationOfNonExistingUser() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "amila:abc"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationOfNonExistingPassword() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "isuru:xxy"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthentication() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "isuru:xxx"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationWithEmptyUsername() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = ":xxx"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationWithEmptyPassword() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "isuru:"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationWithEmptyPasswordAndInvalidUsername() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "invalid:"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationWithEmptyUsernameAndEmptyPassword() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = ":"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationSha256() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha256:xxx"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationSha384() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha384:xxx"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationSha512() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha512:xxx"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationPlain() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "plain:plainpassword"; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationSha512Negative() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha512:xxx "; - string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); - return configAuthStoreProvider.authenticate(credential); + return authenticate(usernameAndPassword); } function testAuthenticationPlainNegative() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "plain:plainpassword "; + return authenticate(usernameAndPassword); +} + +function authenticate(string usernameAndPassword) returns string { string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); -} +} \ No newline at end of file From 15a1659e1108bdd610616d591ee072fd86c3e67c Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 25 Apr 2019 12:01:58 +0530 Subject: [PATCH 29/52] Refactor integration tests --- .../ballerinalang/test/auth/AuthBaseTest.java | 17 ++++ .../test/auth/AuthnConfigInheritanceTest.java | 36 +++------ .../auth/AuthnWithMultipleHandlersTest.java | 12 +-- .../auth/AuthnWithoutHTTPAnnotationsTest.java | 6 +- .../test/auth/AuthzCacheTest.java | 9 +-- .../test/auth/AuthzConfigInheritanceTest.java | 81 +++++++------------ .../test/auth/LdapAuthStoreTest.java | 14 +--- .../test/auth/ResourceLevelAuthTest.java | 9 +-- .../test/auth/ServiceLevelAuthnTest.java | 15 ++-- .../test/auth/TokenPropagationTest.java | 16 ++-- 10 files changed, 83 insertions(+), 132 deletions(-) diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java index d4e452a9e5b3..ee727f439f0b 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java @@ -20,6 +20,8 @@ import org.ballerinalang.test.BaseTest; import org.ballerinalang.test.context.BServerInstance; +import org.ballerinalang.test.util.HttpResponse; +import org.testng.Assert; import org.testng.annotations.AfterGroups; import org.testng.annotations.BeforeGroups; @@ -55,4 +57,19 @@ public void cleanup() throws Exception { serverInstance.removeAllLeechers(); serverInstance.shutdownServer(); } + + public void assertOK(HttpResponse response) { + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + } + + public void assertUnauthorized(HttpResponse response) { + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + } + + public void assertForbidden(HttpResponse response) { + Assert.assertNotNull(response); + Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java index 6f3cddf15480..726ac7425c2e 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java @@ -38,32 +38,28 @@ public class AuthnConfigInheritanceTest extends AuthBaseTest { public void testNoAuthHeaders1() throws Exception { HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test1"), serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } @Test(description = "Non secured resource, secured service test case with no auth headers") public void testNoAuthHeaders2() throws Exception { HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test2"), serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Secured resource, non secured service test case with no auth headers") public void testNoAuthHeaders3() throws Exception { HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test1"), serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } @Test(description = "Non secured resource, non secured service test case with no auth headers") public void testNoAuthHeaders4() throws Exception { HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test2"), serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Secured resource, secured service test case with valid auth headers") @@ -72,8 +68,7 @@ public void testValidAuthHeaders1() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Non secured resource, secured service test case with valid auth headers") @@ -82,8 +77,7 @@ public void testValidAuthHeaders2() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Secured resource, non secured service test case with valid auth headers") @@ -92,8 +86,7 @@ public void testValidAuthHeaders3() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Non secured resource, non secured service test case with valid auth headers") @@ -102,8 +95,7 @@ public void testValidAuthHeaders4() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Secured resource, secured service test case with invalid auth headers") @@ -112,8 +104,7 @@ public void testInvalidAuthHeaders1() throws Exception { headersMap.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } @Test(description = "Non secured resource, secured service test case with invalid auth headers") @@ -122,8 +113,7 @@ public void testInvalidAuthHeaders2() throws Exception { headersMap.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo1/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Secured resource, non secured service test case with invalid auth headers") @@ -132,8 +122,7 @@ public void testInvalidAuthHeaders3() throws Exception { headersMap.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } @Test(description = "Non secured resource, non secured service test case with invalid auth headers") @@ -142,7 +131,6 @@ public void testInvalidAuthHeaders4() throws Exception { headersMap.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo2/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java index 0e722e36253c..7954c5168c78 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java @@ -66,8 +66,7 @@ public void testAuthSuccessWithExample1Issuer() throws Exception { "DakBTiEITrbO3OzrNeCQFBN-Ji4BTXq97TulCIRNneDLCUBSRE1A"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Authn success test case with example2 issuer") @@ -98,8 +97,7 @@ public void testAuthSuccessWithExample2Issuer() throws Exception { "pvcLBUiAaXFeXPb9t4iHFugJzHY68eQQZcxyIxWVyj2eNV4HmBjvqVLQuA"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Authn fail test case with example3 issuer") @@ -130,8 +128,7 @@ public void testAuthFailWithExample3Issuer() throws Exception { "t1xdW40dCnDrSR6urqVGys0Zg_Ru0mnPg4dU2JPuwDLuKzj4KzWXShZ2Il5Ol-IA"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } @Test(description = "Authn fail test case with example1 issuer and invalid audience") @@ -160,7 +157,6 @@ public void testAuthFailWithExample1IssuerAndInvalidAudience() throws Exception "roxJPVxncPTRuewApF-RpXPKdheVEqQ4w"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java index 6452d388d694..3218c1aa7145 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java @@ -46,8 +46,7 @@ public void testAuthSuccess() throws Exception { headers.put("Authorization", "Basic aXN1cnU6eHh4"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Authn failure test case") @@ -57,7 +56,6 @@ public void testAuthnFailure() throws Exception { headers.put("Authorization", "Basic aW52YWxpZFVzZXI6YWJj"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java index 4a77dbb67ef7..32dc7c4e296c 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java @@ -66,8 +66,7 @@ public void testAuthCache() throws Exception { "z1BbKC2z79eMe15yx8asas3krgJyKVNISUWlgPWvKHxyfh_RoQYgWPn-rhng1_P8Ag"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); // JWT used in the second request: // { @@ -95,8 +94,7 @@ public void testAuthCache() throws Exception { "dpwoUnOy9aseNB8iy0AAPQwf1MkpbgCUJFGLAWHAQsUBJXPpCPGMKVJ5CYzFiPC_bX_pUrzrXOJw"); response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); // JWT used in the third request: // { @@ -124,7 +122,6 @@ public void testAuthCache() throws Exception { "LbLux8FaxyAglgRoDNgBgaCynbhUYAUnpr2JSx72FN8J0CJB5f31EMmmd4FukTtv-8w"); response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java index 74bc71707441..c84d3417e097 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java @@ -42,8 +42,7 @@ public void testValidScopesAtListener1() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo1/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - valid scopes, service - valid scopes and resource - invalid scopes") @@ -52,8 +51,7 @@ public void testValidScopesAtListener2() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo1/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - valid scopes, service - valid scopes and resource - scopes not given") @@ -62,8 +60,7 @@ public void testValidScopesAtListener3() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo1/test3"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - valid scopes, service - invalid scopes and resource - valid scopes") @@ -72,8 +69,7 @@ public void testValidScopesAtListener4() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo2/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - valid scopes, service - invalid scopes and resource - invalid scopes") @@ -82,8 +78,7 @@ public void testValidScopesAtListener5() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo2/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - valid scopes, service - invalid scopes and resource - scopes not given") @@ -92,8 +87,7 @@ public void testValidScopesAtListener6() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo2/test3"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - valid scopes, service - scopes not given and resource - valid scopes") @@ -102,8 +96,7 @@ public void testValidScopesAtListener7() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo3/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - valid scopes, service - scopes not given and resource - invalid scopes") @@ -112,8 +105,7 @@ public void testValidScopesAtListener8() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo3/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - valid scopes, service - scopes not given and resource - scopes not given") @@ -122,8 +114,7 @@ public void testValidScopesAtListener9() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort1, "echo3/test3"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - invalid scopes, service - valid scopes and resource - valid scopes") @@ -132,8 +123,7 @@ public void testInValidScopesAtListener1() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo1/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - invalid scopes, service - valid scopes and resource - invalid scopes") @@ -142,8 +132,7 @@ public void testInValidScopesAtListener2() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo1/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - invalid scopes, service - valid scopes and resource - scopes not given") @@ -152,8 +141,7 @@ public void testInValidScopesAtListener3() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo1/test3"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - invalid scopes, service - invalid scopes and resource - valid scopes") @@ -162,8 +150,7 @@ public void testInValidScopesAtListener4() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo2/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - invalid scopes, service - invalid scopes and resource - invalid scopes") @@ -172,8 +159,7 @@ public void testInValidScopesAtListener5() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo2/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - invalid scopes, service - invalid scopes and resource - scopes not given") @@ -182,8 +168,7 @@ public void testInValidScopesAtListener6() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo2/test3"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - invalid scopes, service - scopes not given and resource - valid scopes") @@ -192,8 +177,7 @@ public void testInValidScopesAtListener7() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo3/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - invalid scopes, service - scopes not given and resource - invalid scopes") @@ -202,8 +186,7 @@ public void testInValidScopesAtListener8() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo3/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - invalid scopes, service - scopes not given and resource - scopes not given") @@ -212,8 +195,7 @@ public void testInValidScopesAtListener9() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort2, "echo3/test3"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - scopes not given, service - valid scopes and resource - valid scopes") @@ -222,8 +204,7 @@ public void testNotGivenScopesAtListener1() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo1/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - scopes not given, service - valid scopes and resource - invalid scopes") @@ -232,8 +213,7 @@ public void testNotGivenScopesAtListener2() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo1/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - scopes not given, service - valid scopes and resource - scopes not given") @@ -242,8 +222,7 @@ public void testNotGivenScopesAtListener3() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo1/test3"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - scopes not given, service - invalid scopes and resource - valid scopes") @@ -252,8 +231,7 @@ public void testNotGivenScopesAtListener4() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo2/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - scopes not given, service - invalid scopes and resource - invalid scopes") @@ -262,8 +240,7 @@ public void testNotGivenScopesAtListener5() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo2/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - scopes not given, service - invalid scopes and resource - scopes not given") @@ -272,8 +249,7 @@ public void testNotGivenScopesAtListener6() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo2/test3"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - scopes not given, service - scopes not given and resource - valid scopes") @@ -282,8 +258,7 @@ public void testNotGivenScopesAtListener7() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo3/test1"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Listener - scopes not given, service - scopes not given and resource - invalid scopes") @@ -292,8 +267,7 @@ public void testNotGivenScopesAtListener8() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo3/test2"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Listener - scopes not given, service - scopes not given and resource - scopes not given") @@ -302,7 +276,6 @@ public void testNotGivenScopesAtListener9() throws Exception { headersMap.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort3, "echo3/test3"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java index dc4c623087e5..021cf4c253ed 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java @@ -43,7 +43,7 @@ public void testAuthenticationWithInvalidCredentials() throws Exception { headersMap.put("Authorization", "Basic dmlqaXRoYTp2aWppdGhhQDEyMw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "ldapAuth/disableAuthz"), headersMap, serverInstance.getServerHome()); - assertResponse(response, 401, "Authentication failure"); + assertUnauthorized(response); } @Test(description = "Test authenticate request against ldap auth store") @@ -52,7 +52,7 @@ public void testAuthenticationWithLDAPAuthstoreWithoutAuthorization() throws Exc headersMap.put("Authorization", "Basic dmlqaXRoYTpiYWxsZXJpbmE="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "ldapAuth/disableAuthz"), headersMap, serverInstance.getServerHome()); - assertResponse(response, 200, "Hello, World!!!"); + assertOK(response); } @Test(description = "Test authenticate and authorize request against ldap auth store") @@ -61,7 +61,7 @@ public void testAuthenticationWithLDAPAuthstoreWithAuthorization() throws Except headersMap.put("Authorization", "Basic dmlqaXRoYTpiYWxsZXJpbmE="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "ldapAuth/enableAuthz"), headersMap, serverInstance.getServerHome()); - assertResponse(response, 200, "Hello, World!!!"); + assertOK(response); } @Test(description = "Test the failure of authorization request against ldap auth store") @@ -70,12 +70,6 @@ public void testAuthorizatioFailureWithLDAPAuthstore() throws Exception { headersMap.put("Authorization", "Basic dmlqaXRoYTpiYWxsZXJpbmE="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(authzServicePort, "auth/failAuthz"), headersMap, serverInstance.getServerHome()); - assertResponse(response, 403, "Authorization failure"); - } - - private void assertResponse(HttpResponse response, int statusCode, String message) { - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), statusCode, "Response code mismatched"); - Assert.assertEquals(response.getData(), message, "Response message content mismatched."); + assertForbidden(response); } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java index 604422c4526a..600a3fb3ecfa 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java @@ -40,8 +40,7 @@ public void testAuthSuccessWithResourceLevelConfigs() throws Exception { headers.put("Authorization", "Basic aXN1cnU6eHh4"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Authn success and authz failure test case") @@ -50,8 +49,7 @@ public void testAuthzFailureWithResourceLevelConfigs() throws Exception { headers.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Authn and authz failure test case") @@ -60,7 +58,6 @@ public void testAuthFailureWithResourceLevelConfigs() throws Exception { headers.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java index 5eade76a7305..46790c613c89 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java @@ -42,8 +42,7 @@ public void testAuthSuccessWithServiceLevelConfigs() throws Exception { headers.put("Authorization", "Basic aXN1cnU6eHh4"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Authn success and authz failure test case") @@ -52,8 +51,7 @@ public void testAuthzFailureWithServiceLevelConfigs() throws Exception { headers.put("Authorization", "Basic aXNoYXJhOmFiYw=="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); + assertForbidden(response); } @Test(description = "Authn and authz failure test case") @@ -62,8 +60,7 @@ public void testAuthFailureWithServiceLevelConfigs() throws Exception { headers.put("Authorization", "Basic dGVzdDp0ZXN0MTIz"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } @Test(description = "Auth with JWT signed with expired trusted certificate") @@ -93,8 +90,7 @@ public void testAuthnWithJWTSignedWithExpiredTrustedCertificate() throws Excepti HttpResponse response = HttpsClientRequest.doGet(serverInstance .getServiceURLHttps(servicePortForExpiredCertificateTest, "echo/test"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } @Test(description = "Auth with JWT signed with expired trusted certificate but with expiry validation off") @@ -124,7 +120,6 @@ public void testAuthnWithJWTSignedWithExpiredTrustedCertificateWithNoExpiryValid HttpResponse response = HttpsClientRequest.doGet(serverInstance .getServiceURLHttps(servicePortForExpiredCertificateTestWithNoExpiryValidation, "echo/test"), headersMap, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java index 5392f42199e6..88468ddc113c 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java @@ -38,8 +38,7 @@ public void testTokenPropagationWithBasicAuthInbound() throws Exception { headers.put("Authorization", "Basic aXN1cnU6eHh4"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9103, "passthrough"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Test behaviour when JWT Token propagation is disabled, resulting in authn failure") @@ -48,8 +47,7 @@ public void testWithoutTokenPropagation() throws Exception { headers.put("Authorization", "Basic aXN1cnU6eHh4"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9101, "passthrough"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } @Test(description = "Test JWT Token propagation with JWT auth as the inbound authentication mechanism, without " + @@ -65,8 +63,8 @@ public void testTokenPropagationWithJwtAuthInbound() throws Exception { "oI60HQFFlgC1g_crPIDakBTiEITrbO3OzrNeCQFBN-Ji4BTXq97TulCIRNneDLCUBSRE1A"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9105, "passthrough"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + + assertOK(response); } @Test(description = "Test JWT Token propagation with JWT auth as the inbound authentication mechanism, with " + @@ -82,8 +80,7 @@ public void testTokenPropagationWithJwtAuthInboundAndTokenReissuing() throws Exc "oI60HQFFlgC1g_crPIDakBTiEITrbO3OzrNeCQFBN-Ji4BTXq97TulCIRNneDLCUBSRE1A"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9107, "passthrough"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); + assertOK(response); } @Test(description = "Negative test for JWT Token propagation with JWT auth as the inbound authentication " + @@ -99,7 +96,6 @@ public void testTokenPropagationWithJwtAuthInboundAndTokenReissuingNegative() th "oI60HQFFlgC1g_crPIDakBTiEITrbO3OzrNeCQFBN-Ji4BTXq97TulCIRNneDLCUBSRE1A"); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(9109, "passthrough"), headers, serverInstance.getServerHome()); - Assert.assertNotNull(response); - Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); + assertUnauthorized(response); } } From ba0b138ef29c22243ce5497a544d46fe11d48095 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 25 Apr 2019 12:14:08 +0530 Subject: [PATCH 30/52] Fix a bug --- .../test-src/config_auth_provider_test.bal | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal index 768ea7600b59..1687b7675100 100644 --- a/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal +++ b/stdlib/auth/src/test/resources/test-src/config_auth_provider_test.bal @@ -23,25 +23,21 @@ function testCreateConfigAuthProvider() returns auth:ConfigAuthStoreProvider { } function testAuthenticationOfNonExistingUser() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "amila:abc"; return authenticate(usernameAndPassword); } function testAuthenticationOfNonExistingPassword() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "isuru:xxy"; return authenticate(usernameAndPassword); } function testAuthentication() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "isuru:xxx"; return authenticate(usernameAndPassword); } function testAuthenticationWithEmptyUsername() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = ":xxx"; return authenticate(usernameAndPassword); } @@ -59,48 +55,42 @@ function testAuthenticationWithEmptyPasswordAndInvalidUsername() returns boolean } function testAuthenticationWithEmptyUsernameAndEmptyPassword() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = ":"; return authenticate(usernameAndPassword); } function testAuthenticationSha256() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha256:xxx"; return authenticate(usernameAndPassword); } function testAuthenticationSha384() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha384:xxx"; return authenticate(usernameAndPassword); } function testAuthenticationSha512() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha512:xxx"; return authenticate(usernameAndPassword); } function testAuthenticationPlain() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "plain:plainpassword"; return authenticate(usernameAndPassword); } function testAuthenticationSha512Negative() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "hashedSha512:xxx "; return authenticate(usernameAndPassword); } function testAuthenticationPlainNegative() returns boolean|error { - auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string usernameAndPassword = "plain:plainpassword "; return authenticate(usernameAndPassword); } -function authenticate(string usernameAndPassword) returns string { +function authenticate(string usernameAndPassword) returns boolean|error { + auth:ConfigAuthStoreProvider configAuthStoreProvider = new; string credential = encoding:encodeBase64(usernameAndPassword.toByteArray("UTF-8")); return configAuthStoreProvider.authenticate(credential); -} \ No newline at end of file +} From 3997072b72bdc59bc05a5090b0a61490c3f01fcd Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 25 Apr 2019 16:08:25 +0530 Subject: [PATCH 31/52] Fix checkstyle bug --- .../org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java | 1 - .../ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java | 1 - .../ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java | 1 - .../test/java/org/ballerinalang/test/auth/AuthzCacheTest.java | 1 - .../org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java | 1 - .../test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java | 1 - .../java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java | 1 - .../java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java | 1 - .../java/org/ballerinalang/test/auth/TokenPropagationTest.java | 1 - 9 files changed, 9 deletions(-) diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java index 726ac7425c2e..284048126374 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnConfigInheritanceTest.java @@ -20,7 +20,6 @@ import org.ballerinalang.test.util.HttpResponse; import org.ballerinalang.test.util.HttpsClientRequest; -import org.testng.Assert; import org.testng.annotations.Test; import java.util.HashMap; diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java index 7954c5168c78..e186613f9d70 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithMultipleHandlersTest.java @@ -22,7 +22,6 @@ import org.ballerinalang.test.util.HttpResponse; import org.ballerinalang.test.util.HttpsClientRequest; import org.ballerinalang.test.util.TestConstant; -import org.testng.Assert; import org.testng.annotations.Test; import java.util.HashMap; diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java index 3218c1aa7145..2b1ecffc96ad 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithoutHTTPAnnotationsTest.java @@ -22,7 +22,6 @@ import org.ballerinalang.test.util.HttpResponse; import org.ballerinalang.test.util.HttpsClientRequest; import org.ballerinalang.test.util.TestConstant; -import org.testng.Assert; import org.testng.annotations.Test; import java.util.HashMap; diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java index 32dc7c4e296c..89d3a7e24903 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzCacheTest.java @@ -22,7 +22,6 @@ import org.ballerinalang.test.util.HttpResponse; import org.ballerinalang.test.util.HttpsClientRequest; import org.ballerinalang.test.util.TestConstant; -import org.testng.Assert; import org.testng.annotations.Test; import java.util.HashMap; diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java index c84d3417e097..82c0ff2d22f6 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthzConfigInheritanceTest.java @@ -20,7 +20,6 @@ import org.ballerinalang.test.util.HttpResponse; import org.ballerinalang.test.util.HttpsClientRequest; -import org.testng.Assert; import org.testng.annotations.Test; import java.util.HashMap; diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java index 021cf4c253ed..e9c27deffb66 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java @@ -20,7 +20,6 @@ import org.ballerinalang.test.util.HttpResponse; import org.ballerinalang.test.util.HttpsClientRequest; -import org.testng.Assert; import org.testng.annotations.Test; import java.util.HashMap; diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java index 600a3fb3ecfa..2e5205f7eae0 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ResourceLevelAuthTest.java @@ -20,7 +20,6 @@ import org.ballerinalang.test.util.HttpResponse; import org.ballerinalang.test.util.HttpsClientRequest; -import org.testng.Assert; import org.testng.annotations.Test; import java.util.HashMap; diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java index 46790c613c89..abb8695e5f91 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java @@ -20,7 +20,6 @@ import org.ballerinalang.test.util.HttpResponse; import org.ballerinalang.test.util.HttpsClientRequest; -import org.testng.Assert; import org.testng.annotations.Test; import java.util.HashMap; diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java index 88468ddc113c..dabedecf2c52 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/TokenPropagationTest.java @@ -20,7 +20,6 @@ import org.ballerinalang.test.util.HttpResponse; import org.ballerinalang.test.util.HttpsClientRequest; -import org.testng.Assert; import org.testng.annotations.Test; import java.util.HashMap; From 5cca33343f0f59494c8e443d975ada13f4b417b0 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 25 Apr 2019 16:52:13 +0530 Subject: [PATCH 32/52] Add integration test for custom handlers --- .../ballerinalang/test/auth/AuthBaseTest.java | 2 +- .../auth/AuthnWithCustomHandlersTest.java | 59 ++++++++++ .../17_authn_with_custom_handlers.bal | 104 ++++++++++++++++++ .../src/test/resources/testng.xml | 1 + 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithCustomHandlersTest.java create mode 100644 tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java index ee727f439f0b..943c3a009f33 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java @@ -39,7 +39,7 @@ public class AuthBaseTest extends BaseTest { @BeforeGroups(value = "auth-test", alwaysRun = true) public void start() throws Exception { int[] requiredPorts = new int[]{9090, 9091, 9092, 9093, 9094, 9095, 9096, 9097, 9098, 9099, 9100, 9101, 9102, - 9103, 9104, 9105, 9106, 9107, 9108, 9109, 9110, 9111, 9112, 9195, 9196}; + 9103, 9104, 9105, 9106, 9107, 9108, 9109, 9110, 9111, 9112, 9113, 9195, 9196}; embeddedDirectoryServer = new EmbeddedDirectoryServer(); embeddedDirectoryServer.startLdapServer(9389); diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithCustomHandlersTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithCustomHandlersTest.java new file mode 100644 index 000000000000..4321758d26f3 --- /dev/null +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthnWithCustomHandlersTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.ballerinalang.test.auth; + +import org.ballerinalang.test.util.HttpResponse; +import org.ballerinalang.test.util.HttpsClientRequest; +import org.testng.annotations.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * Test cases for authentication with custom handlers. + */ +@Test(groups = "auth-test") +public class AuthnWithCustomHandlersTest extends AuthBaseTest { + + private final int servicePort = 9113; + + @Test(description = "Secured resource, secured service test case with valid auth headers") + public void testNoAuthHeaders() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic YWJjOjEyMw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), + headersMap, serverInstance.getServerHome()); + assertUnauthorized(response); + } + + public void testInvalidAuthHeaders() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Basic YWJjOjEyMw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), + headersMap, serverInstance.getServerHome()); + assertUnauthorized(response); + } + + public void testValidAuthHeaders() throws Exception { + Map headersMap = new HashMap<>(); + headersMap.put("Authorization", "Custom YWJjOjEyMw=="); + HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(servicePort, "echo/test"), + headersMap, serverInstance.getServerHome()); + assertOK(response); + } +} diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal new file mode 100644 index 000000000000..eaee5aeb33d0 --- /dev/null +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal @@ -0,0 +1,104 @@ +// Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// +// WSO2 Inc. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/auth; +import ballerina/encoding; +import ballerina/http; +import ballerina/log; +import ballerina/runtime; + +CustomAuthStoreProvider customAuthStoreProvider = new; +CustomAuthnHandler customAuthnHandler = new(customAuthStoreProvider); + +listener http:Listener listener17 = new(9113, config = { + auth: { + authnHandlers: [customAuthnHandler], + scopes: ["all"] + }, + secureSocket: { + keyStore: { + path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", + password: "ballerina" + } + } + }); + +service echo on listener17 { + resource function test(http:Caller caller, http:Request req) { + checkpanic caller->respond("Hello Ballerina!"); + } +} + + +// ---------- custom_authn_handler ---------- + +public type CustomAuthnHandler object { + + *http:AuthnHandler; + + public auth:AuthProvider authProvider; + + public function __init(auth:AuthProvider authProvider) { + self.authProvider = authProvider; + } +}; + +public function CustomAuthnHandler.handle(http:Request req) returns boolean { + var customAuthHeader = req.getHeader(http:AUTH_HEADER); + string credential = customAuthHeader.substring(6, customAuthHeader.length()).trim(); + var authenticated = self.authProvider.authenticate(credential); + if (authenticated is boolean) { + return authenticated; + } + return false; +} + +public function CustomAuthnHandler.canHandle(http:Request req) returns boolean { + var customAuthHeader = req.getHeader(http:AUTH_HEADER); + return customAuthHeader.hasPrefix("Custom"); +} + + +// ---------- custom_auth_store_provider ---------- + +public type CustomAuthStoreProvider object { + + *auth:AuthProvider; + + public function authenticate(string credential) returns boolean|error { + string actualUsername = "abc"; + string actualPassword = "123"; + + string decodedHeaderValue = encoding:byteArrayToString(check encoding:decodeBase64(credential)); + string[] decodedCredentials = decodedHeaderValue.split(":"); + string username = decodedCredentials[0]; + string password = decodedCredentials[1]; + + boolean isAuthenticated = username == actualUsername && password == actualPassword; + if (isAuthenticated) { + runtime:Principal principal = runtime:getInvocationContext().principal; + principal.userId = username; + principal.username = username; + principal.scopes = self.getScopes(); + } + return isAuthenticated; + } + + public function getScopes() returns string[] { + string[] scopes = ["all"]; + return scopes; + } +}; \ No newline at end of file diff --git a/tests/ballerina-integration-test/src/test/resources/testng.xml b/tests/ballerina-integration-test/src/test/resources/testng.xml index 7d0e3a80ab64..c9d91847f9bc 100644 --- a/tests/ballerina-integration-test/src/test/resources/testng.xml +++ b/tests/ballerina-integration-test/src/test/resources/testng.xml @@ -112,6 +112,7 @@ + From 6e683f90bba44fbaeb73caecd098967e6385810e Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 25 Apr 2019 16:57:59 +0530 Subject: [PATCH 33/52] Reformat integration tests --- .../java/org/ballerinalang/test/auth/AuthBaseTest.java | 8 ++++---- .../ballerinalang/test/auth/EmbeddedDirectoryServer.java | 8 ++++---- .../org/ballerinalang/test/auth/LdapAuthStoreTest.java | 2 +- .../ballerinalang/test/auth/ServiceLevelAuthnTest.java | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java index 943c3a009f33..4fbecb247001 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/AuthBaseTest.java @@ -34,7 +34,7 @@ public class AuthBaseTest extends BaseTest { protected static BServerInstance serverInstance; - protected static EmbeddedDirectoryServer embeddedDirectoryServer; + private static EmbeddedDirectoryServer embeddedDirectoryServer; @BeforeGroups(value = "auth-test", alwaysRun = true) public void start() throws Exception { @@ -58,17 +58,17 @@ public void cleanup() throws Exception { serverInstance.shutdownServer(); } - public void assertOK(HttpResponse response) { + void assertOK(HttpResponse response) { Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 200, "Response code mismatched"); } - public void assertUnauthorized(HttpResponse response) { + void assertUnauthorized(HttpResponse response) { Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 401, "Response code mismatched"); } - public void assertForbidden(HttpResponse response) { + void assertForbidden(HttpResponse response) { Assert.assertNotNull(response); Assert.assertEquals(response.getResponseCode(), 403, "Response code mismatched"); } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/EmbeddedDirectoryServer.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/EmbeddedDirectoryServer.java index c830e500415a..ef8024aeac45 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/EmbeddedDirectoryServer.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/EmbeddedDirectoryServer.java @@ -67,7 +67,7 @@ public class EmbeddedDirectoryServer { * * @param partitionId The partition Id * @param partitionDn The partition DN - * @param dnFactory The factory for DNs + * @param dnFactory The factory for DNs * @return The newly added partition * @throws Exception If the partition can't be added */ @@ -109,7 +109,7 @@ public void startLdapServer(int port) throws Exception { // Create a new partition named 'b7a'. Partition b7aPartition = addPartition(LDAP_AUTH_TEST_PARTITION_NAME, - LDAP_AUTH_TEST_PARTITION_DN, service.getDnFactory()); + LDAP_AUTH_TEST_PARTITION_DN, service.getDnFactory()); service.addPartition(b7aPartition); // Start the service @@ -119,7 +119,7 @@ public void startLdapServer(int port) throws Exception { // Load the LDIF file String ldif = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + - "auth" + File.separator + "ldif").getAbsolutePath() + File.separator + "users-import.ldif"; + "auth" + File.separator + "ldif").getAbsolutePath() + File.separator + "users-import.ldif"; LdifFileLoader ldifLoader = new LdifFileLoader(service.getAdminSession(), ldif); ldifLoader.execute(); @@ -166,7 +166,7 @@ private void initSystemPartition() throws LdapInvalidDnException { /** * Stops directory apache directory service. */ - public void stopLdapService() { + void stopLdapService() { ldapServer.stop(); workDir.delete(); } diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java index e9c27deffb66..0d99b0d330b2 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/LdapAuthStoreTest.java @@ -64,7 +64,7 @@ public void testAuthenticationWithLDAPAuthstoreWithAuthorization() throws Except } @Test(description = "Test the failure of authorization request against ldap auth store") - public void testAuthorizatioFailureWithLDAPAuthstore() throws Exception { + public void testAuthorizationFailureWithLDAPAuthStore() throws Exception { Map headersMap = new HashMap<>(); headersMap.put("Authorization", "Basic dmlqaXRoYTpiYWxsZXJpbmE="); HttpResponse response = HttpsClientRequest.doGet(serverInstance.getServiceURLHttps(authzServicePort, diff --git a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java index abb8695e5f91..c5fd338b19f3 100644 --- a/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java +++ b/tests/ballerina-integration-test/src/test/java/org/ballerinalang/test/auth/ServiceLevelAuthnTest.java @@ -117,8 +117,8 @@ public void testAuthnWithJWTSignedWithExpiredTrustedCertificateWithNoExpiryValid "18xqUzweCRL-DLAAYwjbzGQ56ekbEdAg02sFco4aozOyt8OUDwS9cH_JlhUn2JEHmVKaatljEnfgRc8fOW6Y5IJ7dOPp7ra5e" + "00sk7JwYY8wKaZWxAGSgRpWgTY6C4XRjGIsR5ZWQdXCAnV27idGDrtR2uG4YQwCWUCzA"); HttpResponse response = HttpsClientRequest.doGet(serverInstance - .getServiceURLHttps(servicePortForExpiredCertificateTestWithNoExpiryValidation, - "echo/test"), headersMap, serverInstance.getServerHome()); + .getServiceURLHttps(servicePortForExpiredCertificateTestWithNoExpiryValidation, + "echo/test"), headersMap, serverInstance.getServerHome()); assertOK(response); } } From 8379b27c3a5d80cb31dc384c15edd3caf7cc40c4 Mon Sep 17 00:00:00 2001 From: praneesha Date: Mon, 29 Apr 2019 13:26:49 +0530 Subject: [PATCH 34/52] Apply suggestions from code review Co-Authored-By: ldclakmal --- .../secured_client_with_basic_auth.bal | 2 +- .../secured_client_with_jwt_auth.bal | 6 ++--- .../secured_service_with_basic_auth.bal | 23 ++++++++--------- .../secured_service_with_jwt.bal | 25 +++++++++---------- stdlib/auth/src/main/ballerina/auth/Module.md | 19 ++++++-------- 5 files changed, 35 insertions(+), 40 deletions(-) diff --git a/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal b/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal index 3c7939d6d737..6d9694044904 100644 --- a/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal +++ b/examples/secured-client-with-basic-auth/secured_client_with_basic_auth.bal @@ -31,7 +31,7 @@ public function main() { } } -// Create a basic authentication handler with the relevant configurations. +// Create a Basic authentication handler with the relevant configurations. auth:ConfigAuthStoreProvider basicAuthProvider = new; http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); diff --git a/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal b/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal index acbc1e3affcb..eff2280e5287 100644 --- a/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal +++ b/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal @@ -38,8 +38,8 @@ public function main() { } } -// Create a JWT authentication provider with the relevant configuration -// parameters. +// Create a JWT authentication provider with the relevant configurations. +// auth:JWTAuthProvider jwtAuthProvider = new({ issuer: "ballerina", audience: ["ballerina.io"], @@ -50,7 +50,7 @@ auth:JWTAuthProvider jwtAuthProvider = new({ } }); -// Create a JWT authentication handler with the created JWT auth provider +// Create a JWT authentication handler with the created JWT auth provider. http:JwtAuthnHandler jwtAuthnHandler = new(jwtAuthProvider); listener http:Listener ep = new(9090, config = { diff --git a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal index 0e90591f913a..cca73077c9fc 100644 --- a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal +++ b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal @@ -2,20 +2,19 @@ import ballerina/auth; import ballerina/http; import ballerina/log; -// Create a Basic authentication handler with the relevant configuration -// parameters. +// Create a Basic authentication handler with the relevant configurations. auth:ConfigAuthStoreProvider basicAuthProvider = new; http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); -// The endpoint used here is `http:Listener`, which by default tries to -// authenticate and authorize each request. The developer has the option to -// override the authentication and authorization at the service level and +// The endpoint used here is the `http:Listener`, which by default tries to +// authenticate and authorize each request. It is optional to +// override the authentication and authorization at the service level and/or // resource level. listener http:Listener ep = new(9090, config = { auth: { authnHandlers: [basicAuthnHandler] }, - // The secure hello world sample uses https. + // The secure hello world sample uses HTTPS. secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -30,10 +29,10 @@ listener http:Listener ep = new(9090, config = { scopes: ["scope1"] } } -// Auth configuration comprises of two parts - authentication & authorization. +// The Auth configuration comprises of two parts - authentication & authorization. // Authentication can be disabled by setting the `enabled: false` annotation -// attribute, if needed. -// Authorization is based on scopes, where a scope maps to one or more groups. +// attribute. +// Authorization is based on scopes. A scope maps to one or more groups. // For a user to access a resource, the user should be in the same groups as // the scope. // To specify one or more scopes of a resource, the `scopes` annotation @@ -47,11 +46,11 @@ service echo on ep { scopes: ["scope2"] } } - // The authentication and authorization settings can be overridden at + // The authentication and authorization settings can be overridden at the // resource level. // The hello resource would inherit the `enabled: true` flag from the - // service level which is set automatically, and override the scope - // defined in the service level (i.e., scope1) with scope2. + // service level, which is set automatically. The service level scope (i.e., scope1) will be overridden + // by the scope defined in the resource level (i.e., scope2). resource function hello(http:Caller caller, http:Request req) { error? result = caller->respond("Hello, World!!!"); if (result is error) { diff --git a/examples/secured-service-with-jwt/secured_service_with_jwt.bal b/examples/secured-service-with-jwt/secured_service_with_jwt.bal index 32bdc5f4c060..aafa961ec486 100644 --- a/examples/secured-service-with-jwt/secured_service_with_jwt.bal +++ b/examples/secured-service-with-jwt/secured_service_with_jwt.bal @@ -2,8 +2,7 @@ import ballerina/auth; import ballerina/http; import ballerina/log; -// Create a JWT authentication provider with the relevant configuration -// parameters. +// Create a JWT authentication provider with the relevant configurations. auth:JWTAuthProvider jwtAuthProvider = new({ issuer: "ballerina", audience: ["ballerina.io"], @@ -14,18 +13,18 @@ auth:JWTAuthProvider jwtAuthProvider = new({ } }); -// Create a JWT authentication handler with the created JWT auth provider +// Create a JWT authentication handler with the created JWT auth provider. http:JwtAuthnHandler jwtAuthnHandler = new(jwtAuthProvider); -// The endpoint used here is `http:Listener`. The JWT authentication -// handler is set to this endpoint using the `authnHandlers` attribute. The -// developer has the option to override the authentication and authorization +// The endpoint used here is the `http:Listener`. The JWT authentication +// handler is set to this endpoint using the `authnHandlers` attribute. It is optional to +// override the authentication and authorization // at the service and resource levels. listener http:Listener ep = new(9090, config = { auth: { authnHandlers: [jwtAuthnHandler] }, - // The secure hello world sample uses https. + // The secure hello world sample uses HTTPS. secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", @@ -37,9 +36,9 @@ listener http:Listener ep = new(9090, config = { @http:ServiceConfig { basePath: "/hello" } -// Auth configuration comprises of two parts - authentication & authorization. -// Authentication can be disabled by setting the `enabled: false` flag, if needed. -// Authorization is based on scopes, where a scope maps to one or more groups. +// The Auth configuration comprises of two parts - authentication & authorization. +// Authentication can be disabled by setting the `enabled: false` flag. +// Authorization is based on scopes. A scope maps to one or more groups. // For a user to access a resource, the user should be in the same groups as // the scope. // To specify one or more scope of a resource, the annotation attribute @@ -53,10 +52,10 @@ service echo on ep { } } // The authentication and authorization settings can be overridden at - // resource level. + // the resource level. // The hello resource would inherit the `enabled: true` flag from the - // service level which is set automatically, and define `hello` as the - // scope for the resource. + // service level, which is set automatically. + // The scope of the resource is defined as "hello". resource function hello(http:Caller caller, http:Request req) { error? result = caller->respond("Hello, World!!!"); if (result is error) { diff --git a/stdlib/auth/src/main/ballerina/auth/Module.md b/stdlib/auth/src/main/ballerina/auth/Module.md index 9502dd523bac..a8b334562eb8 100644 --- a/stdlib/auth/src/main/ballerina/auth/Module.md +++ b/stdlib/auth/src/main/ballerina/auth/Module.md @@ -1,26 +1,23 @@ ## Module Overview -This module provides a set of default authentication providers that can be extended to create new authentication providers. +This module provides a set of default authentication provider configurations that can be extended to create new authentication providers. ### Authentication Provider -An authentication provider defines an authentication scheme that could be used to protect endpoints. The `auth:AuthStoreProvider` type acts as the interface for all the authentication providers. Any type of implementation, such as LDAP, JDBC, and file based, should be object-wise similar. +An authentication provider defines an authentication scheme that could be used to authenticate endpoints. The `auth:AuthStoreProvider` acts as the interface for all the authentication providers. Any type of implementation such as LDAP, JDBC, and file-based should be object-equivalent. -By default, there are three implementations of the `auth:AuthProvider`. They are; the `auth:ConfigAuthStoreProvider`, - which authenticates based on usernames and passwords stored in a configuration file; the `auth:JWTAuthProvider`, which - authenticates by validating a JWT; and finally the `auth:LdapAuthStoreProvider`, which authenticates based on the user credentials stored in an active directory or an LDAP. -When creating a new authentication provider, there is a function that need to be implemented. +When creating a new authentication provider, there is a function that needs to be implemented. - `authenticate` : Authenticates the user based on a credential, which can be username/password, or a token such as JWT. ### Config Auth Store Provider -`auth:ConfigAuthStoreProvider` is an implementation of the `auth:AuthProvider` interface, which uses the Ballerina configuration file - to store usernames, passwords, scopes and the relevant associations. +The `auth:ConfigAuthStoreProvider` is an implementation of the `auth:AuthProvider` interface, which uses the Ballerina configuration file + to store usernames, passwords, scopes, and relevant associations. A user is denoted by a section in the configuration file. The password and the scopes assigned to the user are denoted - as keys under the relevant user section as seen below. + as keys under the relevant user section as shown below. ``` [b7a.users.] @@ -30,8 +27,8 @@ A user is denoted by a section in the configuration file. The password and the s ### LDAP Auth Store Provider -`auth:LdapAuthStoreProvider` is another implementation of the `auth:AuthProvider` interface, which connects to an active directory or an LDAP to retrieve the necessary user information to perform authentication and authorization. +The `auth:LdapAuthStoreProvider` is another implementation of the `auth:AuthProvider` interface. This connects to an active directory or an LDAP, retrieves the necessary user information, and performs authentication and authorization. ### JWT Auth Provider -`auth:JWTAuthProvider` is another implementation of the `auth:AuthProvider` interface, which authenticate by validating a JWT. +The `auth:JWTAuthProvider` is another implementation of the `auth:AuthProvider` interface, which authenticates by validating a JWT. From 462f7d3e07035e2a759f46534cfa7eefebfc7c9d Mon Sep 17 00:00:00 2001 From: praneesha Date: Mon, 29 Apr 2019 13:27:44 +0530 Subject: [PATCH 35/52] Apply suggestions from code review Co-Authored-By: ldclakmal --- stdlib/auth/src/main/ballerina/auth/Module.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stdlib/auth/src/main/ballerina/auth/Module.md b/stdlib/auth/src/main/ballerina/auth/Module.md index a8b334562eb8..608565087713 100644 --- a/stdlib/auth/src/main/ballerina/auth/Module.md +++ b/stdlib/auth/src/main/ballerina/auth/Module.md @@ -6,7 +6,10 @@ This module provides a set of default authentication provider configurations tha An authentication provider defines an authentication scheme that could be used to authenticate endpoints. The `auth:AuthStoreProvider` acts as the interface for all the authentication providers. Any type of implementation such as LDAP, JDBC, and file-based should be object-equivalent. - credentials stored in an active directory or an LDAP. +By default, there are three implementations of the `auth:AuthProvider`. They are: +1. The `auth:ConfigAuthStoreProvider`, which authenticates based on usernames and passwords stored in a configuration file. +2. The `auth:JWTAuthProvider`, which authenticates by validating a JWT. +3. The `auth:LdapAuthStoreProvider`, which authenticates based on the user credentials stored in an active directory or an LDAP. When creating a new authentication provider, there is a function that needs to be implemented. - `authenticate` : Authenticates the user based on a credential, which can be username/password, or a token such as JWT. From 9ee5e4e1606ec736c771cc90743adab9456d7f08 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Mon, 29 Apr 2019 13:37:14 +0530 Subject: [PATCH 36/52] Reformat code comments --- .../secured_client_with_jwt_auth.bal | 1 - .../secured_service_with_basic_auth.bal | 10 +++++----- .../secured_service_with_jwt.bal | 6 +++--- stdlib/auth/src/main/ballerina/auth/Module.md | 6 ++---- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal b/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal index eff2280e5287..dd18072de726 100644 --- a/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal +++ b/examples/secured-client-with-jwt-auth/secured_client_with_jwt_auth.bal @@ -39,7 +39,6 @@ public function main() { } // Create a JWT authentication provider with the relevant configurations. -// auth:JWTAuthProvider jwtAuthProvider = new({ issuer: "ballerina", audience: ["ballerina.io"], diff --git a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal index cca73077c9fc..f8ba9b8f6ba6 100644 --- a/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal +++ b/examples/secured-service-with-basic-auth/secured_service_with_basic_auth.bal @@ -7,9 +7,8 @@ auth:ConfigAuthStoreProvider basicAuthProvider = new; http:BasicAuthnHandler basicAuthnHandler = new(basicAuthProvider); // The endpoint used here is the `http:Listener`, which by default tries to -// authenticate and authorize each request. It is optional to -// override the authentication and authorization at the service level and/or -// resource level. +// authenticate and authorize each request. It is optional to override the +// authentication and authorization at the service level and/or resource level. listener http:Listener ep = new(9090, config = { auth: { authnHandlers: [basicAuthnHandler] @@ -49,8 +48,9 @@ service echo on ep { // The authentication and authorization settings can be overridden at the // resource level. // The hello resource would inherit the `enabled: true` flag from the - // service level, which is set automatically. The service level scope (i.e., scope1) will be overridden - // by the scope defined in the resource level (i.e., scope2). + // service level, which is set automatically. The service level scope + // (i.e., scope1) will be overridden by the scope defined in the resource + // level (i.e., scope2). resource function hello(http:Caller caller, http:Request req) { error? result = caller->respond("Hello, World!!!"); if (result is error) { diff --git a/examples/secured-service-with-jwt/secured_service_with_jwt.bal b/examples/secured-service-with-jwt/secured_service_with_jwt.bal index aafa961ec486..c94775064e5c 100644 --- a/examples/secured-service-with-jwt/secured_service_with_jwt.bal +++ b/examples/secured-service-with-jwt/secured_service_with_jwt.bal @@ -17,9 +17,9 @@ auth:JWTAuthProvider jwtAuthProvider = new({ http:JwtAuthnHandler jwtAuthnHandler = new(jwtAuthProvider); // The endpoint used here is the `http:Listener`. The JWT authentication -// handler is set to this endpoint using the `authnHandlers` attribute. It is optional to -// override the authentication and authorization -// at the service and resource levels. +// handler is set to this endpoint using the `authnHandlers` attribute. +// It is optional to override the authentication and authorization at the +// service and resource levels. listener http:Listener ep = new(9090, config = { auth: { authnHandlers: [jwtAuthnHandler] diff --git a/stdlib/auth/src/main/ballerina/auth/Module.md b/stdlib/auth/src/main/ballerina/auth/Module.md index 608565087713..1104e3b2ebc5 100644 --- a/stdlib/auth/src/main/ballerina/auth/Module.md +++ b/stdlib/auth/src/main/ballerina/auth/Module.md @@ -16,11 +16,9 @@ When creating a new authentication provider, there is a function that needs to b ### Config Auth Store Provider -The `auth:ConfigAuthStoreProvider` is an implementation of the `auth:AuthProvider` interface, which uses the Ballerina configuration file - to store usernames, passwords, scopes, and relevant associations. +The `auth:ConfigAuthStoreProvider` is an implementation of the `auth:AuthProvider` interface, which uses the Ballerina configuration file to store usernames, passwords, scopes, and relevant associations. -A user is denoted by a section in the configuration file. The password and the scopes assigned to the user are denoted - as keys under the relevant user section as shown below. +A user is denoted by a section in the configuration file. The password and the scopes assigned to the user are denoted as keys under the relevant user section as shown below. ``` [b7a.users.] From 9dda945186a3ea7339255a7bc43a62a60fccffc9 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Tue, 30 Apr 2019 15:26:54 +0530 Subject: [PATCH 37/52] Refactored errors of auth modules --- .../main/ballerina/auth/jwt/jwt_issuer.bal | 17 +++----- .../main/ballerina/auth/jwt/jwt_validator.bal | 40 ++++++------------- stdlib/auth/src/main/ballerina/auth/utils.bal | 15 +++++-- 3 files changed, 30 insertions(+), 42 deletions(-) diff --git a/stdlib/auth/src/main/ballerina/auth/jwt/jwt_issuer.bal b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_issuer.bal index 07abfbb737bf..06ddf80f089b 100644 --- a/stdlib/auth/src/main/ballerina/auth/jwt/jwt_issuer.bal +++ b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_issuer.bal @@ -66,19 +66,14 @@ public function issueJwt(JwtHeader header, JwtPayload payload, JWTIssuerConfig? signature = encoding:encodeBase64Url(check crypto:signRsaSha512(jwtAssertion.toByteArray("UTF-8"), privateKey)); } else { - error jwtError = error(AUTH_ERROR_CODE, { message : "Unsupported JWS algorithm" }); - return jwtError; + return prepareError("Unsupported JWS algorithm."); } return (jwtAssertion + "." + signature); } else { - error jwtError = error(AUTH_ERROR_CODE, - { message : "Signing JWT requires keyStore, keyAlias and keyPassword" }); - return jwtError; + return prepareError("Signing JWT requires keyStore, keyAlias and keyPassword."); } } else { - error jwtError = error(AUTH_ERROR_CODE, - { message : "Signing JWT requires JWTIssuerConfig with keystore information" }); - return jwtError; + return prepareError("Signing JWT requires JWTIssuerConfig with keystore information."); } } } @@ -86,8 +81,7 @@ public function issueJwt(JwtHeader header, JwtPayload payload, JWTIssuerConfig? function buildHeaderString(JwtHeader header) returns (string|error) { json headerJson = {}; if (!validateMandatoryJwtHeaderFields(header)) { - error jwtError = error(AUTH_ERROR_CODE, { message : "Mandatory field signing algorithm (alg) is empty." }); - return jwtError; + return prepareError("Mandatory field signing algorithm (alg) is empty."); } if (header.alg == RS256) { headerJson[ALG] = "RS256"; @@ -98,8 +92,7 @@ function buildHeaderString(JwtHeader header) returns (string|error) { } else if (header.alg == NONE) { headerJson[ALG] = "none"; } else { - error jwtError = error(AUTH_ERROR_CODE, { message : "Unsupported JWS algorithm" }); - return jwtError; + return prepareError("Unsupported JWS algorithm."); } headerJson[TYP] = "JWT"; string headerValInString = headerJson.toString(); diff --git a/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal index 76d3e510e0b3..b2d1a624bb8a 100644 --- a/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal +++ b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal @@ -68,8 +68,7 @@ public function validateJwt(string jwtToken, JWTValidatorConfig config) returns if (jwtValidity) { return payload; } else { - error jwtError = error(AUTH_ERROR_CODE, { message : "Invalid JWT token" }); - return jwtError; + return prepareError("Invalid JWT token."); } } } @@ -77,8 +76,7 @@ public function validateJwt(string jwtToken, JWTValidatorConfig config) returns function getJWTComponents(string jwtToken) returns (string[])|error { string[] jwtComponents = jwtToken.split("\\."); if (jwtComponents.length() < 2 || jwtComponents.length() > 3) { - error jwtError = error(AUTH_ERROR_CODE, { message : "Invalid JWT token" }); - return jwtError; + return prepareError("Invalid JWT token."); } return jwtComponents; } @@ -196,16 +194,14 @@ function parsePayload(json jwtPayloadJson) returns (JwtPayload) { function validateJwtRecords(string[] encodedJWTComponents, JwtHeader jwtHeader, JwtPayload jwtPayload, JWTValidatorConfig config) returns (boolean|error) { if (!validateMandatoryJwtHeaderFields(jwtHeader)) { - error jwtError = error(AUTH_ERROR_CODE, - { message : "Mandatory field signing algorithm(alg) is empty in the given JSON Web Token." }); + return prepareError("Mandatory field signing algorithm(alg) is empty in the given JWT."); return jwtError; } if (config["validateCertificate"] is ()) { config.validateCertificate = true; } if (config.validateCertificate == true && !check validateCertificate(config)) { - error jwtError = error(AUTH_ERROR_CODE, { message : "Public key certificate validity period has passed" }); - return jwtError; + return prepareError("Public key certificate validity period has passed."); } var trustStore = config["trustStore"]; if (trustStore is crypto:TrustStore) { @@ -231,15 +227,13 @@ function validateJwtRecords(string[] encodedJWTComponents, JwtHeader jwtHeader, var exp = jwtPayload["exp"]; if (exp is int) { if (!validateExpirationTime(jwtPayload, config)) { - error jwtError = error(AUTH_ERROR_CODE, { message : "JWT token is expired" }); - return jwtError; + return prepareError("JWT token is expired."); } } var nbf = jwtPayload["nbf"]; if (nbf is int) { if (!validateNotBeforeTime(jwtPayload)) { - error jwtError = error(AUTH_ERROR_CODE, { message : "JWT token is used before Not_Before_Time" }); - return jwtError; + return prepareError("JWT token is used before Not_Before_Time."); } } //TODO : Need to validate jwt id (jti) and custom claims. @@ -273,12 +267,10 @@ function validateCertificate(JWTValidatorConfig config) returns boolean|error { function validateSignature(string[] encodedJWTComponents, JwtHeader jwtHeader, JWTValidatorConfig config) returns boolean|error { if (jwtHeader.alg == NONE) { - error jwtError = error(AUTH_ERROR_CODE, { message : "Not a valid JWS. Signature algorithm is NONE." }); - return jwtError; + return prepareError("Not a valid JWS. Signature algorithm is NONE."); } else { if (encodedJWTComponents.length() == 2) { - error jwtError = error(AUTH_ERROR_CODE, { message : "Not a valid JWS. Signature is required." }); - return jwtError; + return prepareError("Not a valid JWS. Signature is required."); } else { string assertion = encodedJWTComponents[0] + "." + encodedJWTComponents[1]; byte[] signPart = check encoding:decodeBase64Url(encodedJWTComponents[2]); @@ -291,8 +283,7 @@ returns boolean|error { } else if (jwtHeader.alg == RS512) { return crypto:verifyRsaSha512Signature(assertion.toByteArray("UTF-8"), signPart, publicKey); } else { - error jwtError = error(AUTH_ERROR_CODE, { message : "Unsupported JWS algorithm" }); - return jwtError; + return prepareError("Unsupported JWS algorithm."); } } } @@ -302,13 +293,10 @@ function validateIssuer(JwtPayload jwtPayload, JWTValidatorConfig config) return var iss = jwtPayload["iss"]; if (iss is string) { if(jwtPayload.iss != config.issuer) { - error jwtError = error(AUTH_ERROR_CODE, { message : "JWT contained invalid issuer name : " + - jwtPayload.iss }); - return jwtError; + return prepareError("JWT contained invalid issuer name : " + jwtPayload.iss); } } else { - error jwtError = error(AUTH_ERROR_CODE, { message : "JWT must contain a valid issuer name" }); - return jwtError; + return prepareError("JWT must contain a valid issuer name."); } } @@ -328,12 +316,10 @@ function validateAudience(JwtPayload jwtPayload, JWTValidatorConfig config) retu } } if (!validationStatus) { - error jwtError = error(AUTH_ERROR_CODE, { message : "Invalid audience" }); - return jwtError; + return prepareError("Invalid audience."); } } else { - error jwtError = error(AUTH_ERROR_CODE, { message : "JWT must contain a valid audience" }); - return jwtError; + return prepareError("JWT must contain a valid audience."); } } diff --git a/stdlib/auth/src/main/ballerina/auth/utils.bal b/stdlib/auth/src/main/ballerina/auth/utils.bal index 120f4cfee3bb..add0ccb59c94 100644 --- a/stdlib/auth/src/main/ballerina/auth/utils.bal +++ b/stdlib/auth/src/main/ballerina/auth/utils.bal @@ -45,10 +45,19 @@ function extractUsernameAndPassword(string credential) returns (string, string)| string decodedHeaderValue = encoding:byteArrayToString(check encoding:decodeBase64(credential)); string[] decodedCredentials = decodedHeaderValue.split(":"); if (decodedCredentials.length() != 2) { - error err = error(AUTH_ERROR_CODE, - { message: "Incorrect credential format. Format should be username:password" }); - return err; + return prepareError("Incorrect credential format. Format should be username:password"); } else { return (decodedCredentials[0], decodedCredentials[1]); } } + +# Log, prepare and return the `error`. +# +# + message - Error message +# + err - `error` instance +# + return - Prepared `error` instance +function prepareError(string message, error? err = ()) returns error { + log:printError(function () returns string { return message; }); + error preparedError = error(AUTH_ERROR_CODE, { message: message, reason: err.reason() }); + return preparedError; +} From 63aad99bb32362ed2706de12fc42b08d725a8909 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Tue, 30 Apr 2019 15:29:02 +0530 Subject: [PATCH 38/52] Improve error scenarios of auth filters --- .../main/ballerina/http/auth/authn_filter.bal | 50 +++++++++++++------ .../ballerina/http/auth/authn_handler.bal | 8 +-- .../main/ballerina/http/auth/authz_filter.bal | 37 +++++++++----- .../ballerina/http/auth/authz_handler.bal | 5 +- .../http/auth/basic_authn_handler.bal | 25 ++++------ .../ballerina/http/auth/jwt_authn_handler.bal | 45 ++++++----------- .../src/main/ballerina/http/auth/utils.bal | 11 ++-- 7 files changed, 96 insertions(+), 85 deletions(-) diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal index d5dd51a308f0..0cfb1ee0c0a9 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal @@ -35,13 +35,15 @@ public type AuthnFilter object { # + context - A filter context # + return - True if the filter succeeds public function filterRequest(Caller caller, Request request, FilterContext context) returns boolean { - boolean authenticated = true; + boolean|error authenticated; var authnHandlers = getAuthnHandlers(context); if (authnHandlers is AuthnHandler[]) { authenticated = handleAuthnRequest(authnHandlers, request); } else { if (authnHandlers) { authenticated = handleAuthnRequest(self.authnHandlers, request); + } else { + authenticated = true; } } return isAuthnSuccessful(caller, authenticated); @@ -52,16 +54,25 @@ public type AuthnFilter object { } }; -function handleAuthnRequest(AuthnHandler[] authnHandlers, Request request) returns boolean { +function handleAuthnRequest(AuthnHandler[] authnHandlers, Request request) returns boolean|error { foreach AuthnHandler authnHandler in authnHandlers { - if (authnHandler.canHandle(request)) { - boolean authnSuccessful = authnHandler.handle(request); - if (authnSuccessful) { - // If one of the authenticators from the chain could successfully authenticate the user, it is not - // required to look through other providers. The authenticator chain is using "OR" combination of - // provider results. - return true; + var canHandleResponse = authnHandler.canHandle(request); + if (canHandleResponse is boolean) { + if (canHandleResponse) { + var handleResponse = authnHandler.handle(request); + if (handleResponse is boolean) { + if (handleResponse) { + // If one of the authenticators from the chain could successfully authenticate the user, it is not + // required to look through other providers. The authenticator chain is using "OR" combination of + // provider results. + return true; + } + } else { + return handleResponse; + } } + } else { + return canHandleResponse; } } return false; @@ -70,13 +81,22 @@ function handleAuthnRequest(AuthnHandler[] authnHandlers, Request request) retur # Verifies if the authentication is successful. If not responds to the user. # # + caller - Caller for outbound HTTP responses -# + authenticated - Authorization status for the request -# + return - Authorization result to indicate if the filter can proceed(true) or not(false) -function isAuthnSuccessful(Caller caller, boolean authenticated) returns boolean { +# + authenticated - Authentication status for the request, or `error` if error occured +# + return - Authentication result to indicate if the filter can proceed(true) or not(false) +function isAuthnSuccessful(Caller caller, boolean|error authenticated) returns boolean { Response response = new; - if (!authenticated) { - response.statusCode = 401; - response.setTextPayload("Authentication failure"); + response.statusCode = 401; + if (authenticated is boolean) { + if (!authenticated) { + response.setTextPayload("Authentication failure"); + var err = caller->respond(response); + if (err is error) { + panic err; + } + return false; + } + } else { + response.setTextPayload("Authentication failure. " + authenticated.reason()); var err = caller->respond(response); if (err is error) { panic err; diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal index 7f8865482af9..edc00b49c357 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal @@ -20,12 +20,12 @@ public type AuthnHandler abstract object { # Checks if the request can be authenticated with the relevant `HttpAuthnHandler` implementation # # + req - `Request` instance - # + return - true if can be authenticated, else false - public function canHandle(Request req) returns boolean; + # + return - `true` if can be authenticated, else `false` or, `error` in case of errors + public function canHandle(Request req) returns boolean|error; # Tries to authenticate the request with the relevant `HttpAuthnHandler` implementation # # + req - `Request` instance - # + return - true if authenticated successfully, else false - public function handle(Request req) returns boolean; + # + return - `true` if authenticated successfully, else `false` or, `error` in case of errors + public function handle(Request req) returns boolean|error; }; diff --git a/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal index 5de58725d104..d71c3b31e7be 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authz_filter.bal @@ -39,7 +39,7 @@ public type AuthzFilter object { # + context - `FilterContext` instance # + return - A flag to indicate if the request flow should be continued(true) or aborted(false), a code and a message public function filterRequest(Caller caller, Request request, FilterContext context) returns boolean { - boolean authorized = true; + boolean|error authorized; var scopes = getScopes(context); if (scopes is string[]) { authorized = handleAuthzRequest(self.authzHandler, request, context, scopes); @@ -48,7 +48,11 @@ public type AuthzFilter object { var selfScopes = self.scopes; if (selfScopes is string[]) { authorized = handleAuthzRequest(self.authzHandler, request, context, selfScopes); + } else { + authorized = true; } + } else { + authorized = true; } } return isAuthzSuccessful(caller, authorized); @@ -59,14 +63,15 @@ public type AuthzFilter object { } }; -function handleAuthzRequest(AuthzHandler authzHandler, Request request, FilterContext context, string[] scopes) returns boolean { - boolean authorized = true; +function handleAuthzRequest(AuthzHandler authzHandler, Request request, FilterContext context, string[] scopes) returns boolean|error { + boolean|error authorized; if (scopes.length() > 0) { - if (authzHandler.canHandle(request)) { + var canHandleResponse = authzHandler.canHandle(request); + if (canHandleResponse is boolean && canHandleResponse) { authorized = authzHandler.handle(runtime:getInvocationContext().principal.username, context.serviceName, context.resourceName, request.method, scopes); } else { - authorized = false; + authorized = canHandleResponse; } } else { // scopes are not defined, no need to authorize @@ -78,14 +83,22 @@ function handleAuthzRequest(AuthzHandler authzHandler, Request request, FilterCo # Verifies if the authorization is successful. If not responds to the user. # # + caller - Caller for outbound HTTP responses -# + authorized - flag to indicate if authorization is successful or not -# + return - A boolean flag to indicate if the request flow should be continued(true) or -# aborted(false) -function isAuthzSuccessful(Caller caller, boolean authorized) returns boolean { +# + authorized - Authorization status for the request, or `error` if error occured +# + return - Authorization result to indicate if the filter can proceed(true) or not(false) +function isAuthzSuccessful(Caller caller, boolean|error authorized) returns boolean { Response response = new; - if (!authorized) { - response.statusCode = 403; - response.setTextPayload("Authorization failure"); + response.statusCode = 403; + if (authorized is boolean) { + if (!authorized) { + response.setTextPayload("Authorization failure"); + var err = caller->respond(response); + if (err is error) { + panic err; + } + return false; + } + } else { + response.setTextPayload("Authorization failure. " + authorized.reason()); var err = caller->respond(response); if (err is error) { panic err; diff --git a/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal b/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal index 7c97ae25c89f..0a6db414ad3e 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal @@ -153,10 +153,9 @@ function matchScopes(string[] resourceScopes, string[] userScopes) returns boole return true; } -function AuthzHandler.canHandle(Request req) returns boolean { +function AuthzHandler.canHandle(Request req) returns boolean|error { if (runtime:getInvocationContext().principal.username.length() == 0) { - log:printError("Username not set in auth context. Unable to authorize"); - return false; + return prepareError("Username not set in auth context. Unable to authorize."); } return true; } diff --git a/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal index a309b66f99b3..51bc275e4b0d 100644 --- a/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal @@ -36,32 +36,27 @@ public type BasicAuthnHandler object { # Checks if the provided request can be authenticated with basic auth. # # + req - Request object -# + return - `true` if it is possible authenticate with basic auth, else `false` -public function BasicAuthnHandler.handle(Request req) returns boolean { +# + return - `true` if it is possible authenticate with basic auth, else `false`, or `error` in case of errors +public function BasicAuthnHandler.handle(Request req) returns boolean|error { // extract the header value - var basicAuthHeader = extractBasicAuthHeaderValue(req); + var basicAuthHeader = extractAuthorizationHeaderValue(req); if (basicAuthHeader is string) { string credential = basicAuthHeader.substring(5, basicAuthHeader.length()).trim(); - var authenticated = self.authProvider.authenticate(credential); - if (authenticated is boolean) { - return authenticated; - } else { - log:printError("Error while authenticating with BasicAuthnHandler", err = authenticated); - } + return self.authProvider.authenticate(credential); } else { - log:printError("Error in extracting basic authentication header"); + return basicAuthHeader; } - return false; } # Intercept requests for authentication. # # + req - Request object -# + return - `true` if authentication is a success, else `false` -public function BasicAuthnHandler.canHandle(Request req) returns boolean { - var basicAuthHeader = trap req.getHeader(AUTH_HEADER); +# + return - `true` if authentication is a success, else `false`, or `error` in case of errors +public function BasicAuthnHandler.canHandle(Request req) returns boolean|error { + var basicAuthHeader = extractAuthorizationHeaderValue(req); if (basicAuthHeader is string) { return basicAuthHeader.hasPrefix(AUTH_SCHEME_BASIC); + } else { + return basicAuthHeader; } - return false; } diff --git a/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal index d607bd3c7315..12d43a939f54 100644 --- a/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal @@ -34,45 +34,32 @@ public type JwtAuthnHandler object { # Checks if the request can be authenticated with JWT # # + req - `Request` instance -# + return - true if can be authenticated, else false -public function JwtAuthnHandler.canHandle(Request req) returns boolean { - string authHeader = ""; - var headerValue = trap req.getHeader(AUTH_HEADER); +# + return - `true` if can be authenticated, else `false`, or `error` in case of errors +public function JwtAuthnHandler.canHandle(Request req) returns boolean|error { + var headerValue = extractAuthorizationHeaderValue(req); if (headerValue is string) { - authHeader = headerValue; - } else { - string reason = headerValue.reason(); - log:printDebug(function () returns string { - return "Error in retrieving header " + AUTH_HEADER + ": " + reason; - }); - return false; - } - - if (authHeader.hasPrefix(AUTH_SCHEME_BEARER)) { - string[] authHeaderComponents = authHeader.split(" "); - if (authHeaderComponents.length() == 2) { - string[] jwtComponents = authHeaderComponents[1].split("\\."); - if (jwtComponents.length() == 3) { - return true; + if (headerValue.hasPrefix(AUTH_SCHEME_BEARER)) { + string[] authHeaderComponents = headerValue.split(" "); + if (authHeaderComponents.length() == 2) { + string[] jwtComponents = authHeaderComponents[1].split("\\."); + if (jwtComponents.length() == 3) { + return true; + } } } + return false; + } else { + return headerValue; } - return false; } # Authenticates the incoming request using JWT authentication # # + req - `Request` instance -# + return - true if authenticated successfully, else false -public function JwtAuthnHandler.handle(Request req) returns boolean { +# + return - `true` if authenticated successfully, else `false`, or `error` in case of errors +public function JwtAuthnHandler.handle(Request req) returns boolean|error { string jwtToken = extractJWTToken(req); - var authenticated = self.authProvider.authenticate(jwtToken); - if (authenticated is boolean) { - return authenticated; - } else { - log:printError("Error while validating JWT token", err = authenticated); - } - return false; + return self.authProvider.authenticate(jwtToken); } function extractJWTToken(Request req) returns string { diff --git a/stdlib/http/src/main/ballerina/http/auth/utils.bal b/stdlib/http/src/main/ballerina/http/auth/utils.bal index 749901c44d5c..b80a3b1622fb 100644 --- a/stdlib/http/src/main/ballerina/http/auth/utils.bal +++ b/stdlib/http/src/main/ballerina/http/auth/utils.bal @@ -43,20 +43,17 @@ public const OAUTH2 = "OAUTH2"; # JWT authentication scheme. public const JWT_AUTH = "JWT_AUTH"; -# Extracts the basic authentication header value from the request. +# Extracts the Authorization header value from the request. # # + req - Request instance -# + return - Value of the basic authentication header, or nil if not found -public function extractBasicAuthHeaderValue(Request req) returns string? { +# + return - Value of the basic authentication header, or `error` in case of errors +public function extractAuthorizationHeaderValue(Request req) returns string|error { // extract authorization header var headerValue = trap req.getHeader(AUTH_HEADER); if (headerValue is string) { return headerValue; } else { - string reason = headerValue.reason(); - log:printDebug(function () returns string { - return "Error in retrieving header " + AUTH_HEADER + ": " + reason; - }); + return prepareError("Error in retrieving header - " + AUTH_HEADER, err = headerValue); } } From 975e854c96c5470a474ed2e6172f2a58fad0705f Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Tue, 30 Apr 2019 15:39:50 +0530 Subject: [PATCH 39/52] Fix a bug --- stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal | 1 - stdlib/http/src/main/ballerina/http/auth/authz_handler.bal | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal index b2d1a624bb8a..f59572241c60 100644 --- a/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal +++ b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal @@ -195,7 +195,6 @@ function validateJwtRecords(string[] encodedJWTComponents, JwtHeader jwtHeader, JWTValidatorConfig config) returns (boolean|error) { if (!validateMandatoryJwtHeaderFields(jwtHeader)) { return prepareError("Mandatory field signing algorithm(alg) is empty in the given JWT."); - return jwtError; } if (config["validateCertificate"] is ()) { config.validateCertificate = true; diff --git a/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal b/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal index 0a6db414ad3e..e9071b77505d 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authz_handler.bal @@ -36,8 +36,8 @@ public type AuthzHandler object { # Checks if the request can be authorized # # + req - `Request` instance - # + return - true if can be authorized, else false - function canHandle(Request req) returns boolean; + # + return - `true` if can be authorized, else `false`, or `error` if error occured + function canHandle(Request req) returns boolean|error; # Tries to authorize the request # From 04bed90381282fd0931ec16664148c748b97d9b4 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Tue, 30 Apr 2019 15:40:19 +0530 Subject: [PATCH 40/52] Add warn logs for auth disabling --- stdlib/http/src/main/ballerina/http/auth/utils.bal | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stdlib/http/src/main/ballerina/http/auth/utils.bal b/stdlib/http/src/main/ballerina/http/auth/utils.bal index b80a3b1622fb..8d5e6dfd31ce 100644 --- a/stdlib/http/src/main/ballerina/http/auth/utils.bal +++ b/stdlib/http/src/main/ballerina/http/auth/utils.bal @@ -73,6 +73,7 @@ function getAuthnHandlers(FilterContext context) returns AuthnHandler[]|boolean // if resource is not secured, no need to check further if (!resourceSecured) { + log:printWarn("Resource is not secured. `enabled: false`."); return false; } // check if auth providers are given at resource level @@ -87,6 +88,7 @@ function getAuthnHandlers(FilterContext context) returns AuthnHandler[]|boolean // if service is not secured, no need to check further if (!serviceSecured) { + log:printWarn("Service is not secured. `enabled: false`."); return true; } // no auth providers found in resource level, try in service level From b10bcc24d52d393960537e2b196ad83185cf2411 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Wed, 1 May 2019 19:43:15 +0530 Subject: [PATCH 41/52] Fix unit tests --- .../ballerinalang/stdlib/auth/jwt/JwtTest.java | 4 ++-- .../stdlib/auth/BasicAuthnHandlerTest.java | 10 +++++----- .../stdlib/auth/JWTAuthnHandlerTest.java | 4 ++-- .../test-src/auth/basic-authn-handler-test.bal | 16 ++++++++-------- .../test-src/auth/jwt-authn-handler-test.bal | 8 ++++---- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/jwt/JwtTest.java b/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/jwt/JwtTest.java index 0099f3c59195..e216c39073bb 100644 --- a/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/jwt/JwtTest.java +++ b/stdlib/auth/src/test/java/org/ballerinalang/stdlib/auth/jwt/JwtTest.java @@ -145,7 +145,7 @@ public void testCompleteValidatorWithNoIssOrSubNegative() { BValue[] returns = BRunUtil.invoke(compileResult, "testValidateJwt", inputBValues); Assert.assertTrue((returns[0]) instanceof BError); Assert.assertEquals(((BMap) ((BError) returns[0]).getDetails()).get(Constants.MESSAGE).stringValue(), - "JWT must contain a valid issuer name"); + "JWT must contain a valid issuer name."); } @Test(priority = 2, description = "Test case for validating JWT token without issuer or subject information, " + @@ -155,7 +155,7 @@ public void testCompleteValidatorWithNoAudOrSubNegative() { BValue[] returns = BRunUtil.invoke(compileResult, "testValidateJwt", inputBValues); Assert.assertTrue((returns[0]) instanceof BError); Assert.assertEquals(((BMap) ((BError) returns[0]).getDetails()).get(Constants.MESSAGE).stringValue(), - "JWT must contain a valid audience"); + "JWT must contain a valid audience."); } @Test(priority = 2, description = "Test case for validating JWT token without issuer or subject information, " + diff --git a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java index 72fa4e8ce809..0977b1df244e 100644 --- a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java +++ b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java @@ -23,6 +23,8 @@ import org.ballerinalang.launcher.util.BRunUtil; import org.ballerinalang.launcher.util.CompileResult; import org.ballerinalang.model.values.BBoolean; +import org.ballerinalang.model.values.BError; +import org.ballerinalang.model.values.BString; import org.ballerinalang.model.values.BValue; import org.testng.Assert; import org.testng.annotations.AfterClass; @@ -72,8 +74,7 @@ private void copySecretFile(String from, String to) throws IOException { @Test(description = "Test case for basic auth interceptor canHandle method, without the basic auth header") public void testCanHandleHttpBasicAuthWithoutHeader() { BValue[] returns = BRunUtil.invoke(compileResult, "testCanHandleHttpBasicAuthWithoutHeader"); - Assert.assertTrue(returns[0] instanceof BBoolean); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertTrue(returns[0] instanceof BError); } @Test(description = "Test case for basic auth interceptor canHandle method") @@ -100,14 +101,13 @@ public void testHandleHttpBasicAuth() { @Test(description = "Test case for extracting non existing basic auth header value") public void testNonExistingBasicAuthHeaderValue() { BValue[] returns = BRunUtil.invoke(compileResult, "testNonExistingBasicAuthHeaderValue"); - Assert.assertNotNull(returns); - Assert.assertNull(returns[0]); + Assert.assertTrue(returns[0] instanceof BError); } @Test(description = "Test case for extracting basic auth header value") public void testExtractBasicAuthHeaderValue() { BValue[] returns = BRunUtil.invoke(compileResult, "testExtractBasicAuthHeaderValue"); - Assert.assertNotNull(returns); + Assert.assertTrue(returns[0] instanceof BString); // no error should be returned Assert.assertEquals(returns[0].stringValue(), "Basic aXN1cnU6eHh4"); } diff --git a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/JWTAuthnHandlerTest.java b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/JWTAuthnHandlerTest.java index ae2308c85472..dd0c549817a7 100644 --- a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/JWTAuthnHandlerTest.java +++ b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/JWTAuthnHandlerTest.java @@ -23,6 +23,7 @@ import org.ballerinalang.launcher.util.BRunUtil; import org.ballerinalang.launcher.util.CompileResult; import org.ballerinalang.model.values.BBoolean; +import org.ballerinalang.model.values.BError; import org.ballerinalang.model.values.BInteger; import org.ballerinalang.model.values.BMap; import org.ballerinalang.model.values.BString; @@ -149,8 +150,7 @@ public void testCanHandleHttpJwtAuth() { @Test(description = "Test case for JWT auth interceptor authentication failure") public void testHandleHttpJwtAuthFailure() { BValue[] returns = BRunUtil.invoke(compileResult, "testHandleHttpJwtAuthFailure"); - Assert.assertTrue(returns[0] instanceof BBoolean); - Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); + Assert.assertTrue(returns[0] instanceof BError); } @Test(description = "Test case for JWT auth interceptor authentication success") diff --git a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal index 5a845541e06c..572a3be33a40 100644 --- a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal @@ -1,7 +1,7 @@ import ballerina/auth; import ballerina/http; -function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { +function testCanHandleHttpBasicAuthWithoutHeader() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); @@ -10,7 +10,7 @@ function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { return handler.canHandle(inRequest); } -function testCanHandleHttpBasicAuth() returns boolean { +function testCanHandleHttpBasicAuth() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); @@ -19,7 +19,7 @@ function testCanHandleHttpBasicAuth() returns boolean { return handler.canHandle(inRequest); } -function testHandleHttpBasicAuthFailure() returns boolean { +function testHandleHttpBasicAuthFailure() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); @@ -28,7 +28,7 @@ function testHandleHttpBasicAuthFailure() returns boolean { return handler.handle(inRequest); } -function testHandleHttpBasicAuth() returns boolean { +function testHandleHttpBasicAuth() returns boolean|error { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); @@ -37,18 +37,18 @@ function testHandleHttpBasicAuth() returns boolean { return handler.handle(inRequest); } -function testNonExistingBasicAuthHeaderValue() returns string? { +function testNonExistingBasicAuthHeaderValue() returns string|error { // create dummy request http:Request inRequest = createRequest(); - return http:extractBasicAuthHeaderValue(inRequest); + return http:extractAuthorizationHeaderValue(inRequest); } -function testExtractBasicAuthHeaderValue() returns string? { +function testExtractBasicAuthHeaderValue() returns string|error { // create dummy request http:Request inRequest = createRequest(); string basicAuthHeaderValue = "Basic aXN1cnU6eHh4"; inRequest.setHeader("Authorization", basicAuthHeaderValue); - return http:extractBasicAuthHeaderValue(inRequest); + return http:extractAuthorizationHeaderValue(inRequest); } function createRequest() returns http:Request { diff --git a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal index 3b0fa22a841f..c2bae766d5d3 100644 --- a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal @@ -2,7 +2,7 @@ import ballerina/auth; import ballerina/http; import ballerina/crypto; -function testCanHandleHttpJwtAuthWithoutHeader() returns boolean { +function testCanHandleHttpJwtAuthWithoutHeader() returns boolean|error { http:JwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Basic xxxxxx"; @@ -10,7 +10,7 @@ function testCanHandleHttpJwtAuthWithoutHeader() returns boolean { return handler.canHandle(request); } -function testCanHandleHttpJwtAuth() returns boolean { +function testCanHandleHttpJwtAuth() returns boolean|error { http:JwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Bearer xxx.yyy.zzz"; @@ -18,7 +18,7 @@ function testCanHandleHttpJwtAuth() returns boolean { return handler.canHandle(request); } -function testHandleHttpJwtAuthFailure() returns boolean { +function testHandleHttpJwtAuthFailure() returns boolean|error { http:JwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Bearer xxx.yyy.zzz"; @@ -26,7 +26,7 @@ function testHandleHttpJwtAuthFailure() returns boolean { return handler.handle(request); } -function testHandleHttpJwtAuth(string token, string trustStorePath) returns boolean { +function testHandleHttpJwtAuth(string token, string trustStorePath) returns boolean|error { http:JwtAuthnHandler handler = new(createJwtAuthProvider(trustStorePath)); http:Request request = createRequest(); string authHeaderValue = "Bearer " + token; From d938ed8013451abf1a3d1594fb5c75e2dd876484 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Wed, 1 May 2019 22:52:35 +0530 Subject: [PATCH 42/52] Fix language server tests --- .../completion/function/matchStatementSuggestions4.json | 6 +++--- .../resources/completion/packageimport/packageImport.json | 6 +++--- .../completion/service/serviceBodyCompletion5.json | 6 +++--- .../resources/completion/service/serviceEndpointBind4.json | 6 +++--- .../completion/toplevel/globalVarDefPackageContent.json | 6 +++--- .../completion/toplevel/topLevelPackageContentAccess.json | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/language-server/modules/langserver-core/src/test/resources/completion/function/matchStatementSuggestions4.json b/language-server/modules/langserver-core/src/test/resources/completion/function/matchStatementSuggestions4.json index 243934eeafe0..3bf7b904c742 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/function/matchStatementSuggestions4.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/function/matchStatementSuggestions4.json @@ -6,14 +6,14 @@ "source": "function/source/matchStatementSuggestions4.bal", "items": [ { - "label":"extractBasicAuthHeaderValue(req)", + "label":"extractAuthorizationHeaderValue(req)", "kind":"Function", "detail":"Snippet", "documentation":{ - "left":"Extracts the basic authentication header value from the request.\n" + "left":"Extracts the Authorization header value from the request.\n" }, "sortText":"120", - "insertText":"extractBasicAuthHeaderValue(req) {\n${1:value} \u003d\u003e {${2}}\n}", + "insertText":"extractAuthorizationHeaderValue(req) {\n${1:value} \u003d\u003e {${2}}\n}", "insertTextFormat":"Snippet" }, { diff --git a/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json b/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json index 2ed22652ea93..aacfcc630f2a 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json @@ -6,17 +6,17 @@ "source": "packageimport/source/packageImport.bal", "items": [ { - "label": "extractBasicAuthHeaderValue(http:Request req)(string?)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" } }, "sortText": "121", - "insertText": "extractBasicAuthHeaderValue(${1:req})", + "insertText": "extractAuthorizationHeaderValue(${1:req})", "insertTextFormat": "Snippet" }, { diff --git a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json index dade41d79c1d..159452be9faa 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json @@ -6,17 +6,17 @@ "source": "service/source/serviceBodyCompletion5.bal", "items": [ { - "label": "extractBasicAuthHeaderValue(http:Request req)(string?)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" } }, "sortText": "121", - "insertText": "extractBasicAuthHeaderValue(${1:req})", + "insertText": "extractAuthorizationHeaderValue(${1:req})", "insertTextFormat": "Snippet" }, { diff --git a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json index 3a3bb67f241f..03eca1e17487 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json @@ -6,16 +6,16 @@ "source": "service/source/serviceEndpointBind4.bal", "items": [ { - "label": "extractBasicAuthHeaderValue(http:Request req)(string?)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" } }, - "insertText": "extractBasicAuthHeaderValue(${1:req})", + "insertText": "extractAuthorizationHeaderValue(${1:req})", "insertTextFormat": "Snippet" }, { diff --git a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json index d7fb69fc0f2a..87c19380eea4 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json @@ -6,17 +6,17 @@ "source": "toplevel/source/globalVarDefPackageContent.bal", "items": [ { - "label": "extractBasicAuthHeaderValue(http:Request req)(string?)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" } }, "sortText": "121", - "insertText": "extractBasicAuthHeaderValue(${1:req})", + "insertText": "extractAuthorizationHeaderValue(${1:req})", "insertTextFormat": "Snippet" }, { diff --git a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json index df2864eacf79..e43f3f68c519 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json @@ -6,16 +6,16 @@ "source": "toplevel/source/topLevelPackageContentAccess.bal", "items": [ { - "label": "extractBasicAuthHeaderValue(http:Request req)(string?)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the basic authentication header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring?" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" } }, - "insertText": "extractBasicAuthHeaderValue(${1:req})", + "insertText": "extractAuthorizationHeaderValue(${1:req})", "insertTextFormat": "Snippet", "additionalTextEdits": [ { From 2372bd545730f7ac261f8611bdf5b1dd699467db Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 2 May 2019 20:32:50 +0530 Subject: [PATCH 43/52] Fix integration tests --- .../authservices/17_authn_with_custom_handlers.bal | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal index eaee5aeb33d0..2c90a40769bb 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal @@ -56,17 +56,13 @@ public type CustomAuthnHandler object { } }; -public function CustomAuthnHandler.handle(http:Request req) returns boolean { +public function CustomAuthnHandler.handle(http:Request req) returns boolean|error { var customAuthHeader = req.getHeader(http:AUTH_HEADER); string credential = customAuthHeader.substring(6, customAuthHeader.length()).trim(); - var authenticated = self.authProvider.authenticate(credential); - if (authenticated is boolean) { - return authenticated; - } - return false; + return self.authProvider.authenticate(credential); } -public function CustomAuthnHandler.canHandle(http:Request req) returns boolean { +public function CustomAuthnHandler.canHandle(http:Request req) returns boolean|error { var customAuthHeader = req.getHeader(http:AUTH_HEADER); return customAuthHeader.hasPrefix("Custom"); } From 39f1042eade281e1aeed8fe27f58bd3dd297bfef Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 2 May 2019 21:20:47 +0530 Subject: [PATCH 44/52] Add temporary fix for multiple handlers --- stdlib/http/src/main/ballerina/http/auth/authn_filter.bal | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal index 0cfb1ee0c0a9..b1a46da4ba61 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal @@ -55,6 +55,7 @@ public type AuthnFilter object { }; function handleAuthnRequest(AuthnHandler[] authnHandlers, Request request) returns boolean|error { + //TODO: Discuss how we can return the error here. foreach AuthnHandler authnHandler in authnHandlers { var canHandleResponse = authnHandler.canHandle(request); if (canHandleResponse is boolean) { @@ -68,11 +69,11 @@ function handleAuthnRequest(AuthnHandler[] authnHandlers, Request request) retur return true; } } else { - return handleResponse; + //return handleResponse; } } } else { - return canHandleResponse; + //return canHandleResponse; } } return false; From 5cf27eb5a7c975a369e16cf94e29e9c1eaf31fb3 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 2 May 2019 21:21:03 +0530 Subject: [PATCH 45/52] Address review suggestions --- stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal | 2 +- stdlib/auth/src/main/ballerina/auth/utils.bal | 2 +- .../auth/authservices/17_authn_with_custom_handlers.bal | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal index f59572241c60..336bff7f11bd 100644 --- a/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal +++ b/stdlib/auth/src/main/ballerina/auth/jwt/jwt_validator.bal @@ -291,7 +291,7 @@ returns boolean|error { function validateIssuer(JwtPayload jwtPayload, JWTValidatorConfig config) returns error? { var iss = jwtPayload["iss"]; if (iss is string) { - if(jwtPayload.iss != config.issuer) { + if (jwtPayload.iss != config.issuer) { return prepareError("JWT contained invalid issuer name : " + jwtPayload.iss); } } else { diff --git a/stdlib/auth/src/main/ballerina/auth/utils.bal b/stdlib/auth/src/main/ballerina/auth/utils.bal index add0ccb59c94..bd404cd59df4 100644 --- a/stdlib/auth/src/main/ballerina/auth/utils.bal +++ b/stdlib/auth/src/main/ballerina/auth/utils.bal @@ -57,7 +57,7 @@ function extractUsernameAndPassword(string credential) returns (string, string)| # + err - `error` instance # + return - Prepared `error` instance function prepareError(string message, error? err = ()) returns error { - log:printError(function () returns string { return message; }); + log:printError(message, err = err); error preparedError = error(AUTH_ERROR_CODE, { message: message, reason: err.reason() }); return preparedError; } diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal index 2c90a40769bb..33d34149150f 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal @@ -17,7 +17,6 @@ import ballerina/auth; import ballerina/encoding; import ballerina/http; -import ballerina/log; import ballerina/runtime; CustomAuthStoreProvider customAuthStoreProvider = new; @@ -97,4 +96,4 @@ public type CustomAuthStoreProvider object { string[] scopes = ["all"]; return scopes; } -}; \ No newline at end of file +}; From 6898cb56ed1d99c92166dee95052505a72d7e8ae Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Thu, 2 May 2019 21:45:10 +0530 Subject: [PATCH 46/52] Add missing licence headers --- .../test-src/auth/basic-authn-handler-test.bal | 16 ++++++++++++++++ .../test-src/auth/jwt-authn-handler-test.bal | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal index 572a3be33a40..035cc8cb0bff 100644 --- a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal @@ -1,3 +1,19 @@ +// Copyright (c) 2019 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// +// WSO2 Inc. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + import ballerina/auth; import ballerina/http; diff --git a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal index c2bae766d5d3..96c2ac585f05 100644 --- a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal @@ -1,3 +1,19 @@ +// Copyright (c) 2019 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// +// WSO2 Inc. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + import ballerina/auth; import ballerina/http; import ballerina/crypto; From d6fe111d0d5141fd37639123e36126a56dcefbff Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Fri, 3 May 2019 11:59:32 +0530 Subject: [PATCH 47/52] Fix authn filter error handling for multiple handlers --- .../main/ballerina/http/auth/authn_filter.bal | 32 +++++++++---------- .../ballerina/http/auth/authn_handler.bal | 4 +-- .../http/auth/basic_authn_handler.bal | 22 +++++-------- .../ballerina/http/auth/jwt_authn_handler.bal | 19 ++++++----- .../src/main/ballerina/http/auth/utils.bal | 11 ++----- 5 files changed, 40 insertions(+), 48 deletions(-) diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal index b1a46da4ba61..133249669241 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_filter.bal @@ -55,27 +55,27 @@ public type AuthnFilter object { }; function handleAuthnRequest(AuthnHandler[] authnHandlers, Request request) returns boolean|error { - //TODO: Discuss how we can return the error here. + error? err = (); foreach AuthnHandler authnHandler in authnHandlers { - var canHandleResponse = authnHandler.canHandle(request); - if (canHandleResponse is boolean) { - if (canHandleResponse) { - var handleResponse = authnHandler.handle(request); - if (handleResponse is boolean) { - if (handleResponse) { - // If one of the authenticators from the chain could successfully authenticate the user, it is not - // required to look through other providers. The authenticator chain is using "OR" combination of - // provider results. - return true; - } - } else { - //return handleResponse; + boolean canHandleResponse = authnHandler.canHandle(request); + if (canHandleResponse) { + var handleResponse = authnHandler.handle(request); + if (handleResponse is boolean) { + if (handleResponse) { + // If one of the authenticators from the chain could successfully authenticate the user, it is not + // required to look through other providers. The authenticator chain is using "OR" combination of + // provider results. + return true; } + } else { + err = handleResponse; } - } else { - //return canHandleResponse; } } + + if (err is error) { + return err; + } return false; } diff --git a/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal index edc00b49c357..a30737fe5f18 100644 --- a/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/authn_handler.bal @@ -20,8 +20,8 @@ public type AuthnHandler abstract object { # Checks if the request can be authenticated with the relevant `HttpAuthnHandler` implementation # # + req - `Request` instance - # + return - `true` if can be authenticated, else `false` or, `error` in case of errors - public function canHandle(Request req) returns boolean|error; + # + return - `true` if can be authenticated, else `false` + public function canHandle(Request req) returns boolean; # Tries to authenticate the request with the relevant `HttpAuthnHandler` implementation # diff --git a/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal index 51bc275e4b0d..569f0815a8fd 100644 --- a/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/basic_authn_handler.bal @@ -38,25 +38,19 @@ public type BasicAuthnHandler object { # + req - Request object # + return - `true` if it is possible authenticate with basic auth, else `false`, or `error` in case of errors public function BasicAuthnHandler.handle(Request req) returns boolean|error { - // extract the header value - var basicAuthHeader = extractAuthorizationHeaderValue(req); - if (basicAuthHeader is string) { - string credential = basicAuthHeader.substring(5, basicAuthHeader.length()).trim(); - return self.authProvider.authenticate(credential); - } else { - return basicAuthHeader; - } + string basicAuthHeader = extractAuthorizationHeaderValue(req); + string credential = basicAuthHeader.substring(5, basicAuthHeader.length()).trim(); + return self.authProvider.authenticate(credential); } # Intercept requests for authentication. # # + req - Request object -# + return - `true` if authentication is a success, else `false`, or `error` in case of errors -public function BasicAuthnHandler.canHandle(Request req) returns boolean|error { - var basicAuthHeader = extractAuthorizationHeaderValue(req); - if (basicAuthHeader is string) { +# + return - `true` if authentication is a success, else `false` +public function BasicAuthnHandler.canHandle(Request req) returns boolean { + if (req.hasHeader(AUTH_HEADER)) { + string basicAuthHeader = extractAuthorizationHeaderValue(req); return basicAuthHeader.hasPrefix(AUTH_SCHEME_BASIC); - } else { - return basicAuthHeader; } + return false; } diff --git a/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal b/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal index 12d43a939f54..e563145b1715 100644 --- a/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal +++ b/stdlib/http/src/main/ballerina/http/auth/jwt_authn_handler.bal @@ -34,10 +34,10 @@ public type JwtAuthnHandler object { # Checks if the request can be authenticated with JWT # # + req - `Request` instance -# + return - `true` if can be authenticated, else `false`, or `error` in case of errors -public function JwtAuthnHandler.canHandle(Request req) returns boolean|error { - var headerValue = extractAuthorizationHeaderValue(req); - if (headerValue is string) { +# + return - `true` if can be authenticated, else `false` +public function JwtAuthnHandler.canHandle(Request req) returns boolean { + if (req.hasHeader(AUTH_HEADER)) { + string headerValue = extractAuthorizationHeaderValue(req); if (headerValue.hasPrefix(AUTH_SCHEME_BEARER)) { string[] authHeaderComponents = headerValue.split(" "); if (authHeaderComponents.length() == 2) { @@ -47,10 +47,8 @@ public function JwtAuthnHandler.canHandle(Request req) returns boolean|error { } } } - return false; - } else { - return headerValue; } + return false; } # Authenticates the incoming request using JWT authentication @@ -59,7 +57,12 @@ public function JwtAuthnHandler.canHandle(Request req) returns boolean|error { # + return - `true` if authenticated successfully, else `false`, or `error` in case of errors public function JwtAuthnHandler.handle(Request req) returns boolean|error { string jwtToken = extractJWTToken(req); - return self.authProvider.authenticate(jwtToken); + var authenticated = self.authProvider.authenticate(jwtToken); + if (authenticated is boolean) { + return authenticated; + } else { + return prepareError("Error while validating JWT token"); + } } function extractJWTToken(Request req) returns string { diff --git a/stdlib/http/src/main/ballerina/http/auth/utils.bal b/stdlib/http/src/main/ballerina/http/auth/utils.bal index 8d5e6dfd31ce..0851350a77e2 100644 --- a/stdlib/http/src/main/ballerina/http/auth/utils.bal +++ b/stdlib/http/src/main/ballerina/http/auth/utils.bal @@ -46,15 +46,10 @@ public const JWT_AUTH = "JWT_AUTH"; # Extracts the Authorization header value from the request. # # + req - Request instance -# + return - Value of the basic authentication header, or `error` in case of errors -public function extractAuthorizationHeaderValue(Request req) returns string|error { +# + return - Value of the Authorization header +public function extractAuthorizationHeaderValue(Request req) returns string { // extract authorization header - var headerValue = trap req.getHeader(AUTH_HEADER); - if (headerValue is string) { - return headerValue; - } else { - return prepareError("Error in retrieving header - " + AUTH_HEADER, err = headerValue); - } + return req.getHeader(AUTH_HEADER); } # Tries to retrieve the authentication handlers hierarchically - first from the resource level and then From 474ce2bb65b9a7d07465da6a0e2518713ec4bb07 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Fri, 3 May 2019 12:00:05 +0530 Subject: [PATCH 48/52] Fix unit tests --- .../stdlib/auth/BasicAuthnHandlerTest.java | 9 ++------- .../test-src/auth/basic-authn-handler-test.bal | 10 ++-------- .../resources/test-src/auth/jwt-authn-handler-test.bal | 4 ++-- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java index 0977b1df244e..d883d810375a 100644 --- a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java +++ b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java @@ -74,7 +74,8 @@ private void copySecretFile(String from, String to) throws IOException { @Test(description = "Test case for basic auth interceptor canHandle method, without the basic auth header") public void testCanHandleHttpBasicAuthWithoutHeader() { BValue[] returns = BRunUtil.invoke(compileResult, "testCanHandleHttpBasicAuthWithoutHeader"); - Assert.assertTrue(returns[0] instanceof BError); + Assert.assertTrue(returns[0] instanceof BBoolean); + Assert.assertFalse(((BBoolean) returns[0]).booleanValue()); } @Test(description = "Test case for basic auth interceptor canHandle method") @@ -98,12 +99,6 @@ public void testHandleHttpBasicAuth() { Assert.assertTrue(((BBoolean) returns[0]).booleanValue()); } - @Test(description = "Test case for extracting non existing basic auth header value") - public void testNonExistingBasicAuthHeaderValue() { - BValue[] returns = BRunUtil.invoke(compileResult, "testNonExistingBasicAuthHeaderValue"); - Assert.assertTrue(returns[0] instanceof BError); - } - @Test(description = "Test case for extracting basic auth header value") public void testExtractBasicAuthHeaderValue() { BValue[] returns = BRunUtil.invoke(compileResult, "testExtractBasicAuthHeaderValue"); diff --git a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal index 035cc8cb0bff..ed6ea55d176f 100644 --- a/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/basic-authn-handler-test.bal @@ -17,7 +17,7 @@ import ballerina/auth; import ballerina/http; -function testCanHandleHttpBasicAuthWithoutHeader() returns boolean|error { +function testCanHandleHttpBasicAuthWithoutHeader() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); @@ -26,7 +26,7 @@ function testCanHandleHttpBasicAuthWithoutHeader() returns boolean|error { return handler.canHandle(inRequest); } -function testCanHandleHttpBasicAuth() returns boolean|error { +function testCanHandleHttpBasicAuth() returns boolean { auth:ConfigAuthStoreProvider configAuthStoreProvider = new; http:BasicAuthnHandler handler = new(configAuthStoreProvider); http:Request inRequest = createRequest(); @@ -53,12 +53,6 @@ function testHandleHttpBasicAuth() returns boolean|error { return handler.handle(inRequest); } -function testNonExistingBasicAuthHeaderValue() returns string|error { - // create dummy request - http:Request inRequest = createRequest(); - return http:extractAuthorizationHeaderValue(inRequest); -} - function testExtractBasicAuthHeaderValue() returns string|error { // create dummy request http:Request inRequest = createRequest(); diff --git a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal index 96c2ac585f05..5a597456f49f 100644 --- a/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal +++ b/stdlib/http/src/test/resources/test-src/auth/jwt-authn-handler-test.bal @@ -18,7 +18,7 @@ import ballerina/auth; import ballerina/http; import ballerina/crypto; -function testCanHandleHttpJwtAuthWithoutHeader() returns boolean|error { +function testCanHandleHttpJwtAuthWithoutHeader() returns boolean { http:JwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Basic xxxxxx"; @@ -26,7 +26,7 @@ function testCanHandleHttpJwtAuthWithoutHeader() returns boolean|error { return handler.canHandle(request); } -function testCanHandleHttpJwtAuth() returns boolean|error { +function testCanHandleHttpJwtAuth() returns boolean { http:JwtAuthnHandler handler = new(createJwtAuthProvider("ballerina/security/ballerinaTruststore.p12")); http:Request request = createRequest(); string authHeaderValue = "Bearer xxx.yyy.zzz"; From 336328dd99b57cb513a4232b372b182356671cb6 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Fri, 3 May 2019 13:09:55 +0530 Subject: [PATCH 49/52] Fix lang server tests --- .../resources/completion/packageimport/packageImport.json | 4 ++-- .../resources/completion/service/serviceBodyCompletion5.json | 4 ++-- .../resources/completion/service/serviceEndpointBind4.json | 4 ++-- .../completion/toplevel/globalVarDefPackageContent.json | 4 ++-- .../completion/toplevel/topLevelPackageContentAccess.json | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json b/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json index aacfcc630f2a..2cdb8af998f9 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/packageimport/packageImport.json @@ -6,13 +6,13 @@ "source": "packageimport/source/packageImport.bal", "items": [ { - "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring" } }, "sortText": "121", diff --git a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json index 159452be9faa..0bf36b7c7884 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceBodyCompletion5.json @@ -6,13 +6,13 @@ "source": "service/source/serviceBodyCompletion5.bal", "items": [ { - "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring" } }, "sortText": "121", diff --git a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json index 03eca1e17487..0e6f622b84e2 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/service/serviceEndpointBind4.json @@ -6,13 +6,13 @@ "source": "service/source/serviceEndpointBind4.bal", "items": [ { - "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring" } }, "insertText": "extractAuthorizationHeaderValue(${1:req})", diff --git a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json index 87c19380eea4..71ab2c1726d5 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/globalVarDefPackageContent.json @@ -6,13 +6,13 @@ "source": "toplevel/source/globalVarDefPackageContent.bal", "items": [ { - "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring" } }, "sortText": "121", diff --git a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json index e43f3f68c519..11c4acb8b7f9 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/toplevel/topLevelPackageContentAccess.json @@ -6,13 +6,13 @@ "source": "toplevel/source/topLevelPackageContentAccess.bal", "items": [ { - "label": "extractAuthorizationHeaderValue(http:Request req)(string|error)", + "label": "extractAuthorizationHeaderValue(http:Request req)(string)", "kind": "Function", "detail": "Function", "documentation": { "right": { "kind": "markdown", - "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring|error" + "value": "**Package:** _ballerina/http_ \n \nExtracts the Authorization header value from the request.\n \n \n--- \n**Parameters** \n- _req_ \n Request instance \n \n \n**Return** \nstring" } }, "insertText": "extractAuthorizationHeaderValue(${1:req})", From 63dee6d0ccd1851ca15044f7ae30d3422e9654f7 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Fri, 3 May 2019 13:10:09 +0530 Subject: [PATCH 50/52] Fix integration tests --- .../auth/authservices/17_authn_with_custom_handlers.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal index 33d34149150f..a0f784dd9c62 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal @@ -61,7 +61,7 @@ public function CustomAuthnHandler.handle(http:Request req) returns boolean|erro return self.authProvider.authenticate(credential); } -public function CustomAuthnHandler.canHandle(http:Request req) returns boolean|error { +public function CustomAuthnHandler.canHandle(http:Request req) returns boolean { var customAuthHeader = req.getHeader(http:AUTH_HEADER); return customAuthHeader.hasPrefix("Custom"); } From 00d78aaa627982aa6aa9a00d4764ca62a6fc52a1 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Fri, 3 May 2019 13:24:50 +0530 Subject: [PATCH 51/52] Fix checkstyle bug --- .../org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java index d883d810375a..0459d9904150 100644 --- a/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java +++ b/stdlib/http/src/test/java/org/ballerinalang/stdlib/auth/BasicAuthnHandlerTest.java @@ -23,7 +23,6 @@ import org.ballerinalang.launcher.util.BRunUtil; import org.ballerinalang.launcher.util.CompileResult; import org.ballerinalang.model.values.BBoolean; -import org.ballerinalang.model.values.BError; import org.ballerinalang.model.values.BString; import org.ballerinalang.model.values.BValue; import org.testng.Assert; From f990ac844d9595f9234cd7775b2c17647d02f285 Mon Sep 17 00:00:00 2001 From: Chanaka Lakmal Date: Fri, 3 May 2019 14:09:40 +0530 Subject: [PATCH 52/52] Refactor integration tests --- .../auth/authservices/17_authn_with_custom_handlers.bal | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal index a0f784dd9c62..c51e642b0b69 100644 --- a/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal +++ b/tests/ballerina-integration-test/src/test/resources/auth/authservices/17_authn_with_custom_handlers.bal @@ -35,7 +35,10 @@ listener http:Listener listener17 = new(9113, config = { } }); -service echo on listener17 { +@http:ServiceConfig { + basePath: "/echo" +} +service echo17 on listener17 { resource function test(http:Caller caller, http:Request req) { checkpanic caller->respond("Hello Ballerina!"); }