From 882a6305b9171d855dd9b38239404ca823f3f513 Mon Sep 17 00:00:00 2001 From: Zhangmei Li Date: Fri, 12 Mar 2021 22:41:32 +0800 Subject: [PATCH] Transfer permission of some operations from STATUS to ANY Change-Id: I7ca443973ff27f45c4d61ac3f4b4c39075d70ba2 --- .../api/filter/AuthenticationFilter.java | 64 ++++++++++++------- .../hugegraph/auth/HugeAuthenticator.java | 28 ++------ .../hugegraph/auth/HugeGraphAuthProxy.java | 44 +++++++------ 3 files changed, 71 insertions(+), 65 deletions(-) diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/AuthenticationFilter.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/AuthenticationFilter.java index 99c8692235..12925a8332 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/AuthenticationFilter.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/AuthenticationFilter.java @@ -48,7 +48,6 @@ import com.baidu.hugegraph.auth.HugeAuthenticator.User; import com.baidu.hugegraph.auth.RolePermission; import com.baidu.hugegraph.core.GraphManager; -import com.baidu.hugegraph.server.RestServer; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; import com.google.common.collect.ImmutableMap; @@ -58,7 +57,7 @@ @Priority(Priorities.AUTHENTICATION) public class AuthenticationFilter implements ContainerRequestFilter { - private static final Logger LOG = Log.logger(RestServer.class); + private static final Logger LOG = Log.logger(AuthenticationFilter.class); @Context private javax.inject.Provider managerProvider; @@ -159,20 +158,12 @@ public Principal getUserPrincipal() { @Override public boolean isUserInRole(String required) { - boolean valid; if (required.equals(HugeAuthenticator.KEY_DYNAMIC)) { // Let the resource itself determine dynamically - valid = true; + return true; } else { - valid = this.matchPermission(required); - } - - if (!valid && LOG.isDebugEnabled() && - !required.equals(HugeAuthenticator.ROLE_ADMIN)) { - LOG.debug("Permission denied to {}, expect permission '{}'", - this.user, required); + return this.matchPermission(required); } - return valid; } @Override @@ -186,24 +177,49 @@ public String getAuthenticationScheme() { } private boolean matchPermission(String required) { + boolean valid; + RequiredPerm requiredPerm; + if (!required.startsWith(HugeAuthenticator.KEY_OWNER)) { // Permission format like: "admin" - return RolePerm.match(this.role(), required); + requiredPerm = new RequiredPerm(); + requiredPerm.owner(required); + } else { + // The required like: $owner=graph1 $action=vertex_write + requiredPerm = RequiredPerm.fromPermission(required); + + /* + * Replace owner value(it may be a variable) if the permission + * format like: "$owner=$graph $action=vertex_write" + */ + String owner = requiredPerm.owner(); + if (owner.startsWith(HugeAuthenticator.VAR_PREFIX)) { + // Replace `$graph` with graph name like "graph1" + int prefixLen = HugeAuthenticator.VAR_PREFIX.length(); + assert owner.length() > prefixLen; + owner = owner.substring(prefixLen); + owner = this.getPathParameter(owner); + requiredPerm.owner(owner); + } } - // Permission format like: "$owner=$graph $action=vertex-write" - RequiredPerm requiredPerm = RequiredPerm.fromPermission(required); - - // Replace owner value(may be variable) if needed - String owner = requiredPerm.owner(); - if (owner.startsWith(HugeAuthenticator.VAR_PREFIX)) { - assert owner.length() > HugeAuthenticator.VAR_PREFIX.length(); - owner = owner.substring(HugeAuthenticator.VAR_PREFIX.length()); - owner = this.getPathParameter(owner); - requiredPerm.owner(owner); + if (LOG.isDebugEnabled()) { + LOG.debug("Verify permission {} {} for user '{}' with role {}", + requiredPerm.action().string(), + requiredPerm.resourceObject(), + this.user.username(), this.user.role()); } - return RolePerm.match(this.role(), requiredPerm); + // verify role permission + valid = RolePerm.match(this.role(), requiredPerm); + + if (!valid && LOG.isInfoEnabled() && + !required.equals(HugeAuthenticator.USER_ADMIN)) { + LOG.info("User '{}' is denied to {} {}", + this.user.username(), requiredPerm.action().string(), + requiredPerm.resourceObject()); + } + return valid; } private String getPathParameter(String key) { diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeAuthenticator.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeAuthenticator.java index cd72272f04..c8b39d3191 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeAuthenticator.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeAuthenticator.java @@ -324,36 +324,22 @@ public static RolePerm fromJson(Object role) { return new RolePerm((Map) table.map()); } - public static boolean match(Object role, Object requiredPerm) { + public static boolean match(Object role, RequiredPerm requiredPerm) { if (role == ROLE_ADMIN) { return true; } if (role == ROLE_NONE) { return false; } - RolePerm rolePerm = RolePerm.fromJson(role); - RequiredPerm actionRequiredPerm; - if (requiredPerm instanceof RequiredPerm) { - actionRequiredPerm = (RequiredPerm) requiredPerm; - } else { - // The required like: $owner=graph1 $action=vertex-write - String required = (String) requiredPerm; - if (!required.startsWith(KEY_OWNER)) { - /* - * The required parameter means the owner if not started - * with ROLE_OWNER, any action is OK if the owner matched. - */ - return rolePerm.matchOwner(required); - } - actionRequiredPerm = RequiredPerm.fromPermission(required); - } + RolePerm rolePerm = RolePerm.fromJson(role); - if (actionRequiredPerm.action() == HugePermission.NONE) { - return rolePerm.matchOwner(actionRequiredPerm.owner()); + if (requiredPerm.action() == HugePermission.NONE) { + // None action means any action is OK if the owner matched + return rolePerm.matchOwner(requiredPerm.owner()); } - return rolePerm.matchResource(actionRequiredPerm.action(), - actionRequiredPerm.resourceObject()); + return rolePerm.matchResource(requiredPerm.action(), + requiredPerm.resourceObject()); } public static boolean match(Object role, HugePermission required, diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java index 36ffbe32d6..bb495d7619 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java @@ -122,13 +122,13 @@ public HugeGraph hugegraph() { @Override public C compute(Class clazz) throws IllegalArgumentException { - this.verifyStatusPermission(); + this.verifyAnyPermission(); return this.hugegraph.compute(clazz); } @Override public GraphComputer compute() throws IllegalArgumentException { - this.verifyStatusPermission(); + this.verifyAnyPermission(); return this.hugegraph.compute(); } @@ -141,7 +141,7 @@ public GraphTraversalSource traversal() { @SuppressWarnings({ "rawtypes", "deprecation" }) @Override public I io(final Io.Builder builder) { - this.verifyStatusPermission(); + this.verifyAnyPermission(); return this.hugegraph.io(builder); } @@ -451,7 +451,7 @@ public Iterator adjacentVertices(Iterator edges) { @Override public boolean checkAdjacentVertexExist() { - verifyStatusPermission(); + verifyAnyPermission(); return this.hugegraph.checkAdjacentVertexExist(); } @@ -511,7 +511,7 @@ public void close() throws Exception { @Override public HugeFeatures features() { // Can't verifyPermission() here, will be called by rollbackAll() - //verifyPermission(HugePermission.READ, ResourceType.STATUS); + //verifyStatusPermission(); return this.hugegraph.features(); } @@ -528,7 +528,7 @@ public HugeConfig configuration() { @Override public String toString() { - this.verifyStatusPermission(); + this.verifyAnyPermission(); return this.hugegraph.toString(); } @@ -553,25 +553,25 @@ public long now() { @Override public V option(ConfigOption option) { - this.verifyStatusPermission(); + this.verifyAnyPermission(); return this.hugegraph.option(option); } @Override public String name() { - this.verifyStatusPermission(); + this.verifyAnyPermission(); return this.hugegraph.name(); } @Override public String backend() { - this.verifyStatusPermission(); + this.verifyAnyPermission(); return this.hugegraph.backend(); } @Override public String backendVersion() { - this.verifyStatusPermission(); + this.verifyAnyPermission(); return this.hugegraph.backendVersion(); } @@ -583,13 +583,13 @@ public BackendStoreSystemInfo backendStoreSystemInfo() { @Override public BackendFeatures backendStoreFeatures() { - this.verifyPermission(HugePermission.READ, ResourceType.STATUS); + this.verifyAnyPermission(); return this.hugegraph.backendStoreFeatures(); } @Override public GraphMode mode() { - this.verifyPermission(HugePermission.READ, ResourceType.STATUS); + this.verifyStatusPermission(); return this.hugegraph.mode(); } @@ -601,7 +601,7 @@ public void mode(GraphMode mode) { @Override public GraphReadMode readMode() { - this.verifyPermission(HugePermission.READ, ResourceType.STATUS); + this.verifyStatusPermission(); return this.hugegraph.readMode(); } @@ -613,7 +613,7 @@ public void readMode(GraphReadMode readMode) { @Override public void waitStarted() { - this.verifyPermission(HugePermission.READ, ResourceType.STATUS); + this.verifyAnyPermission(); this.hugegraph.waitStarted(); } @@ -708,6 +708,10 @@ private void verifyStatusPermission() { verifyPermission(HugePermission.READ, ResourceType.STATUS); } + private void verifyAnyPermission() { + verifyPermission(HugePermission.READ, ResourceType.NONE); + } + private void verifyPermission(HugePermission actionPerm, ResourceType resType) { /* @@ -860,8 +864,8 @@ private V verifyResPermission(HugePermission actionPerm, String action = actionPerm.string(); if (LOG.isDebugEnabled()) { - LOG.debug("Verify permission '{}' for role '{}' with resource {}", - action, role, ro); + LOG.debug("Verify permission {} {} for user '{}' with role {}", + action, ro, username, role); } V result = ro.operated(); @@ -979,27 +983,27 @@ public boolean close() { @Override public HugeTask waitUntilTaskCompleted(Id id, long seconds) throws TimeoutException { - verifyStatusPermission(); + verifyAnyPermission(); return this.taskScheduler.waitUntilTaskCompleted(id, seconds); } @Override public HugeTask waitUntilTaskCompleted(Id id) throws TimeoutException { - verifyStatusPermission(); + verifyAnyPermission(); return this.taskScheduler.waitUntilTaskCompleted(id); } @Override public void waitUntilAllTasksCompleted(long seconds) throws TimeoutException { - verifyStatusPermission(); + verifyAnyPermission(); this.taskScheduler.waitUntilAllTasksCompleted(seconds); } @Override public void checkRequirement(String op) { - verifyStatusPermission(); + verifyAnyPermission(); this.taskScheduler.checkRequirement(op); }