This closes #573
This commit is contained in:
commit
bafa59cc38
|
@ -51,6 +51,7 @@ import org.apache.directory.server.annotations.CreateTransport;
|
|||
import org.apache.directory.server.core.annotations.ApplyLdifFiles;
|
||||
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
|
||||
import org.apache.directory.server.core.integ.FrameworkRunner;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
|
@ -75,6 +76,7 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
|
|||
}
|
||||
|
||||
private ServerLocator locator;
|
||||
ActiveMQServer server;
|
||||
|
||||
public static final String TARGET_TMP = "./target/tmp";
|
||||
private static final String PRINCIPAL = "uid=admin,ou=system";
|
||||
|
@ -93,8 +95,24 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
locator = ActiveMQClient.createServerLocatorWithHA(new TransportConfiguration(InVMConnectorFactory.class.getCanonicalName()));
|
||||
locator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(InVMConnectorFactory.class.getCanonicalName()));
|
||||
testDir = temporaryFolder.getRoot().getAbsolutePath();
|
||||
|
||||
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
|
||||
Configuration configuration = new ConfigurationImpl()
|
||||
.setSecurityEnabled(true)
|
||||
.addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()))
|
||||
.setJournalDirectory(ActiveMQTestBase.getJournalDir(testDir, 0, false))
|
||||
.setBindingsDirectory(ActiveMQTestBase.getBindingsDir(testDir, 0, false))
|
||||
.setPagingDirectory(ActiveMQTestBase.getPageDir(testDir, 0, false))
|
||||
.setLargeMessagesDirectory(ActiveMQTestBase.getLargeMessagesDir(testDir, 0, false));
|
||||
server = ActiveMQServers.newActiveMQServer(configuration, ManagementFactory.getPlatformMBeanServer(), securityManager, false);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -121,11 +139,12 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
|
|||
Assert.assertTrue(set.contains("ou=groups"));
|
||||
Assert.assertTrue(set.contains("ou=configuration"));
|
||||
Assert.assertTrue(set.contains("prefNodeName=sysPrefRoot"));
|
||||
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJAASSecurityManagerAuthentication() throws Exception {
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
server.start();
|
||||
ClientSessionFactory cf = locator.createSessionFactory();
|
||||
|
||||
|
@ -139,13 +158,10 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
|
|||
}
|
||||
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJAASSecurityManagerAuthenticationBadPassword() throws Exception {
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
server.start();
|
||||
ClientSessionFactory cf = locator.createSessionFactory();
|
||||
|
||||
|
@ -158,8 +174,6 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
|
|||
}
|
||||
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -168,7 +182,6 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
|
|||
final SimpleString DURABLE_QUEUE = new SimpleString("durableQueue");
|
||||
final SimpleString NON_DURABLE_QUEUE = new SimpleString("nonDurableQueue");
|
||||
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
Set<Role> roles = new HashSet<>();
|
||||
roles.add(new Role("programmers", false, false, false, false, false, false, false));
|
||||
server.getConfiguration().putSecurityRoles("#", roles);
|
||||
|
@ -246,8 +259,6 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
|
|||
|
||||
session.close();
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -256,7 +267,6 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
|
|||
final SimpleString DURABLE_QUEUE = new SimpleString("durableQueue");
|
||||
final SimpleString NON_DURABLE_QUEUE = new SimpleString("nonDurableQueue");
|
||||
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
Set<Role> roles = new HashSet<>();
|
||||
roles.add(new Role("admins", true, true, true, true, true, true, true));
|
||||
server.getConfiguration().putSecurityRoles("#", roles);
|
||||
|
@ -329,17 +339,5 @@ public class LDAPSecurityTest extends AbstractLdapTestUnit {
|
|||
|
||||
session.close();
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
private ActiveMQServer getActiveMQServer() {
|
||||
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
|
||||
Configuration configuration = new ConfigurationImpl().setSecurityEnabled(true).addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()))
|
||||
.setJournalDirectory(ActiveMQTestBase.getJournalDir(testDir, 0, false))
|
||||
.setBindingsDirectory(ActiveMQTestBase.getBindingsDir(testDir, 0, false))
|
||||
.setPagingDirectory(ActiveMQTestBase.getPageDir(testDir, 0, false))
|
||||
.setLargeMessagesDirectory(ActiveMQTestBase.getLargeMessagesDir(testDir, 0, false));
|
||||
return ActiveMQServers.newActiveMQServer(configuration, ManagementFactory.getPlatformMBeanServer(), securityManager, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.apache.directory.server.annotations.CreateTransport;
|
|||
import org.apache.directory.server.core.annotations.ApplyLdifFiles;
|
||||
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
|
||||
import org.apache.directory.server.core.integ.FrameworkRunner;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
|
@ -80,6 +81,7 @@ public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTes
|
|||
}
|
||||
|
||||
private ServerLocator locator;
|
||||
ActiveMQServer server;
|
||||
|
||||
public static final String TARGET_TMP = "./target/tmp";
|
||||
private static final String PRINCIPAL = "uid=admin,ou=system";
|
||||
|
@ -98,8 +100,38 @@ public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTes
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
locator = ActiveMQClient.createServerLocatorWithHA(new TransportConfiguration(InVMConnectorFactory.class.getCanonicalName()));
|
||||
locator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(InVMConnectorFactory.class.getCanonicalName()));
|
||||
testDir = temporaryFolder.getRoot().getAbsolutePath();
|
||||
|
||||
LegacyLDAPSecuritySettingPlugin legacyLDAPSecuritySettingPlugin = new LegacyLDAPSecuritySettingPlugin();
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_URL, "ldap://localhost:1024");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_USERNAME, "uid=admin,ou=system");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_PASSWORD, "secret");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_PROTOCOL, "s");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.AUTHENTICATION, "simple");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.ENABLE_LISTENER, "true");
|
||||
legacyLDAPSecuritySettingPlugin.init(map);
|
||||
|
||||
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
|
||||
Configuration configuration = new ConfigurationImpl()
|
||||
.setSecurityEnabled(true)
|
||||
.addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()))
|
||||
.setJournalDirectory(ActiveMQTestBase.getJournalDir(testDir, 0, false))
|
||||
.setBindingsDirectory(ActiveMQTestBase.getBindingsDir(testDir, 0, false))
|
||||
.setPagingDirectory(ActiveMQTestBase.getPageDir(testDir, 0, false))
|
||||
.setLargeMessagesDirectory(ActiveMQTestBase.getLargeMessagesDir(testDir, 0, false))
|
||||
.setPersistenceEnabled(false)
|
||||
.addSecuritySettingPlugin(legacyLDAPSecuritySettingPlugin);
|
||||
|
||||
server = ActiveMQServers.newActiveMQServer(configuration, ManagementFactory.getPlatformMBeanServer(), securityManager, false);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -134,7 +166,6 @@ public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTes
|
|||
|
||||
@Test
|
||||
public void testProducerPermissionUpdate() throws Exception {
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
server.getConfiguration().setSecurityInvalidationInterval(0);
|
||||
server.start();
|
||||
ClientSessionFactory cf = locator.createSessionFactory();
|
||||
|
@ -158,6 +189,7 @@ public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTes
|
|||
BasicAttributes basicAttributes = new BasicAttributes();
|
||||
basicAttributes.put("uniquemember", "uid=role2");
|
||||
ctx.modifyAttributes("cn=write,uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,ou=system", DirContext.REPLACE_ATTRIBUTE, basicAttributes);
|
||||
ctx.close();
|
||||
|
||||
producer2.send(name, session.createMessage(true));
|
||||
|
||||
|
@ -170,13 +202,10 @@ public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTes
|
|||
}
|
||||
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumerPermissionUpdate() throws Exception {
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
server.getConfiguration().setSecurityInvalidationInterval(0);
|
||||
server.start();
|
||||
ClientSessionFactory cf = locator.createSessionFactory();
|
||||
|
@ -201,6 +230,7 @@ public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTes
|
|||
BasicAttributes basicAttributes = new BasicAttributes();
|
||||
basicAttributes.put("uniquemember", "uid=role2");
|
||||
ctx.modifyAttributes("cn=read,uid=queue1,ou=queues,ou=destinations,o=ActiveMQ,ou=system", DirContext.REPLACE_ATTRIBUTE, basicAttributes);
|
||||
ctx.close();
|
||||
|
||||
consumer2 = session2.createConsumer(queue);
|
||||
consumer2.receiveImmediate();
|
||||
|
@ -215,13 +245,10 @@ public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTes
|
|||
}
|
||||
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewConsumerPermission() throws Exception {
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
server.getConfiguration().setSecurityInvalidationInterval(0);
|
||||
server.start();
|
||||
String queue = "queue2";
|
||||
|
@ -261,16 +288,11 @@ public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTes
|
|||
// ok
|
||||
}
|
||||
|
||||
consumer.close();
|
||||
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewProducerPermission() throws Exception {
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
server.getConfiguration().setSecurityInvalidationInterval(0);
|
||||
server.start();
|
||||
String queue = "queue2";
|
||||
|
@ -309,43 +331,6 @@ public class LegacyLDAPSecuritySettingPluginListenerTest extends AbstractLdapTes
|
|||
// ok
|
||||
}
|
||||
|
||||
producer.close();
|
||||
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
private ActiveMQServer getActiveMQServer() {
|
||||
LegacyLDAPSecuritySettingPlugin legacyLDAPSecuritySettingPlugin = new LegacyLDAPSecuritySettingPlugin();
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_URL, "ldap://localhost:1024");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_USERNAME, "uid=admin,ou=system");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_PASSWORD, "secret");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.CONNECTION_PROTOCOL, "s");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.AUTHENTICATION, "simple");
|
||||
map.put(LegacyLDAPSecuritySettingPlugin.ENABLE_LISTENER, "true");
|
||||
legacyLDAPSecuritySettingPlugin.init(map);
|
||||
// .setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory")
|
||||
// .setConnectionURL("ldap://localhost:1024")
|
||||
// .setConnectionUsername("uid=admin,ou=system")
|
||||
// .setConnectionPassword("secret")
|
||||
// .setConnectionProtocol("s")
|
||||
// .setAuthentication("simple")
|
||||
// .setEnableListener(true);
|
||||
|
||||
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
|
||||
Configuration configuration = new ConfigurationImpl()
|
||||
.setSecurityEnabled(true)
|
||||
.addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()))
|
||||
.setJournalDirectory(ActiveMQTestBase.getJournalDir(testDir, 0, false))
|
||||
.setBindingsDirectory(ActiveMQTestBase.getBindingsDir(testDir, 0, false))
|
||||
.setPagingDirectory(ActiveMQTestBase.getPageDir(testDir, 0, false))
|
||||
.setLargeMessagesDirectory(ActiveMQTestBase.getLargeMessagesDir(testDir, 0, false))
|
||||
.setPersistenceEnabled(false)
|
||||
.addSecuritySettingPlugin(legacyLDAPSecuritySettingPlugin);
|
||||
|
||||
return ActiveMQServers.newActiveMQServer(configuration, ManagementFactory.getPlatformMBeanServer(), securityManager, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ import org.apache.directory.server.annotations.CreateTransport;
|
|||
import org.apache.directory.server.core.annotations.ApplyLdifFiles;
|
||||
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
|
||||
import org.apache.directory.server.core.integ.FrameworkRunner;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
|
@ -74,6 +75,7 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
|
|||
}
|
||||
|
||||
private ServerLocator locator;
|
||||
ActiveMQServer server;
|
||||
|
||||
public static final String TARGET_TMP = "./target/tmp";
|
||||
private static final String PRINCIPAL = "uid=admin,ou=system";
|
||||
|
@ -92,8 +94,35 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
locator = ActiveMQClient.createServerLocatorWithHA(new TransportConfiguration(InVMConnectorFactory.class.getCanonicalName()));
|
||||
locator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(InVMConnectorFactory.class.getCanonicalName()));
|
||||
testDir = temporaryFolder.getRoot().getAbsolutePath();
|
||||
|
||||
LegacyLDAPSecuritySettingPlugin legacyLDAPSecuritySettingPlugin = new LegacyLDAPSecuritySettingPlugin()
|
||||
.setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory")
|
||||
.setConnectionURL("ldap://localhost:1024")
|
||||
.setConnectionUsername("uid=admin,ou=system")
|
||||
.setConnectionPassword("secret")
|
||||
.setConnectionProtocol("s")
|
||||
.setAuthentication("simple");
|
||||
|
||||
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
|
||||
Configuration configuration = new ConfigurationImpl()
|
||||
.setSecurityEnabled(true)
|
||||
.addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()))
|
||||
.setJournalDirectory(ActiveMQTestBase.getJournalDir(testDir, 0, false))
|
||||
.setBindingsDirectory(ActiveMQTestBase.getBindingsDir(testDir, 0, false))
|
||||
.setPagingDirectory(ActiveMQTestBase.getPageDir(testDir, 0, false))
|
||||
.setLargeMessagesDirectory(ActiveMQTestBase.getLargeMessagesDir(testDir, 0, false))
|
||||
.setPersistenceEnabled(false)
|
||||
.addSecuritySettingPlugin(legacyLDAPSecuritySettingPlugin);
|
||||
|
||||
server = ActiveMQServers.newActiveMQServer(configuration, ManagementFactory.getPlatformMBeanServer(), securityManager, false);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -124,7 +153,6 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
|
|||
|
||||
@Test
|
||||
public void testBasicPluginAuthorization() throws Exception {
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
server.start();
|
||||
ClientSessionFactory cf = locator.createSessionFactory();
|
||||
String name = "queue1";
|
||||
|
@ -142,8 +170,6 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
|
|||
}
|
||||
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -151,7 +177,6 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
|
|||
final SimpleString ADDRESS = new SimpleString("queue2");
|
||||
final SimpleString QUEUE = new SimpleString("queue2");
|
||||
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
server.start();
|
||||
server.createQueue(ADDRESS, QUEUE, null, true, false);
|
||||
|
||||
|
@ -215,8 +240,6 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
|
|||
|
||||
session.close();
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -224,7 +247,6 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
|
|||
final SimpleString ADDRESS = new SimpleString("queue1");
|
||||
final SimpleString QUEUE = new SimpleString("queue1");
|
||||
|
||||
ActiveMQServer server = getActiveMQServer();
|
||||
server.start();
|
||||
|
||||
ClientSessionFactory cf = locator.createSessionFactory();
|
||||
|
@ -285,30 +307,5 @@ public class LegacyLDAPSecuritySettingPluginTest extends AbstractLdapTestUnit {
|
|||
|
||||
session.close();
|
||||
cf.close();
|
||||
locator.close();
|
||||
server.stop();
|
||||
}
|
||||
|
||||
private ActiveMQServer getActiveMQServer() {
|
||||
LegacyLDAPSecuritySettingPlugin legacyLDAPSecuritySettingPlugin = new LegacyLDAPSecuritySettingPlugin()
|
||||
.setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory")
|
||||
.setConnectionURL("ldap://localhost:1024")
|
||||
.setConnectionUsername("uid=admin,ou=system")
|
||||
.setConnectionPassword("secret")
|
||||
.setConnectionProtocol("s")
|
||||
.setAuthentication("simple");
|
||||
|
||||
ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("LDAPLogin");
|
||||
Configuration configuration = new ConfigurationImpl()
|
||||
.setSecurityEnabled(true)
|
||||
.addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()))
|
||||
.setJournalDirectory(ActiveMQTestBase.getJournalDir(testDir, 0, false))
|
||||
.setBindingsDirectory(ActiveMQTestBase.getBindingsDir(testDir, 0, false))
|
||||
.setPagingDirectory(ActiveMQTestBase.getPageDir(testDir, 0, false))
|
||||
.setLargeMessagesDirectory(ActiveMQTestBase.getLargeMessagesDir(testDir, 0, false))
|
||||
.setPersistenceEnabled(false)
|
||||
.addSecuritySettingPlugin(legacyLDAPSecuritySettingPlugin);
|
||||
|
||||
return ActiveMQServers.newActiveMQServer(configuration, ManagementFactory.getPlatformMBeanServer(), securityManager, false);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue