Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import org.apache.commons.lang3.StringUtils;
import org.apache.pulsar.broker.ServiceConfiguration;
import org.apache.pulsar.broker.authentication.AuthenticationDataSource;
import org.apache.pulsar.broker.cache.ConfigurationCacheService;
Expand Down Expand Up @@ -225,12 +226,19 @@ CompletableFuture<Void> grantPermissionAsync(TopicName topicName, Set<AuthAction
* @param authData
* @return CompletableFuture<Boolean>
*/
@Deprecated
default CompletableFuture<Boolean> allowTenantOperationAsync(String tenantName, String originalRole, String role,
TenantOperation operation,
AuthenticationDataSource authData) {
return isTenantAdmin(tenantName, role, null, authData);
return allowTenantOperationAsync(
tenantName,
StringUtils.isBlank(originalRole) ? role : originalRole,
operation,
authData
);
}

@Deprecated
default Boolean allowTenantOperation(String tenantName, String originalRole, String role, TenantOperation operation,
AuthenticationDataSource authData) {
try {
Expand All @@ -242,27 +250,94 @@ default Boolean allowTenantOperation(String tenantName, String originalRole, Str
}
}

/**
* Check if a given <tt>role</tt> is allowed to execute a given <tt>operation</tt> on the tenant.
*
* @param tenantName tenant name
* @param role role name
* @param operation tenant operation
* @param authData authenticated data of the role
* @return a completable future represents check result
*/
default CompletableFuture<Boolean> allowTenantOperationAsync(String tenantName, String role,
TenantOperation operation,
AuthenticationDataSource authData) {
return FutureUtil.failedFuture(new IllegalStateException(
String.format("allowTenantOperation(%s) on tenant %s is not supported by the Authorization" +
" provider you are using.",
operation.toString(), tenantName)));
}

default Boolean allowTenantOperation(String tenantName, String role, TenantOperation operation,
AuthenticationDataSource authData) {
try {
return allowTenantOperationAsync(tenantName, role, operation, authData).get();
} catch (InterruptedException e) {
throw new RestException(e);
} catch (ExecutionException e) {
throw new RestException(e.getCause());
}
}

/**
* Check if a given <tt>role</tt> is allowed to execute a given <tt>operation</tt> on the namespace.
*
* @param namespaceName namespace name
* @param role role name
* @param operation namespace operation
* @param authData authenticated data
* @return a completable future represents check result
*/
default CompletableFuture<Boolean> allowNamespaceOperationAsync(NamespaceName namespaceName,
String role,
NamespaceOperation operation,
AuthenticationDataSource authData) {
return FutureUtil.failedFuture(
new IllegalStateException("NamespaceOperation is not supported by the Authorization provider you are using."));
}

default Boolean allowNamespaceOperation(NamespaceName namespaceName,
String role,
NamespaceOperation operation,
AuthenticationDataSource authData) {
try {
return allowNamespaceOperationAsync(namespaceName, role, operation, authData).get();
} catch (InterruptedException e) {
throw new RestException(e);
} catch (ExecutionException e) {
throw new RestException(e.getCause());
}
}

/**
* Grant authorization-action permission on a namespace to the given client
*
* @param namespaceName
* @param originalRole role not overriden by proxy role if request do pass through proxy
* @param role originalRole | proxyRole if the request didn't pass through proxy
* @param role
* @param operation
* @param authData
* @return CompletableFuture<Boolean>
*/
default CompletableFuture<Boolean> allowNamespaceOperationAsync(NamespaceName namespaceName, String originalRole,
String role, NamespaceOperation operation,
AuthenticationDataSource authData) {
return FutureUtil.failedFuture(
new IllegalStateException(
String.format("NamespaceOperation(%s) on namespace(%s) by role(%s) is not supported" +
" by the Authorization provider you are using.",
operation.toString(), namespaceName.toString(), role == null ? "null" : role)));
@Deprecated
default CompletableFuture<Boolean> allowNamespaceOperationAsync(NamespaceName namespaceName,
String originalRole,
String role,
NamespaceOperation operation,
AuthenticationDataSource authData) {
return allowNamespaceOperationAsync(
namespaceName,
StringUtils.isBlank(originalRole) ? role : originalRole,
operation,
authData
);
}

default Boolean allowNamespaceOperation(NamespaceName namespaceName, String originalRole, String role,
NamespaceOperation operation, AuthenticationDataSource authData) {
@Deprecated
default Boolean allowNamespaceOperation(NamespaceName namespaceName,
String originalRole,
String role,
NamespaceOperation operation,
AuthenticationDataSource authData) {
try {
return allowNamespaceOperationAsync(namespaceName, originalRole, role, operation, authData).get();
} catch (InterruptedException e) {
Expand All @@ -272,6 +347,39 @@ default Boolean allowNamespaceOperation(NamespaceName namespaceName, String orig
}
}

/**
* Check if a given <tt>role</tt> is allowed to execute a given policy <tt>operation</tt> on the namespace.
*
* @param namespaceName namespace name
* @param policy policy name
* @param operation policy operation
* @param role role name
* @param authData authenticated data
* @return a completable future represents check result
*/
default CompletableFuture<Boolean> allowNamespacePolicyOperationAsync(NamespaceName namespaceName,
PolicyName policy,
PolicyOperation operation,
String role,
AuthenticationDataSource authData) {
return FutureUtil.failedFuture(
new IllegalStateException("NamespacePolicyOperation is not supported by the Authorization provider you are using."));
}

default Boolean allowNamespacePolicyOperation(NamespaceName namespaceName,
PolicyName policy,
PolicyOperation operation,
String role,
AuthenticationDataSource authData) {
try {
return allowNamespacePolicyOperationAsync(namespaceName, policy, operation, role, authData).get();
} catch (InterruptedException e) {
throw new RestException(e);
} catch (ExecutionException e) {
throw new RestException(e.getCause());
}
}

/**
* Grant authorization-action permission on a namespace to the given client
* @param namespaceName
Expand All @@ -281,23 +389,68 @@ default Boolean allowNamespaceOperation(NamespaceName namespaceName, String orig
* @param authData
* @return CompletableFuture<Boolean>
*/
default CompletableFuture<Boolean> allowNamespacePolicyOperationAsync(NamespaceName namespaceName, PolicyName policy,
PolicyOperation operation, String originalRole,
String role, AuthenticationDataSource authData) {
return isTenantAdmin(namespaceName.getTenant(), role, null, authData);
@Deprecated
default CompletableFuture<Boolean> allowNamespacePolicyOperationAsync(NamespaceName namespaceName,
PolicyName policy,
PolicyOperation operation,
String originalRole,
String role,
AuthenticationDataSource authData) {
return allowNamespacePolicyOperationAsync(
namespaceName,
policy,
operation,
StringUtils.isBlank(originalRole) ? role : originalRole,
authData
);
}

default Boolean allowNamespacePolicyOperation(NamespaceName namespaceName, PolicyName policy, PolicyOperation operation,
String originalRole, String role, AuthenticationDataSource authData) {
@Deprecated
default Boolean allowNamespacePolicyOperation(NamespaceName namespaceName,
PolicyName policy,
PolicyOperation operation,
String originalRole,
String role,
AuthenticationDataSource authData) {
try {
return allowNamespacePolicyOperationAsync(namespaceName, policy, operation, originalRole, role, authData).get();
return allowNamespacePolicyOperationAsync(
namespaceName, policy, operation, originalRole, role, authData).get();
} catch (InterruptedException e) {
throw new RestException(e);
} catch (ExecutionException e) {
throw new RestException(e.getCause());
}
}

/**
* Check if a given <tt>role</tt> is allowed to execute a given topic <tt>operation</tt> on the topic.
*
* @param topic topic name
* @param role role name
* @param operation topic operation
* @param authData authenticated data
* @return CompletableFuture<Boolean>
*/
default CompletableFuture<Boolean> allowTopicOperationAsync(TopicName topic,
String role,
TopicOperation operation,
AuthenticationDataSource authData) {
return FutureUtil.failedFuture(
new IllegalStateException("TopicOperation is not supported by the Authorization provider you are using."));
}

default Boolean allowTopicOperation(TopicName topicName,
String role,
TopicOperation operation,
AuthenticationDataSource authData) {
try {
return allowTopicOperationAsync(topicName, role, operation, authData).get();
} catch (InterruptedException e) {
throw new RestException(e);
} catch (ExecutionException e) {
throw new RestException(e.getCause());
}
}

/**
* Grant authorization-action permission on a topic to the given client
Expand All @@ -308,27 +461,26 @@ default Boolean allowNamespacePolicyOperation(NamespaceName namespaceName, Polic
* @param authData
* @return CompletableFuture<Boolean>
*/
default CompletableFuture<Boolean> allowTopicOperationAsync(TopicName topic, String originalRole, String role,
TopicOperation operation,
AuthenticationDataSource authData) {
switch (operation) {
case PRODUCE:
return canProduceAsync(topic, role, authData);
case CONSUME:
return canConsumeAsync(topic, role, authData, null);
case LOOKUP:
return canLookupAsync(topic, role, authData);
default:
return FutureUtil.failedFuture(
new IllegalStateException(
String.format("TopicOperation(%s) on topic(%s) by role(%s) is not supported" +
" by the Authorization provider you are using.",
operation.toString(), topic.toString(), role == null ? "null" : null)));
}
@Deprecated
default CompletableFuture<Boolean> allowTopicOperationAsync(TopicName topic,
String originalRole,
String role,
TopicOperation operation,
AuthenticationDataSource authData) {
return allowTopicOperationAsync(
topic,
StringUtils.isBlank(originalRole) ? role : originalRole,
operation,
authData
);
}

default Boolean allowTopicOperation(TopicName topicName, String originalRole, String role, TopicOperation operation,
AuthenticationDataSource authData) {
@Deprecated
default Boolean allowTopicOperation(TopicName topicName,
String originalRole,
String role,
TopicOperation operation,
AuthenticationDataSource authData) {
try {
return allowTopicOperationAsync(topicName, originalRole, role, operation, authData).get();
} catch (InterruptedException e) {
Expand Down
Loading