You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/03/26 04:49:50 UTC
[shardingsphere] branch master updated: Update user privilege in
real time (#9796)
This is an automated email from the ASF dual-hosted git repository.
panjuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new b9feef8 Update user privilege in real time (#9796)
b9feef8 is described below
commit b9feef846dd79ad2841c8287acaf896e2b9ab49c
Author: JingShang Lu <lu...@apache.org>
AuthorDate: Fri Mar 26 12:49:25 2021 +0800
Update user privilege in real time (#9796)
* Update user privilege in real time
* fix
* fix
* fix
* fix
---
.../metadata/GovernanceMetaDataContexts.java | 32 ++++++++++++++++
.../metadata/GovernanceMetaDataContextsTest.java | 5 ++-
.../event/model/auth/PrivilegeChangedEvent.java | 22 ++++++-----
.../governance/core/registry/RegistryCenter.java | 17 +++++++++
.../core/registry/RegistryCenterNode.java | 11 ++++++
.../listener/PrivilegeNodeChangedListener.java | 44 ++++++++++++++++++++++
.../registry/listener/RegistryListenerManager.java | 4 ++
.../GrantEvent.java} | 21 ++++++-----
.../type/GrantStatementAuthRefresher.java | 15 +++++++-
9 files changed, 149 insertions(+), 22 deletions(-)
diff --git a/shardingsphere-governance/shardingsphere-governance-context/src/main/java/org/apache/shardingsphere/governance/context/metadata/GovernanceMetaDataContexts.java b/shardingsphere-governance/shardingsphere-governance-context/src/main/java/org/apache/shardingsphere/governance/context/metadata/GovernanceMetaDataContexts.java
index def19de..890af4a 100644
--- a/shardingsphere-governance/shardingsphere-governance-context/src/main/java/org/apache/shardingsphere/governance/context/metadata/GovernanceMetaDataContexts.java
+++ b/shardingsphere-governance/shardingsphere-governance-context/src/main/java/org/apache/shardingsphere/governance/context/metadata/GovernanceMetaDataContexts.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.governance.context.metadata;
import com.google.common.collect.Maps;
import com.google.common.eventbus.Subscribe;
+import org.apache.shardingsphere.governance.core.event.model.auth.PrivilegeChangedEvent;
import org.apache.shardingsphere.governance.core.event.model.auth.UserRuleChangedEvent;
import org.apache.shardingsphere.governance.core.event.model.datasource.DataSourceChangeCompletedEvent;
import org.apache.shardingsphere.governance.core.event.model.datasource.DataSourceChangedEvent;
@@ -46,6 +47,9 @@ import org.apache.shardingsphere.infra.executor.kernel.ExecutorEngine;
import org.apache.shardingsphere.infra.lock.ShardingSphereLock;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.auth.Authentication;
+import org.apache.shardingsphere.infra.metadata.auth.builder.PrivilegeBuilder;
+import org.apache.shardingsphere.infra.metadata.auth.builder.loader.PrivilegeLoader;
+import org.apache.shardingsphere.infra.metadata.auth.builder.loader.PrivilegeLoaderEngine;
import org.apache.shardingsphere.infra.metadata.auth.builtin.DefaultAuthentication;
import org.apache.shardingsphere.infra.metadata.auth.model.privilege.ShardingSpherePrivilege;
import org.apache.shardingsphere.infra.metadata.auth.model.user.ShardingSphereUser;
@@ -211,6 +215,18 @@ public final class GovernanceMetaDataContexts implements MetaDataContexts {
DefaultAuthentication authentication = new DefaultAuthentication(getNewUsers(users));
authentication.getAuthentication().putAll(getModifiedUsers(users));
metaDataContexts = new StandardMetaDataContexts(metaDataContexts.getMetaDataMap(), metaDataContexts.getExecutorEngine(), authentication, metaDataContexts.getProps());
+ reloadPrivilege(users);
+ }
+
+ /**
+ * Renew privilege.
+ *
+ * @param event privilege changed event
+ */
+ @Subscribe
+ public synchronized void renew(final PrivilegeChangedEvent event) {
+ Collection<ShardingSphereUser> users = event.getUsers();
+ reloadPrivilege(users);
}
/**
@@ -393,4 +409,20 @@ public final class GovernanceMetaDataContexts implements MetaDataContexts {
}
return result;
}
+
+ private void reloadPrivilege(final Collection<ShardingSphereUser> users) {
+ Optional<PrivilegeLoader> loader = PrivilegeLoaderEngine.findPrivilegeLoader(metaDataContexts.getMetaDataMap().values().iterator().next().getResource().getDatabaseType());
+ if (!loader.isPresent()) {
+ return;
+ }
+ Map<ShardingSphereUser, ShardingSpherePrivilege> result = PrivilegeBuilder.build(metaDataContexts.getMetaDataMap().values(), users, metaDataContexts.getProps());
+ for (Entry<ShardingSphereUser, ShardingSpherePrivilege> each : result.entrySet()) {
+ Optional<ShardingSphereUser> user = metaDataContexts.getAuthentication().getAuthentication().keySet().stream().filter(t -> t.getGrantee().equals(t.getGrantee())).findFirst();
+ if (user.isPresent() && null != result.get(each.getKey())) {
+ metaDataContexts.getAuthentication().getAuthentication().put(user.get(), each.getValue());
+ } else if (!user.isPresent() && null != result.get(each.getKey())) {
+ metaDataContexts.getAuthentication().getAuthentication().put(each.getKey(), each.getValue());
+ }
+ }
+ }
}
diff --git a/shardingsphere-governance/shardingsphere-governance-context/src/test/java/org/apache/shardingsphere/governance/context/metadata/GovernanceMetaDataContextsTest.java b/shardingsphere-governance/shardingsphere-governance-context/src/test/java/org/apache/shardingsphere/governance/context/metadata/GovernanceMetaDataContextsTest.java
index 810e6aa..00d4eaa 100644
--- a/shardingsphere-governance/shardingsphere-governance-context/src/test/java/org/apache/shardingsphere/governance/context/metadata/GovernanceMetaDataContextsTest.java
+++ b/shardingsphere-governance/shardingsphere-governance-context/src/test/java/org/apache/shardingsphere/governance/context/metadata/GovernanceMetaDataContextsTest.java
@@ -32,6 +32,7 @@ import org.apache.shardingsphere.infra.config.datasource.DataSourceConfiguration
import org.apache.shardingsphere.infra.config.properties.ConfigurationProperties;
import org.apache.shardingsphere.infra.config.properties.ConfigurationPropertyKey;
import org.apache.shardingsphere.infra.context.metadata.impl.StandardMetaDataContexts;
+import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
import org.apache.shardingsphere.infra.executor.kernel.ExecutorEngine;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.auth.builtin.DefaultAuthentication;
@@ -97,7 +98,9 @@ public final class GovernanceMetaDataContextsTest {
private Map<String, ShardingSphereMetaData> createMetaDataMap() {
when(metaData.getName()).thenReturn("schema");
- when(metaData.getResource()).thenReturn(mock(ShardingSphereResource.class));
+ ShardingSphereResource resource = mock(ShardingSphereResource.class);
+ when(resource.getDatabaseType()).thenReturn(new MySQLDatabaseType());
+ when(metaData.getResource()).thenReturn(resource);
when(metaData.getSchema()).thenReturn(mock(ShardingSphereSchema.class));
when(metaData.getRuleMetaData().getRules()).thenReturn(Collections.singletonList(readWriteSplittingRule));
return Collections.singletonMap("schema", metaData);
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/event/model/auth/PrivilegeChangedEvent.java
similarity index 55%
copy from shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java
copy to shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/event/model/auth/PrivilegeChangedEvent.java
index 0909dc2..a7133fb 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java
+++ b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/event/model/auth/PrivilegeChangedEvent.java
@@ -15,19 +15,21 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.metadata.auth.refresher.type;
+package org.apache.shardingsphere.governance.core.event.model.auth;
-import org.apache.shardingsphere.infra.metadata.auth.Authentication;
-import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
-import org.apache.shardingsphere.infra.metadata.auth.refresher.AuthenticationRefresher;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.governance.core.event.model.GovernanceEvent;
+import org.apache.shardingsphere.infra.metadata.auth.model.user.ShardingSphereUser;
+
+import java.util.Collection;
/**
- * Grant statement auth refresher.
+ * Privilege changed event.
*/
-public final class GrantStatementAuthRefresher implements AuthenticationRefresher {
+@RequiredArgsConstructor
+@Getter
+public final class PrivilegeChangedEvent implements GovernanceEvent {
- @Override
- public void refresh(final Authentication authentication, final SQLStatement sqlStatement, final ShardingSphereMetaData metaData) {
- }
+ private final Collection<ShardingSphereUser> users;
}
diff --git a/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/RegistryCenter.java b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/RegistryCenter.java
index f88fccd..d11d7b1 100644
--- a/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/RegistryCenter.java
+++ b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/RegistryCenter.java
@@ -45,6 +45,7 @@ import org.apache.shardingsphere.infra.eventbus.ShardingSphereEventBus;
import org.apache.shardingsphere.infra.metadata.auth.builtin.yaml.swapper.UserRuleYamlSwapper;
import org.apache.shardingsphere.infra.metadata.auth.model.user.ShardingSphereUser;
import org.apache.shardingsphere.infra.metadata.auth.refresher.event.CreateUserEvent;
+import org.apache.shardingsphere.infra.metadata.auth.refresher.event.GrantEvent;
import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
import org.apache.shardingsphere.infra.metadata.schema.refresher.event.SchemaAlteredEvent;
import org.apache.shardingsphere.infra.rule.event.impl.DataSourceDisabledEvent;
@@ -195,6 +196,12 @@ public final class RegistryCenter {
YamlEngine.marshal(new UserRuleYamlSwapper().swapToYamlConfiguration(users)));
}
}
+
+ private void persistChangedPrivilege(final Collection<ShardingSphereUser> users) {
+ if (!users.isEmpty()) {
+ repository.persist(node.getPrivilegeNodePath(), YamlEngine.marshal(new UserRuleYamlSwapper().swapToYamlConfiguration(users)));
+ }
+ }
private void persistProperties(final Properties props, final boolean isOverwrite) {
if (!props.isEmpty() && (isOverwrite || !hasProperties())) {
@@ -459,6 +466,16 @@ public final class RegistryCenter {
}
/**
+ * User with changed privilege cached event.
+ *
+ * @param event grant event
+ */
+ @Subscribe
+ public synchronized void renew(final GrantEvent event) {
+ persistChangedPrivilege(event.getUsers());
+ }
+
+ /**
* Persist instance online.
*/
public void persistInstanceOnline() {
diff --git a/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/RegistryCenterNode.java b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/RegistryCenterNode.java
index 7b0e340..c5fe9de 100644
--- a/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/RegistryCenterNode.java
+++ b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/RegistryCenterNode.java
@@ -55,6 +55,8 @@ public final class RegistryCenterNode {
private static final String AUTHENTICATION_NODE = "authentication";
+ private static final String PRIVILEGE_NODE = "privilegenode";
+
private static final String PROPS_NODE = "props";
private static final String COMMA_SEPARATOR = ",";
@@ -253,6 +255,15 @@ public final class RegistryCenterNode {
}
/**
+ * Get authenticationnodes path.
+ *
+ * @return authenticationnodes path
+ */
+ public String getPrivilegeNodePath() {
+ return Joiner.on(PATH_SEPARATOR).join(ROOT, PRIVILEGE_NODE);
+ }
+
+ /**
* Get properties path.
*
* @return properties path
diff --git a/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/listener/PrivilegeNodeChangedListener.java b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/listener/PrivilegeNodeChangedListener.java
new file mode 100644
index 0000000..3b7dc8a
--- /dev/null
+++ b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/listener/PrivilegeNodeChangedListener.java
@@ -0,0 +1,44 @@
+/*
+ * 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.governance.core.registry.listener;
+
+import org.apache.shardingsphere.governance.core.event.listener.PostGovernanceRepositoryEventListener;
+import org.apache.shardingsphere.governance.core.event.model.GovernanceEvent;
+import org.apache.shardingsphere.governance.core.event.model.auth.PrivilegeChangedEvent;
+import org.apache.shardingsphere.governance.core.registry.RegistryCenterNode;
+import org.apache.shardingsphere.governance.core.yaml.config.YamlConfigurationConverter;
+import org.apache.shardingsphere.governance.repository.api.RegistryRepository;
+import org.apache.shardingsphere.governance.repository.api.listener.DataChangedEvent;
+
+import java.util.Collections;
+import java.util.Optional;
+
+/**
+ * Authentication changed listener.
+ */
+public final class PrivilegeNodeChangedListener extends PostGovernanceRepositoryEventListener<GovernanceEvent> {
+
+ public PrivilegeNodeChangedListener(final RegistryRepository registryRepository) {
+ super(registryRepository, Collections.singletonList(new RegistryCenterNode().getPrivilegeNodePath()));
+ }
+
+ @Override
+ protected Optional<GovernanceEvent> createEvent(final DataChangedEvent event) {
+ return Optional.of(new PrivilegeChangedEvent(YamlConfigurationConverter.convertUserRule(event.getValue())));
+ }
+}
diff --git a/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/listener/RegistryListenerManager.java b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/listener/RegistryListenerManager.java
index 5cabee7..03bceda 100644
--- a/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/listener/RegistryListenerManager.java
+++ b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/registry/listener/RegistryListenerManager.java
@@ -40,6 +40,8 @@ public final class RegistryListenerManager {
private final AuthenticationChangedListener authenticationChangedListener;
+ private final PrivilegeNodeChangedListener privilegeNodeChangedListener;
+
public RegistryListenerManager(final RegistryRepository registryRepository, final Collection<String> schemaNames) {
terminalStateChangedListener = new TerminalStateChangedListener(registryRepository);
dataSourceStateChangedListener = new DataSourceStateChangedListener(registryRepository, schemaNames);
@@ -47,6 +49,7 @@ public final class RegistryListenerManager {
metaDataListener = new MetaDataListener(registryRepository, schemaNames);
propertiesChangedListener = new PropertiesChangedListener(registryRepository);
authenticationChangedListener = new AuthenticationChangedListener(registryRepository);
+ privilegeNodeChangedListener = new PrivilegeNodeChangedListener(registryRepository);
}
/**
@@ -59,5 +62,6 @@ public final class RegistryListenerManager {
metaDataListener.watch();
propertiesChangedListener.watch(Type.UPDATED);
authenticationChangedListener.watch(Type.UPDATED);
+ privilegeNodeChangedListener.watch(Type.UPDATED);
}
}
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/event/GrantEvent.java
similarity index 60%
copy from shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java
copy to shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/event/GrantEvent.java
index 0909dc2..034a058 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/event/GrantEvent.java
@@ -15,19 +15,20 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.infra.metadata.auth.refresher.type;
+package org.apache.shardingsphere.infra.metadata.auth.refresher.event;
-import org.apache.shardingsphere.infra.metadata.auth.Authentication;
-import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
-import org.apache.shardingsphere.infra.metadata.auth.refresher.AuthenticationRefresher;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.metadata.auth.model.user.ShardingSphereUser;
+
+import java.util.Collection;
/**
- * Grant statement auth refresher.
+ * Grant event.
*/
-public final class GrantStatementAuthRefresher implements AuthenticationRefresher {
+@RequiredArgsConstructor
+@Getter
+public final class GrantEvent {
- @Override
- public void refresh(final Authentication authentication, final SQLStatement sqlStatement, final ShardingSphereMetaData metaData) {
- }
+ private final Collection<ShardingSphereUser> users;
}
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java
index 0909dc2..627cecb 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/metadata/auth/refresher/type/GrantStatementAuthRefresher.java
@@ -17,10 +17,17 @@
package org.apache.shardingsphere.infra.metadata.auth.refresher.type;
-import org.apache.shardingsphere.infra.metadata.auth.Authentication;
+import org.apache.shardingsphere.infra.eventbus.ShardingSphereEventBus;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.metadata.auth.Authentication;
+import org.apache.shardingsphere.infra.metadata.auth.model.user.ShardingSphereUser;
import org.apache.shardingsphere.infra.metadata.auth.refresher.AuthenticationRefresher;
+import org.apache.shardingsphere.infra.metadata.auth.refresher.event.GrantEvent;
import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dcl.MySQLGrantStatement;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
/**
* Grant statement auth refresher.
@@ -29,5 +36,11 @@ public final class GrantStatementAuthRefresher implements AuthenticationRefreshe
@Override
public void refresh(final Authentication authentication, final SQLStatement sqlStatement, final ShardingSphereMetaData metaData) {
+ if (sqlStatement instanceof MySQLGrantStatement) {
+ Collection<ShardingSphereUser> users = ((MySQLGrantStatement) sqlStatement).getUsers().stream()
+ .map(each -> new ShardingSphereUser(each.getUser(), each.getAuth(), each.getHost())).collect(Collectors.toList());
+ ShardingSphereEventBus.getInstance().post(new GrantEvent(users));
+ }
+ // TODO support other db
}
}