Skip to content

Latest commit

 

History

History
144 lines (105 loc) · 5.18 KB

pip-383.md

File metadata and controls

144 lines (105 loc) · 5.18 KB

PIP-383: Support granting/revoking permissions for multiple topics

Background

In AuthorizationProvider, the authorization interface grantPermissionAsync(TopicName topicName, Set<AuthAction> actions, String role, String authDataJson) currently only supports granting permissions to a single topic at a time. When multiple topics need to be authorized under a namespace, the client makes the calls to the authorization interface concurrently. Since the permissions information is stored in the namespace-level policies, and multiple topics may be on different brokers, concurrent authorization modification will cause concurrent modification exceptions. Therefore, supporting granting permissions for multiple topics is very beneficial.

Motivation

Supporting granting/revoking permissions for multiple topics, add grantPermissionAsync(List<GrantTopicPermissionOptions> options) and revokePermissionAsync(List<RevokeTopicPermissionOptions> options) in AuthorizationProvider.

Goals

In Scope

  • Add grantPermissionAsync(List<GrantTopicPermissionOptions> options) in AuthorizationProvider.
  • Add revokePermissionAsync(List<GrantTopicPermissionOptions> options) in AuthorizationProvider.

High-Level Design

Design & Implementation Details

Add default method implementation in AuthorizationProvider

public interface AuthorizationProvider extends Closeable {

    default CompletableFuture<Void> grantPermissionAsync(List<GrantTopicPermissionOptions> options) {
        return FutureUtil.failedFuture(new IllegalStateException(
                String.format("grantPermissionAsync is not supported by the Authorization")));
    }

    default CompletableFuture<Void> revokePermissionAsync(List<RevokeTopicPermissionOptions> options) {
        return FutureUtil.failedFuture(new IllegalStateException(
                String.format("revokePermissionAsync is not supported by the Authorization")));
    }
}
@Data
@Builder
public class GrantTopicPermissionOptions {

    private final String topic;
    
    private final String role;

    private final Set<AuthAction> actions;
}

@Data
@Builder
public class RevokeTopicPermissionOptions {

    private final String topic;

    private final String role;
}

Add namespace admin API.

public interface Namespaces {
    
    CompletableFuture<Void> grantPermissionOnTopicsAsync(List<GrantTopicPermissionOptions> options);

    void grantPermissionOnTopics(List<GrantTopicPermissionOptions> options) throws PulsarAdminException;

    CompletableFuture<Void> revokePermissionOnTopicsAsync(List<RevokeTopicPermissionOptions> options);

    void revokePermissionOnTopics(List<RevokeTopicPermissionOptions> options) throws PulsarAdminException;
}

Add namespace rest implementation in broker side.

@POST
@Path("/grantPermissions")
public void grantPermissionOnTopics(@Suspended final AsyncResponse asyncResponse,
                             List<GrantTopicPermissionOptions> options) {
    internalGrantPermissionsAsync(options)
            .thenAccept(__ -> asyncResponse.resume(Response.noContent().build()))
            .exceptionally(ex -> {
                log.error("[{}] Failed to grant permissions {}",
                        clientAppId(), options, ex);
                resumeAsyncResponseExceptionally(asyncResponse, ex);
                return null;
            });
}

@POST
@Path("/revokePermissions")
public void revokePermissionOnTopics(@Suspended final AsyncResponse asyncResponse,
                             List<RevokeTopicPermissionOptions> options) {
    internalRevokePermissionsAsync(options)
            .thenAccept(__ -> asyncResponse.resume(Response.noContent().build()))
            .exceptionally(ex -> {
                log.error("[{}] Failed to revoke permissions {}",
                        clientAppId(), options, ex);
                resumeAsyncResponseExceptionally(asyncResponse, ex);
                return null;
            });
}

so user can grant/revoke permissions to multi-topics like :

public class TestAuthorization {
    
    @Test
    public void testGrantPermission() {
        // grant permission for multi-topics
        List<GrantPermissionOptions> grantPermissions = new ArrayList<>();
        grantPermissions.add(GrantPermissionOptions.builder().topic("topic1").role("role1").actions(Set.of(AuthAction.produce)).build());
        grantPermissions.add(GrantPermissionOptions.builder().topic("topic2").role("role2").actions(Set.of(AuthAction.consume)).build());
        admin.namespaces().grantPermissionOnTopics(grantPermissions);
        // revoke permission topics
        List<RevokePermissionOptions> revokePermissions = new ArrayList<>();
        revokePermissions.add(RevokePermissionOptions.builder().topic("topic1").role("role1").build());
        revokePermissions.add(RevokePermissionOptions.builder().topic("topic2").role("role2").build());
        admin.namespaces().revokePermissionOnTopics(revokePermissions);
    }
}

Backward & Forward Compatibility

Alternatives

General Notes

Links