Skip to content
Merged
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
17 changes: 15 additions & 2 deletions core/src/main/scala/kafka/security/authorizer/AclAuthorizer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import org.apache.kafka.common.Endpoint
import org.apache.kafka.common.acl._
import org.apache.kafka.common.errors.{ApiException, InvalidRequestException, UnsupportedVersionException}
import org.apache.kafka.common.protocol.ApiKeys
import org.apache.kafka.common.resource.PatternType
import org.apache.kafka.common.resource.{PatternType, ResourcePatternFilter}
import org.apache.kafka.common.security.auth.KafkaPrincipal
import org.apache.kafka.common.utils.{Time, SecurityUtils => JSecurityUtils}
import org.apache.kafka.server.authorizer.AclDeleteResult.AclBindingDeleteResult
Expand Down Expand Up @@ -188,7 +188,9 @@ class AclAuthorizer extends Authorizer with Logging {
val deleteExceptions = new mutable.HashMap[AclBinding, ApiException]()
val filters = aclBindingFilters.asScala.zipWithIndex
inWriteLock(lock) {
val resourcesToUpdate = aclCache.keys.map { resource =>
// Find all potentially matching resource patterns from the provided filters and ACL cache and apply the filters
val resources = aclCache.keys ++ filters.map(_._1.patternFilter).filter(_.matchesAtMostOne).flatMap(filterToResources)
val resourcesToUpdate = resources.map { resource =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing to consider for a separate PR: this method seems highly inefficient. We take all the keys in the cache and do a bunch of transformations. It seems like we should avoid that, no? Intuitively, we would do a filter operation first and then transform only the cache items that match.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will do https://issues.apache.org/jira/browse/KAFKA-8847 first to remove references to the old classes and deprecate those. And that would avoid a lot of the unnecessary conversions. I can see if more can be done to improve this in the same PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

val matchingFilters = filters.filter { case (filter, _) =>
filter.patternFilter.matches(resource.toPattern)
}
Expand Down Expand Up @@ -363,6 +365,17 @@ class AclAuthorizer extends Authorizer with Logging {
.map(store => store.createListener(AclChangedNotificationHandler, zkClient))
}

private def filterToResources(filter: ResourcePatternFilter): Set[Resource] = {
filter.patternType match {
case PatternType.LITERAL | PatternType.PREFIXED =>
Set(Resource(ResourceType.fromJava(filter.resourceType), filter.name, filter.patternType))
case PatternType.ANY =>
Set(Resource(ResourceType.fromJava(filter.resourceType), filter.name, PatternType.LITERAL),
Resource(ResourceType.fromJava(filter.resourceType), filter.name, PatternType.PREFIXED))
case _ => throw new IllegalArgumentException(s"Cannot determine matching resources for patternType $filter")
}
}

def logAuditMessage(requestContext: AuthorizableRequestContext, action: Action, authorized: Boolean): Unit = {
def logMessage: String = {
val principal = requestContext.principal
Expand Down