Skip to content

Commit

Permalink
[Authorization] Converge authz of ns policies from super-user to tena…
Browse files Browse the repository at this point in the history
…nt-administrator (apache#13157)

* [Authorization] Converge authz of ns policies from super-user to tenant-administrator

* Address all comments
  • Loading branch information
yuruguo authored Dec 18, 2021
1 parent c5d7a84 commit 3cc8309
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1178,7 +1178,7 @@ private NamespaceBundleSplitAlgorithm getNamespaceBundleSplitAlgorithmByName(Str
}

protected void internalSetPublishRate(PublishRate maxPublishMessageRate) {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.RATE, PolicyOperation.WRITE);
log.info("[{}] Set namespace publish-rate {}/{}", clientAppId(), namespaceName, maxPublishMessageRate);
updatePolicies(namespaceName, policies -> {
policies.publishMaxMessageRate.put(pulsar().getConfiguration().getClusterName(), maxPublishMessageRate);
Expand All @@ -1189,7 +1189,7 @@ protected void internalSetPublishRate(PublishRate maxPublishMessageRate) {
}

protected void internalRemovePublishRate() {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.RATE, PolicyOperation.WRITE);
log.info("[{}] Remove namespace publish-rate {}/{}", clientAppId(), namespaceName, topicName);
try {
updatePolicies(namespaceName, policies -> {
Expand All @@ -1216,7 +1216,7 @@ protected PublishRate internalGetPublishRate() {

@SuppressWarnings("deprecation")
protected void internalSetTopicDispatchRate(DispatchRateImpl dispatchRate) {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.RATE, PolicyOperation.WRITE);
log.info("[{}] Set namespace dispatch-rate {}/{}", clientAppId(), namespaceName, dispatchRate);

try {
Expand All @@ -1235,7 +1235,7 @@ protected void internalSetTopicDispatchRate(DispatchRateImpl dispatchRate) {
}

protected void internalDeleteTopicDispatchRate() {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.RATE, PolicyOperation.WRITE);
try {
updatePolicies(namespaceName, policies -> {
policies.topicDispatchRate.remove(pulsar().getConfiguration().getClusterName());
Expand All @@ -1260,7 +1260,7 @@ protected DispatchRate internalGetTopicDispatchRate() {
}

protected void internalSetSubscriptionDispatchRate(DispatchRateImpl dispatchRate) {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.RATE, PolicyOperation.WRITE);
log.info("[{}] Set namespace subscription dispatch-rate {}/{}", clientAppId(), namespaceName, dispatchRate);

try {
Expand All @@ -1278,7 +1278,7 @@ protected void internalSetSubscriptionDispatchRate(DispatchRateImpl dispatchRate
}

protected void internalDeleteSubscriptionDispatchRate() {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.RATE, PolicyOperation.WRITE);

try {
updatePolicies(namespaceName, policies -> {
Expand All @@ -1302,7 +1302,7 @@ protected DispatchRate internalGetSubscriptionDispatchRate() {
}

protected void internalSetSubscribeRate(SubscribeRate subscribeRate) {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.RATE, PolicyOperation.WRITE);
log.info("[{}] Set namespace subscribe-rate {}/{}", clientAppId(), namespaceName, subscribeRate);
try {
updatePolicies(namespaceName, policies -> {
Expand All @@ -1319,7 +1319,7 @@ protected void internalSetSubscribeRate(SubscribeRate subscribeRate) {
}

protected void internalDeleteSubscribeRate() {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.RATE, PolicyOperation.WRITE);
try {
updatePolicies(namespaceName, policies -> {
policies.clusterSubscribeRate.remove(pulsar().getConfiguration().getClusterName());
Expand All @@ -1341,7 +1341,7 @@ protected SubscribeRate internalGetSubscribeRate() {
}

protected void internalRemoveReplicatorDispatchRate() {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.REPLICATION_RATE, PolicyOperation.WRITE);
try {
updatePolicies(namespaceName, policies -> {
policies.replicatorDispatchRate.remove(pulsar().getConfiguration().getClusterName());
Expand All @@ -1357,7 +1357,7 @@ protected void internalRemoveReplicatorDispatchRate() {
}

protected void internalSetReplicatorDispatchRate(DispatchRateImpl dispatchRate) {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.REPLICATION_RATE, PolicyOperation.WRITE);
log.info("[{}] Set namespace replicator dispatch-rate {}/{}", clientAppId(), namespaceName, dispatchRate);
try {
updatePolicies(namespaceName, policies -> {
Expand Down Expand Up @@ -1758,7 +1758,7 @@ protected InactiveTopicPolicies internalGetInactiveTopic() {
}

protected void internalSetInactiveTopic(InactiveTopicPolicies inactiveTopicPolicies) {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.INACTIVE_TOPIC, PolicyOperation.WRITE);
validatePoliciesReadOnlyAccess();
internalSetPolicies("inactive_topic_policies", inactiveTopicPolicies);
}
Expand All @@ -1785,7 +1785,7 @@ protected void internalSetPolicies(String fieldName, Object value) {
}

protected void internalSetDelayedDelivery(DelayedDeliveryPolicies delayedDeliveryPolicies) {
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.DELAYED_DELIVERY, PolicyOperation.WRITE);
validatePoliciesReadOnlyAccess();
internalSetPolicies("delayed_delivery_policies", delayedDeliveryPolicies);
}
Expand Down Expand Up @@ -2179,7 +2179,7 @@ protected Integer internalGetMaxSubscriptionsPerTopic() {
}

protected void internalSetMaxSubscriptionsPerTopic(Integer maxSubscriptionsPerTopic){
validateSuperUserAccess();
validateNamespacePolicyOperation(namespaceName, PolicyName.MAX_SUBSCRIPTIONS, PolicyOperation.WRITE);
validatePoliciesReadOnlyAccess();
if (maxSubscriptionsPerTopic != null && maxSubscriptionsPerTopic < 0) {
throw new RestException(Status.PRECONDITION_FAILED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ public List<String> getNamespacesForCluster(@PathParam("property") String tenant
@Path("/{property}/{cluster}/{namespace}/destinations")
@ApiOperation(hidden = true, value = "Get the list of all the topics under a certain namespace.",
response = String.class, responseContainer = "Set")
@ApiResponses(value = {@ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Property or cluster or namespace doesn't exist")})
public void getTopics(@PathParam("property") String property,
@PathParam("cluster") String cluster, @PathParam("namespace") String namespace,
Expand Down Expand Up @@ -900,7 +901,8 @@ public PersistencePolicies getPersistence(@PathParam("property") String property
@POST
@Path("/{property}/{cluster}/{namespace}/clearBacklog")
@ApiOperation(hidden = true, value = "Clear backlog for all topics on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void clearNamespaceBacklog(@Suspended final AsyncResponse asyncResponse,
@PathParam("property") String property, @PathParam("cluster") String cluster,
Expand All @@ -921,7 +923,7 @@ public void clearNamespaceBacklog(@Suspended final AsyncResponse asyncResponse,
@ApiOperation(hidden = true, value = "Clear backlog for all topics on a namespace bundle.")
@ApiResponses(value = {
@ApiResponse(code = 307, message = "Current broker doesn't serve the namespace"),
@ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void clearNamespaceBundleBacklog(@PathParam("property") String property,
@PathParam("cluster") String cluster, @PathParam("namespace") String namespace,
Expand All @@ -934,7 +936,8 @@ public void clearNamespaceBundleBacklog(@PathParam("property") String property,
@POST
@Path("/{property}/{cluster}/{namespace}/clearBacklog/{subscription}")
@ApiOperation(hidden = true, value = "Clear backlog for a given subscription on all topics on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void clearNamespaceBacklogForSubscription(@Suspended final AsyncResponse asyncResponse,
@PathParam("property") String property, @PathParam("cluster") String cluster,
Expand All @@ -955,7 +958,7 @@ public void clearNamespaceBacklogForSubscription(@Suspended final AsyncResponse
@ApiOperation(hidden = true, value = "Clear backlog for a given subscription on all topics on a namespace bundle.")
@ApiResponses(value = {
@ApiResponse(code = 307, message = "Current broker doesn't serve the namespace"),
@ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void clearNamespaceBundleBacklogForSubscription(@PathParam("property") String property,
@PathParam("cluster") String cluster, @PathParam("namespace") String namespace,
Expand All @@ -968,7 +971,8 @@ public void clearNamespaceBundleBacklogForSubscription(@PathParam("property") St
@POST
@Path("/{property}/{cluster}/{namespace}/unsubscribe/{subscription}")
@ApiOperation(hidden = true, value = "Unsubscribes the given subscription on all topics on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void unsubscribeNamespace(@Suspended final AsyncResponse asyncResponse,
@PathParam("property") String property, @PathParam("cluster") String cluster,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ public class PersistentTopics extends PersistentTopicsBase {
@Path("/{property}/{cluster}/{namespace}")
@ApiOperation(hidden = true, value = "Get the list of topics under a namespace.",
response = String.class, responseContainer = "List")
@ApiResponses(value = {@ApiResponse(code = 403, message = "Don't have admin or consume permission on namespace"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace doesn't exist")})
public void getList(@Suspended final AsyncResponse asyncResponse, @PathParam("property") String property,
@PathParam("cluster") String cluster, @PathParam("namespace") String namespace) {
Expand All @@ -87,7 +88,8 @@ public void getList(@Suspended final AsyncResponse asyncResponse, @PathParam("pr
@Path("/{property}/{cluster}/{namespace}/partitioned")
@ApiOperation(hidden = true, value = "Get the list of partitioned topics under a namespace.",
response = String.class, responseContainer = "List")
@ApiResponses(value = {@ApiResponse(code = 403, message = "Don't have admin or consume permission on namespace"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace doesn't exist")})
public List<String> getPartitionedTopicList(@PathParam("property") String property,
@PathParam("cluster") String cluster, @PathParam("namespace") String namespace) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ public List<String> getTenantNamespaces(@PathParam("tenant") String tenant) {
@Path("/{tenant}/{namespace}/topics")
@ApiOperation(value = "Get the list of all the topics under a certain namespace.",
response = String.class, responseContainer = "Set")
@ApiResponses(value = {@ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Tenant or cluster or namespace doesn't exist")})
public void getTopics(@PathParam("tenant") String tenant,
@PathParam("namespace") String namespace,
Expand Down Expand Up @@ -906,7 +907,8 @@ public PersistencePolicies getPersistence(@PathParam("tenant") String tenant,
@POST
@Path("/{tenant}/{namespace}/clearBacklog")
@ApiOperation(value = "Clear backlog for all topics on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void clearNamespaceBacklog(@Suspended final AsyncResponse asyncResponse, @PathParam("tenant") String tenant,
@PathParam("namespace") String namespace,
Expand All @@ -926,7 +928,7 @@ public void clearNamespaceBacklog(@Suspended final AsyncResponse asyncResponse,
@ApiOperation(value = "Clear backlog for all topics on a namespace bundle.")
@ApiResponses(value = {
@ApiResponse(code = 307, message = "Current broker doesn't serve the namespace"),
@ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void clearNamespaceBundleBacklog(@PathParam("tenant") String tenant,
@PathParam("namespace") String namespace, @PathParam("bundle") String bundleRange,
Expand All @@ -938,7 +940,8 @@ public void clearNamespaceBundleBacklog(@PathParam("tenant") String tenant,
@POST
@Path("/{tenant}/{namespace}/clearBacklog/{subscription}")
@ApiOperation(value = "Clear backlog for a given subscription on all topics on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void clearNamespaceBacklogForSubscription(@Suspended final AsyncResponse asyncResponse,
@PathParam("tenant") String tenant, @PathParam("namespace") String namespace,
Expand All @@ -959,7 +962,7 @@ public void clearNamespaceBacklogForSubscription(@Suspended final AsyncResponse
@ApiOperation(value = "Clear backlog for a given subscription on all topics on a namespace bundle.")
@ApiResponses(value = {
@ApiResponse(code = 307, message = "Current broker doesn't serve the namespace"),
@ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void clearNamespaceBundleBacklogForSubscription(@PathParam("tenant") String tenant,
@PathParam("namespace") String namespace, @PathParam("subscription") String subscription,
Expand All @@ -972,7 +975,8 @@ public void clearNamespaceBundleBacklogForSubscription(@PathParam("tenant") Stri
@POST
@Path("/{tenant}/{namespace}/unsubscribe/{subscription}")
@ApiOperation(value = "Unsubscribes the given subscription on all topics on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"),
@ApiResponses(value = {
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "Namespace does not exist") })
public void unsubscribeNamespace(@Suspended final AsyncResponse asyncResponse, @PathParam("tenant") String tenant,
@PathParam("namespace") String namespace,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public class PersistentTopics extends PersistentTopicsBase {
response = String.class, responseContainer = "List")
@ApiResponses(value = {
@ApiResponse(code = 401, message = "Don't have permission to administrate resources on this tenant"),
@ApiResponse(code = 403, message = "Don't have admin or consume permission on namespace"),
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "tenant/namespace/topic doesn't exit"),
@ApiResponse(code = 412, message = "Namespace name is not valid"),
@ApiResponse(code = 500, message = "Internal server error")})
Expand All @@ -111,7 +111,7 @@ public void getList(
response = String.class, responseContainer = "List")
@ApiResponses(value = {
@ApiResponse(code = 401, message = "Don't have permission to administrate resources on this tenant"),
@ApiResponse(code = 403, message = "Don't have admin or consume permission on namespace"),
@ApiResponse(code = 403, message = "Don't have admin or operate permission on the namespace"),
@ApiResponse(code = 404, message = "tenant/namespace/topic doesn't exit"),
@ApiResponse(code = 412, message = "Namespace name is not valid"),
@ApiResponse(code = 500, message = "Internal server error")})
Expand Down
Loading

0 comments on commit 3cc8309

Please sign in to comment.