mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
fixed permission and assigned environment variables for url context
This commit is contained in:
parent
93ae646c50
commit
2fbaf31b93
@ -173,6 +173,11 @@
|
|||||||
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
|
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wso2.carbon</groupId>
|
||||||
|
<artifactId>org.wso2.carbon.registry.core</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@ -56,6 +56,9 @@ public class ApiPermissionFilter implements Filter {
|
|||||||
PermissionConfiguration permissionConfiguration = (PermissionConfiguration)
|
PermissionConfiguration permissionConfiguration = (PermissionConfiguration)
|
||||||
unmarshaller.unmarshal(permissionStream);
|
unmarshaller.unmarshal(permissionStream);
|
||||||
permissions = permissionConfiguration.getPermissions();
|
permissions = permissionConfiguration.getPermissions();
|
||||||
|
for (Permission permission : permissions) {
|
||||||
|
APIUtil.putPermission(PERMISSION_PREFIX + permission.getPath());
|
||||||
|
}
|
||||||
} catch (JAXBException e) {
|
} catch (JAXBException e) {
|
||||||
log.error("invalid permissions.xml", e);
|
log.error("invalid permissions.xml", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,12 +21,18 @@ package org.wso2.carbon.apimgt.application.extension.api.util;
|
|||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
|
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
|
||||||
|
import org.wso2.carbon.base.MultitenantConstants;
|
||||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||||
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||||
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
||||||
|
import org.wso2.carbon.registry.api.Resource;
|
||||||
|
import org.wso2.carbon.registry.core.Registry;
|
||||||
|
import org.wso2.carbon.registry.core.exceptions.RegistryException;
|
||||||
|
import org.wso2.carbon.registry.core.service.RegistryService;
|
||||||
import org.wso2.carbon.user.core.service.RealmService;
|
import org.wso2.carbon.user.core.service.RealmService;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides utility functions used by REST-API.
|
* This class provides utility functions used by REST-API.
|
||||||
@ -35,6 +41,8 @@ public class APIUtil {
|
|||||||
|
|
||||||
private static Log log = LogFactory.getLog(APIUtil.class);
|
private static Log log = LogFactory.getLog(APIUtil.class);
|
||||||
private static final String DEFAULT_CDMF_API_TAG = "device_management";
|
private static final String DEFAULT_CDMF_API_TAG = "device_management";
|
||||||
|
private static final String DEFAULT_CERT_API_TAG = "scep_management";
|
||||||
|
public static final String PERMISSION_PROPERTY_NAME = "name";
|
||||||
|
|
||||||
public static String getAuthenticatedUser() {
|
public static String getAuthenticatedUser() {
|
||||||
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||||
@ -48,8 +56,7 @@ public class APIUtil {
|
|||||||
|
|
||||||
public static String getTenantDomainOftheUser() {
|
public static String getTenantDomainOftheUser() {
|
||||||
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||||
String tenantDomain = threadLocalCarbonContext.getTenantDomain();
|
return threadLocalCarbonContext.getTenantDomain();
|
||||||
return tenantDomain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static APIManagementProviderService getAPIManagementProviderService() {
|
public static APIManagementProviderService getAPIManagementProviderService() {
|
||||||
@ -92,6 +99,55 @@ public class APIUtil {
|
|||||||
//Todo get allowed cdmf service tags from config.
|
//Todo get allowed cdmf service tags from config.
|
||||||
List<String> allowedApisTags = getDeviceManagementProviderService().getAvailableDeviceTypes();
|
List<String> allowedApisTags = getDeviceManagementProviderService().getAvailableDeviceTypes();
|
||||||
allowedApisTags.add(DEFAULT_CDMF_API_TAG);
|
allowedApisTags.add(DEFAULT_CDMF_API_TAG);
|
||||||
|
allowedApisTags.add(DEFAULT_CERT_API_TAG);
|
||||||
return allowedApisTags;
|
return allowedApisTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void putPermission(String permission) {
|
||||||
|
try {
|
||||||
|
StringTokenizer tokenizer = new StringTokenizer(permission, "/");
|
||||||
|
String lastToken = "", currentToken, tempPath;
|
||||||
|
while (tokenizer.hasMoreTokens()) {
|
||||||
|
currentToken = tokenizer.nextToken();
|
||||||
|
tempPath = lastToken + "/" + currentToken;
|
||||||
|
if (!checkResourceExists(tempPath)) {
|
||||||
|
createRegistryCollection(tempPath, currentToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
lastToken = tempPath;
|
||||||
|
}
|
||||||
|
} catch (org.wso2.carbon.registry.api.RegistryException e) {
|
||||||
|
log.error("Failed to creation permission in registry" + permission, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createRegistryCollection(String path, String resourceName)
|
||||||
|
throws org.wso2.carbon.registry.api.RegistryException {
|
||||||
|
Resource resource = getGovernanceRegistry().newCollection();
|
||||||
|
resource.addProperty(PERMISSION_PROPERTY_NAME, resourceName);
|
||||||
|
getGovernanceRegistry().beginTransaction();
|
||||||
|
getGovernanceRegistry().put(path, resource);
|
||||||
|
getGovernanceRegistry().commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkResourceExists(String path)
|
||||||
|
throws RegistryException {
|
||||||
|
return getGovernanceRegistry().resourceExists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Registry getGovernanceRegistry() throws RegistryException {
|
||||||
|
return getRegistryService().getGovernanceSystemRegistry(MultitenantConstants.SUPER_TENANT_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RegistryService getRegistryService() {
|
||||||
|
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||||
|
RegistryService registryService =
|
||||||
|
(RegistryService) ctx.getOSGiService(RegistryService.class, null);
|
||||||
|
if (registryService == null) {
|
||||||
|
String msg = "registry service has not initialized.";
|
||||||
|
log.error(msg);
|
||||||
|
throw new IllegalStateException(msg);
|
||||||
|
}
|
||||||
|
return registryService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,14 +37,14 @@
|
|||||||
</Permission>
|
</Permission>
|
||||||
<Permission>
|
<Permission>
|
||||||
<name>Register application</name>
|
<name>Register application</name>
|
||||||
<path>/device-mgt/user/api/application</path>
|
<path>/device-mgt/api/application</path>
|
||||||
<url>/register</url>
|
<url>/register</url>
|
||||||
<method>POST</method>
|
<method>POST</method>
|
||||||
<scope>application_user</scope>
|
<scope>application_user</scope>
|
||||||
</Permission>
|
</Permission>
|
||||||
<Permission>
|
<Permission>
|
||||||
<name>Delete application</name>
|
<name>Delete application</name>
|
||||||
<path>/device-mgt/user/api/application</path>
|
<path>/device-mgt/api/application</path>
|
||||||
<url>/unregister</url>
|
<url>/unregister</url>
|
||||||
<method>DELETE</method>
|
<method>DELETE</method>
|
||||||
<scope>application_user</scope>
|
<scope>application_user</scope>
|
||||||
|
|||||||
@ -64,6 +64,12 @@ import javax.ws.rs.core.Response;
|
|||||||
description = "Deleting an SSL Certificate",
|
description = "Deleting an SSL Certificate",
|
||||||
key = "perm:admin:certificates:delete",
|
key = "perm:admin:certificates:delete",
|
||||||
permissions = {"/device-mgt/admin/certificates/delete"}
|
permissions = {"/device-mgt/admin/certificates/delete"}
|
||||||
|
),
|
||||||
|
@Scope(
|
||||||
|
name = "Verify SSL certificate",
|
||||||
|
description = "Verify SSL certificate",
|
||||||
|
key = "perm:admin:certificates:verify",
|
||||||
|
permissions = {"/device-mgt/admin/certificates/verify"}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -428,7 +434,12 @@ public interface CertificateManagementAdminService {
|
|||||||
httpMethod = "POST",
|
httpMethod = "POST",
|
||||||
value = "Verify Android SSL certificate",
|
value = "Verify Android SSL certificate",
|
||||||
notes = "Verify Android Certificate for the API security filter.\n",
|
notes = "Verify Android Certificate for the API security filter.\n",
|
||||||
tags = "Certificate Management")
|
tags = "Certificate Management",
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name = SCOPE, value = "perm:admin:certificates:add")
|
||||||
|
})
|
||||||
|
})
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
|
|||||||
@ -29,7 +29,6 @@ import io.swagger.annotations.ApiParam;
|
|||||||
import io.swagger.annotations.ApiResponse;
|
import io.swagger.annotations.ApiResponse;
|
||||||
import io.swagger.annotations.ApiResponses;
|
import io.swagger.annotations.ApiResponses;
|
||||||
import io.swagger.annotations.ResponseHeader;
|
import io.swagger.annotations.ResponseHeader;
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.wso2.carbon.apimgt.annotations.api.Scope;
|
import org.wso2.carbon.apimgt.annotations.api.Scope;
|
||||||
import org.wso2.carbon.apimgt.annotations.api.Scopes;
|
import org.wso2.carbon.apimgt.annotations.api.Scopes;
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
|
|||||||
@ -22,9 +22,17 @@ import io.swagger.annotations.Api;
|
|||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import io.swagger.annotations.ApiResponse;
|
import io.swagger.annotations.ApiResponse;
|
||||||
import io.swagger.annotations.ApiResponses;
|
import io.swagger.annotations.ApiResponses;
|
||||||
|
import io.swagger.annotations.Extension;
|
||||||
|
import io.swagger.annotations.ExtensionProperty;
|
||||||
|
import io.swagger.annotations.Info;
|
||||||
|
import io.swagger.annotations.SwaggerDefinition;
|
||||||
|
import io.swagger.annotations.Tag;
|
||||||
|
import org.wso2.carbon.apimgt.annotations.api.Scope;
|
||||||
|
import org.wso2.carbon.apimgt.annotations.api.Scopes;
|
||||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAuthorizationResult;
|
import org.wso2.carbon.device.mgt.common.authorization.DeviceAuthorizationResult;
|
||||||
import org.wso2.carbon.device.mgt.jaxrs.beans.AuthorizationRequest;
|
import org.wso2.carbon.device.mgt.jaxrs.beans.AuthorizationRequest;
|
||||||
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
|
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
|
||||||
|
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
@ -37,6 +45,32 @@ import javax.ws.rs.core.Response;
|
|||||||
@Api(value = "Device Authorization Administrative Service", description = "This an API intended to be used by " +
|
@Api(value = "Device Authorization Administrative Service", description = "This an API intended to be used by " +
|
||||||
"'internal' components to log in as an admin user and validate whether the user/device are trusted entity." +
|
"'internal' components to log in as an admin user and validate whether the user/device are trusted entity." +
|
||||||
"Further, this is strictly restricted to admin users only ")
|
"Further, this is strictly restricted to admin users only ")
|
||||||
|
|
||||||
|
@SwaggerDefinition(
|
||||||
|
info = @Info(
|
||||||
|
version = "1.0.0",
|
||||||
|
title = "",
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name = "name", value = "DeviceAccessAuthorizationAdminService"),
|
||||||
|
@ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/admin/authorization"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
),
|
||||||
|
tags = {
|
||||||
|
@Tag(name = "device_management", description = "")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@Scopes(
|
||||||
|
scopes = {
|
||||||
|
@Scope(
|
||||||
|
name = "Verify device authorization",
|
||||||
|
description = "Verify device authorization",
|
||||||
|
key = "perm:authorization:verify",
|
||||||
|
permissions = {"/device-mgt/authorization/verify"}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
/**
|
/**
|
||||||
@ -52,7 +86,13 @@ public interface DeviceAccessAuthorizationAdminService {
|
|||||||
value = "Check for device access authorization\n",
|
value = "Check for device access authorization\n",
|
||||||
notes = "This is an internal API that can be used to check for authorization.",
|
notes = "This is an internal API that can be used to check for authorization.",
|
||||||
response = DeviceAuthorizationResult.class,
|
response = DeviceAuthorizationResult.class,
|
||||||
tags = "Authorization Administrative Service")
|
tags = "Authorization Administrative Service",
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name = Constants.SCOPE, value = "perm:authorization:verify")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
@ApiResponses(value = {
|
@ApiResponses(value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
code = 200,
|
code = 200,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"appContext": "/devicemgt/",
|
"appContext": "/devicemgt/",
|
||||||
"httpsURL" : "https://localhost:8243",
|
"httpsURL" : "https://%server.ip%:8243",
|
||||||
"httpURL" : "http://localhost:8280",
|
"httpURL" : "http://%server.ip%:8280",
|
||||||
"wssURL" : "https://localhost:9445",
|
"wssURL" : "https://localhost:9445",
|
||||||
"wsURL" : "%http.ip%",
|
"wsURL" : "%http.ip%",
|
||||||
"portalURL": "https://%server.ip%:9445",
|
"portalURL": "https://%server.ip%:9445",
|
||||||
|
|||||||
@ -35,6 +35,8 @@ import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
|
|||||||
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException;
|
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
@ -86,4 +88,18 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String replaceSystemProperty(String urlWithPlaceholders) {
|
||||||
|
String regex = "\\$\\{(.*?)\\}";
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
Matcher matchPattern = pattern.matcher(urlWithPlaceholders);
|
||||||
|
while (matchPattern.find()) {
|
||||||
|
String sysPropertyName = matchPattern.group(1);
|
||||||
|
String sysPropertyValue = System.getProperty(sysPropertyName);
|
||||||
|
if (sysPropertyValue != null && !sysPropertyName.isEmpty()) {
|
||||||
|
urlWithPlaceholders = urlWithPlaceholders.replaceAll("\\$\\{(" + sysPropertyName + ")\\}", sysPropertyValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return urlWithPlaceholders;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public class BSTAuthenticator implements WebappAuthenticator {
|
|||||||
"are not provided");
|
"are not provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = this.properties.getProperty("TokenValidationEndpointUrl");
|
String url = Utils.replaceSystemProperty(this.properties.getProperty("TokenValidationEndpointUrl"));
|
||||||
if ((url == null) || (url.isEmpty())) {
|
if ((url == null) || (url.isEmpty())) {
|
||||||
throw new IllegalArgumentException("OAuth token validation endpoint url is not provided");
|
throw new IllegalArgumentException("OAuth token validation endpoint url is not provided");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ public class OAuthAuthenticator implements WebappAuthenticator {
|
|||||||
"are not provided");
|
"are not provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = this.properties.getProperty("TokenValidationEndpointUrl");
|
String url = Utils.replaceSystemProperty(this.properties.getProperty("TokenValidationEndpointUrl"));
|
||||||
if ((url == null) || (url.isEmpty())) {
|
if ((url == null) || (url.isEmpty())) {
|
||||||
throw new IllegalArgumentException("OAuth token validation endpoint url is not provided");
|
throw new IllegalArgumentException("OAuth token validation endpoint url is not provided");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
<WebappPublisherConfigs>
|
<WebappPublisherConfigs>
|
||||||
|
|
||||||
<!-- This host is used to define the host address which is used to publish APIs -->
|
<!-- This host is used to define the host address which is used to publish APIs -->
|
||||||
<Host>https://localhost:${carbon.https.port}</Host>
|
<Host>https://${iot.core.host}:${iot.core.https.port}</Host>
|
||||||
|
|
||||||
<!-- If it is true, the APIs of this instance will be published to the defined host -->
|
<!-- If it is true, the APIs of this instance will be published to the defined host -->
|
||||||
<PublishAPI>true</PublishAPI>
|
<PublishAPI>true</PublishAPI>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.OAuthAuthenticator</ClassName>
|
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.OAuthAuthenticator</ClassName>
|
||||||
<Parameters>
|
<Parameters>
|
||||||
<Parameter Name="IsRemote">false</Parameter>
|
<Parameter Name="IsRemote">false</Parameter>
|
||||||
<Parameter Name="TokenValidationEndpointUrl">https://localhost:9443</Parameter>
|
<Parameter Name="TokenValidationEndpointUrl">https://${iot.keymanager.host}:${iot.keymanager.https.port}</Parameter>
|
||||||
<Parameter Name="Username">admin</Parameter>
|
<Parameter Name="Username">admin</Parameter>
|
||||||
<Parameter Name="Password">admin</Parameter>
|
<Parameter Name="Password">admin</Parameter>
|
||||||
<Parameter Name="MaxTotalConnections">100</Parameter>
|
<Parameter Name="MaxTotalConnections">100</Parameter>
|
||||||
@ -23,6 +23,7 @@
|
|||||||
<!--Issuers list and corresponding cert alias-->
|
<!--Issuers list and corresponding cert alias-->
|
||||||
<Parameter Name="wso2.org/products/am">wso2carbon</Parameter>
|
<Parameter Name="wso2.org/products/am">wso2carbon</Parameter>
|
||||||
<Parameter Name="wso2.org/products/iot">wso2carbon</Parameter>
|
<Parameter Name="wso2.org/products/iot">wso2carbon</Parameter>
|
||||||
|
<Parameter Name="wso2.org/products/analytics">wso2carbon</Parameter>
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</Authenticator>
|
</Authenticator>
|
||||||
<Authenticator>
|
<Authenticator>
|
||||||
@ -34,7 +35,7 @@
|
|||||||
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.BSTAuthenticator</ClassName>
|
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.BSTAuthenticator</ClassName>
|
||||||
<Parameters>
|
<Parameters>
|
||||||
<Parameter Name="IsRemote">false</Parameter>
|
<Parameter Name="IsRemote">false</Parameter>
|
||||||
<Parameter Name="TokenValidationEndpointUrl">https://localhost:9443</Parameter>
|
<Parameter Name="TokenValidationEndpointUrl">https://${iot.keymanager.host}:${iot.keymanager.https.port}</Parameter>
|
||||||
<Parameter Name="Username">admin</Parameter>
|
<Parameter Name="Username">admin</Parameter>
|
||||||
<Parameter Name="Password">admin</Parameter>
|
<Parameter Name="Password">admin</Parameter>
|
||||||
<Parameter Name="MaxTotalConnections">100</Parameter>
|
<Parameter Name="MaxTotalConnections">100</Parameter>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user