Skip to content

Commit

Permalink
ShardingProxy supports multiple users and authorizedSchemas (#2237)
Browse files Browse the repository at this point in the history
* rename to UserChangedListenerTest

* use AuthenticationChangedListenerTest

* use UserYamlSwapperTest

* modify authentication

* Authentication changed event

* Authentication changed listener

* modify AUTHENTICATION_YAML

* check style

* check style

* modify swap()

* add AuthenticationYamlSwapperTest.java

* use Authentication()

* modify AUTHENTICATION_YAML

* Authentication engine for MySQL.

* login()

* Authentication engine

* modify unit cases in MySQLAuthenticationHandlerTest.java

* setAuthentication()

* use Authentication

* modify javadoc

* modify javadoc

* modify loadServerConfiguration()

* use authentication in loadServerConfiguration

* modify unit cases

* add user

* add UserYamlSwapper

* modify YamlAuthentication

* use YamlUser

* delete new YamlAuthentication()

* add YamlUser.java

* modify AUTHENTICATION_YAML content

* use Collections

* use Collections

* modify config

* use Collections

* modify unit cases

* prefer to use Collections

* modify swap()

* add isAuthorizedSchema()

* isAuthorizedSchema()

* add userName

* modify assertMarshal()

* getSchemaNames()

* mock(BackendConnection.class)

* new ShowDatabasesBackendHandler(backendConnection)

* modify setUp()

* modify setUp()

* !authorizedSchemas.isEmpty()

* trimResults()

* isAuthorizedSchema()

* modify isAuthorizedSchema()

* isAuthorizedSchema(final String schema)

* rename to ProxyUser

* rename to ProxyUserYamlSwapperTest

* modify examples

* use ProxyUserYamlSwapperTest

* use ProxyUser

* use ProxyUser

* Proxy user YAML swapper

* rename to ProxyUserYamlSwapper

* use ProxyUserYamlSwapper

* ProxyUserYamlSwapperTest

* USE YamlProxyUser

* rename to YamlProxyUser

* use YamlProxyUser

* use YamlProxyUser

* rename to  YamlAuthenticationConfiguration

* rename to YamlAuthenticationConfiguration

* use YamlAuthenticationConfiguration

* use YamlAuthenticationConfiguration

* rename to YamlProxyUserConfiguration

* use YamlProxyUserConfiguration

* use YamlProxyUserConfiguration
  • Loading branch information
tristaZero authored and terrymanu committed Apr 21, 2019
1 parent 7f4faf2 commit 5020861
Show file tree
Hide file tree
Showing 31 changed files with 371 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.HashMap;
import java.util.Map;

/**
* Authentication.
*
Expand All @@ -29,7 +32,5 @@
@Getter
public final class Authentication {

private final String username;

private final String password;
private Map<String, ProxyUser> users = new HashMap<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.shardingsphere.core.rule;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.Collection;

/**
* Proxy user.
*
* @author panjuan
*/
@RequiredArgsConstructor
@Getter
public final class ProxyUser {

private final String password;

private final Collection<String> authorizedSchemas;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.shardingsphere.core.yaml.config.common;

import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.core.yaml.config.YamlConfiguration;

import java.util.HashMap;
import java.util.Map;

/**
* Authentication configuration for YAML.
*
* @author panjuan
*/
@Getter
@Setter
public final class YamlAuthenticationConfiguration implements YamlConfiguration {

private Map<String, YamlProxyUserConfiguration> users = new HashMap<>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@
import org.apache.shardingsphere.core.yaml.config.YamlConfiguration;

/**
* Authentication for YAML.
* Proxy user for YAML.
*
* @author zhangliang
*/
@Getter
@Setter
public final class YamlAuthentication implements YamlConfiguration {

private String username;
public final class YamlProxyUserConfiguration implements YamlConfiguration {

private String password;

private String authorizedSchemas;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,46 @@

package org.apache.shardingsphere.core.yaml.swapper.impl;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import org.apache.shardingsphere.core.rule.Authentication;
import org.apache.shardingsphere.core.yaml.config.common.YamlAuthentication;
import org.apache.shardingsphere.core.rule.ProxyUser;
import org.apache.shardingsphere.core.yaml.config.common.YamlAuthenticationConfiguration;
import org.apache.shardingsphere.core.yaml.config.common.YamlProxyUserConfiguration;
import org.apache.shardingsphere.core.yaml.swapper.YamlSwapper;

/**
* Authentication YAML swapper.
*
* @author zhangliang
*/
public final class AuthenticationYamlSwapper implements YamlSwapper<YamlAuthentication, Authentication> {
public final class AuthenticationYamlSwapper implements YamlSwapper<YamlAuthenticationConfiguration, Authentication> {

private final ProxyUserYamlSwapper proxyUserYamlSwapper = new ProxyUserYamlSwapper();

@Override
public YamlAuthentication swap(final Authentication data) {
YamlAuthentication result = new YamlAuthentication();
result.setUsername(data.getUsername());
result.setPassword(data.getPassword());
public YamlAuthenticationConfiguration swap(final Authentication data) {
YamlAuthenticationConfiguration result = new YamlAuthenticationConfiguration();
result.getUsers().putAll(Maps.transformValues(data.getUsers(), new Function<ProxyUser, YamlProxyUserConfiguration>() {

@Override
public YamlProxyUserConfiguration apply(final ProxyUser input) {
return proxyUserYamlSwapper.swap(input);
}
}));
return result;
}

@Override
public Authentication swap(final YamlAuthentication yamlConfiguration) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(yamlConfiguration.getUsername()), "Username is required.");
return new Authentication(yamlConfiguration.getUsername(), yamlConfiguration.getPassword());
public Authentication swap(final YamlAuthenticationConfiguration yamlConfiguration) {
Authentication result = new Authentication();
result.getUsers().putAll(Maps.transformValues(yamlConfiguration.getUsers(), new Function<YamlProxyUserConfiguration, ProxyUser>() {

@Override
public ProxyUser apply(final YamlProxyUserConfiguration input) {
return proxyUserYamlSwapper.swap(input);
}
}));
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.shardingsphere.core.yaml.swapper.impl;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import org.apache.shardingsphere.core.rule.ProxyUser;
import org.apache.shardingsphere.core.yaml.config.common.YamlProxyUserConfiguration;
import org.apache.shardingsphere.core.yaml.swapper.YamlSwapper;

import java.util.Collections;

/**
* Proxy user YAML swapper.
*
* @author zhangliang
*/
public final class ProxyUserYamlSwapper implements YamlSwapper<YamlProxyUserConfiguration, ProxyUser> {

@Override
public YamlProxyUserConfiguration swap(final ProxyUser data) {
YamlProxyUserConfiguration result = new YamlProxyUserConfiguration();
result.setPassword(data.getPassword());
String authorizedSchemas = null == data.getAuthorizedSchemas() ? "" : Joiner.on(',').join(data.getAuthorizedSchemas());
result.setAuthorizedSchemas(authorizedSchemas);
return result;
}

@Override
public ProxyUser swap(final YamlProxyUserConfiguration yamlConfiguration) {
if (Strings.isNullOrEmpty(yamlConfiguration.getAuthorizedSchemas())) {
return new ProxyUser(yamlConfiguration.getPassword(), Collections.<String>emptyList());
}
return new ProxyUser(yamlConfiguration.getPassword(), Splitter.on(',').trimResults().splitToList(yamlConfiguration.getAuthorizedSchemas()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

package org.apache.shardingsphere.core.yaml.engine;

import org.apache.shardingsphere.core.yaml.config.common.YamlAuthentication;
import org.apache.shardingsphere.core.yaml.config.common.YamlProxyUserConfiguration;
import org.junit.Test;

import java.util.Map;
Expand All @@ -30,32 +30,32 @@ public final class YamlEngineTest {

@Test
public void assertUnmarshal() {
YamlAuthentication actual = YamlEngine.unmarshal("username: root\npassword: pwd", YamlAuthentication.class);
assertThat(actual.getUsername(), is("root"));
YamlProxyUserConfiguration actual = YamlEngine.unmarshal("password: pwd\nauthorizedSchemas: db1", YamlProxyUserConfiguration.class);
assertThat(actual.getPassword(), is("pwd"));
assertThat(actual.getAuthorizedSchemas(), is("db1"));
}

@SuppressWarnings("unchecked")
@Test
public void assertUnmarshalMap() {
Map<String, Object> actual = (Map<String, Object>) YamlEngine.unmarshal("username: root\npassword: pwd");
assertThat(actual.get("username").toString(), is("root"));
Map<String, Object> actual = (Map<String, Object>) YamlEngine.unmarshal("password: pwd\nauthorizedSchemas: db1");
assertThat(actual.get("password").toString(), is("pwd"));
assertThat(actual.get("authorizedSchemas").toString(), is("db1"));
}

@SuppressWarnings("unchecked")
@Test
public void assertUnmarshalProperties() {
Properties actual = YamlEngine.unmarshalProperties("username: root\npassword: pwd");
assertThat(actual.getProperty("username"), is("root"));
Properties actual = YamlEngine.unmarshalProperties("password: pwd\nauthorizedSchemas: db1");
assertThat(actual.getProperty("authorizedSchemas"), is("db1"));
assertThat(actual.getProperty("password"), is("pwd"));
}

@Test
public void assertMarshal() {
YamlAuthentication actual = new YamlAuthentication();
actual.setUsername("root");
YamlProxyUserConfiguration actual = new YamlProxyUserConfiguration();
actual.setPassword("pwd");
assertThat(YamlEngine.marshal(actual), is("password: pwd\nusername: root\n"));
actual.setAuthorizedSchemas("db1");
assertThat(YamlEngine.marshal(actual), is("authorizedSchemas: db1\npassword: pwd\n"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

package org.apache.shardingsphere.core.yaml.swapper;

import org.apache.shardingsphere.core.yaml.swapper.impl.AuthenticationYamlSwapperTest;
import org.apache.shardingsphere.core.yaml.swapper.impl.EncryptorRuleConfigurationYamlSwapperTest;
import org.apache.shardingsphere.core.yaml.swapper.impl.KeyGeneratorConfigurationYamlSwapperTest;
import org.apache.shardingsphere.core.yaml.swapper.impl.MasterSlaveRuleConfigurationYamlSwapperTest;
import org.apache.shardingsphere.core.yaml.swapper.impl.ProxyUserYamlSwapperTest;
import org.apache.shardingsphere.core.yaml.swapper.impl.ShardingRuleConfigurationYamlSwapperTest;
import org.apache.shardingsphere.core.yaml.swapper.impl.ShardingStrategyConfigurationYamlSwapperTest;
import org.apache.shardingsphere.core.yaml.swapper.impl.TableRuleConfigurationYamlSwapperTest;
Expand All @@ -36,7 +36,7 @@
ShardingStrategyConfigurationYamlSwapperTest.class,
KeyGeneratorConfigurationYamlSwapperTest.class,
EncryptorRuleConfigurationYamlSwapperTest.class,
AuthenticationYamlSwapperTest.class
ProxyUserYamlSwapperTest.class
})
public final class AllSwapperTests {
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,31 @@

package org.apache.shardingsphere.core.yaml.swapper.impl;

import org.apache.shardingsphere.core.rule.Authentication;
import org.apache.shardingsphere.core.yaml.config.common.YamlAuthentication;
import org.apache.shardingsphere.core.rule.ProxyUser;
import org.apache.shardingsphere.core.yaml.config.common.YamlProxyUserConfiguration;
import org.junit.Test;

import java.util.Collections;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public final class AuthenticationYamlSwapperTest {
public final class ProxyUserYamlSwapperTest {

@Test
public void assertSwapToYaml() {
YamlAuthentication actual = new AuthenticationYamlSwapper().swap(new Authentication("root", "pwd"));
assertThat(actual.getUsername(), is("root"));
YamlProxyUserConfiguration actual = new ProxyUserYamlSwapper().swap(new ProxyUser("pwd", Collections.singleton("db1")));
assertThat(actual.getAuthorizedSchemas(), is("db1"));
assertThat(actual.getPassword(), is("pwd"));
}

@Test
public void assertSwapToObject() {
YamlAuthentication yamlAuthentication = new YamlAuthentication();
yamlAuthentication.setUsername("root");
yamlAuthentication.setPassword("pwd");
Authentication actual = new AuthenticationYamlSwapper().swap(yamlAuthentication);
assertThat(actual.getUsername(), is("root"));
YamlProxyUserConfiguration yamlProxyUserConfiguration = new YamlProxyUserConfiguration();
yamlProxyUserConfiguration.setAuthorizedSchemas("db1");
yamlProxyUserConfiguration.setPassword("pwd");
ProxyUser actual = new ProxyUserYamlSwapper().swap(yamlProxyUserConfiguration);
assertThat(actual.getAuthorizedSchemas().iterator().next(), is("db1"));
assertThat(actual.getPassword(), is("pwd"));
}

@Test(expected = IllegalArgumentException.class)
public void assertSwapToObjectWithoutUsername() {
new AuthenticationYamlSwapper().swap(new YamlAuthentication());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

package org.apache.shardingsphere.orchestration.internal.registry.config.listener;

import org.apache.shardingsphere.core.yaml.config.common.YamlAuthentication;
import org.apache.shardingsphere.core.yaml.config.common.YamlAuthenticationConfiguration;
import org.apache.shardingsphere.core.yaml.engine.YamlEngine;
import org.apache.shardingsphere.core.yaml.swapper.impl.AuthenticationYamlSwapper;
import org.apache.shardingsphere.orchestration.internal.registry.config.event.AuthenticationChangedEvent;
Expand All @@ -39,6 +39,6 @@ public AuthenticationChangedListener(final String name, final RegistryCenter reg

@Override
protected AuthenticationChangedEvent createShardingOrchestrationEvent(final DataChangedEvent event) {
return new AuthenticationChangedEvent(new AuthenticationYamlSwapper().swap(YamlEngine.unmarshal(event.getValue(), YamlAuthentication.class)));
return new AuthenticationChangedEvent(new AuthenticationYamlSwapper().swap(YamlEngine.unmarshal(event.getValue(), YamlAuthenticationConfiguration.class)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.core.config.DataSourceConfiguration;
import org.apache.shardingsphere.core.rule.Authentication;
import org.apache.shardingsphere.core.yaml.config.common.YamlAuthentication;
import org.apache.shardingsphere.core.yaml.config.common.YamlAuthenticationConfiguration;
import org.apache.shardingsphere.core.yaml.config.masterslave.YamlMasterSlaveRuleConfiguration;
import org.apache.shardingsphere.core.yaml.config.sharding.YamlShardingRuleConfiguration;
import org.apache.shardingsphere.core.yaml.engine.YamlEngine;
Expand Down Expand Up @@ -211,7 +211,7 @@ public MasterSlaveRuleConfiguration loadMasterSlaveRuleConfiguration(final Strin
* @return authentication
*/
public Authentication loadAuthentication() {
return new AuthenticationYamlSwapper().swap(YamlEngine.unmarshal(regCenter.getDirectly(configNode.getAuthenticationPath()), YamlAuthentication.class));
return new AuthenticationYamlSwapper().swap(YamlEngine.unmarshal(regCenter.getDirectly(configNode.getAuthenticationPath()), YamlAuthenticationConfiguration.class));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.shardingsphere.api.config.RuleConfiguration;
import org.apache.shardingsphere.core.config.DataSourceConfiguration;
import org.apache.shardingsphere.core.rule.Authentication;
import org.apache.shardingsphere.core.rule.ProxyUser;
import org.apache.shardingsphere.orchestration.config.OrchestrationConfiguration;
import org.apache.shardingsphere.orchestration.internal.registry.config.service.ConfigurationService;
import org.apache.shardingsphere.orchestration.internal.registry.listener.ShardingOrchestrationListenerManager;
Expand Down Expand Up @@ -73,7 +74,9 @@ public void setUp() {
public void assertInitWithParameters() {
Map<String, DataSourceConfiguration> dataSourceConfigurationMap = Collections.singletonMap("test_ds", mock(DataSourceConfiguration.class));
Map<String, RuleConfiguration> ruleConfigurationMap = Collections.singletonMap("sharding_db", mock(RuleConfiguration.class));
Authentication authentication = new Authentication("root", "root");
ProxyUser proxyUser = new ProxyUser("root", Collections.singleton("db1"));
Authentication authentication = new Authentication();
authentication.getUsers().put("root", proxyUser);
Properties props = new Properties();
shardingOrchestrationFacade.init(Collections.singletonMap("sharding_db", dataSourceConfigurationMap), ruleConfigurationMap, authentication, props);
verify(configService).persistConfiguration("sharding_db", dataSourceConfigurationMap, ruleConfigurationMap.get("sharding_db"), authentication, props, true);
Expand Down
Loading

0 comments on commit 5020861

Please sign in to comment.