-
Notifications
You must be signed in to change notification settings - Fork 164
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RORDEV-757] Data streams rule (#872)
- Loading branch information
1 parent
641f254
commit d034631
Showing
180 changed files
with
5,754 additions
and
2,802 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
core/src/main/scala/tech/beshu/ror/accesscontrol/blocks/rules/DataStreamsRule.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* This file is part of ReadonlyREST. | ||
* | ||
* ReadonlyREST is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* ReadonlyREST is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with ReadonlyREST. If not, see http://www.gnu.org/licenses/ | ||
*/ | ||
package tech.beshu.ror.accesscontrol.blocks.rules | ||
|
||
import cats.data.NonEmptySet | ||
import cats.implicits._ | ||
import monix.eval.Task | ||
import org.apache.logging.log4j.scala.Logging | ||
import tech.beshu.ror.accesscontrol.blocks.BlockContext.DataStreamRequestBlockContext | ||
import tech.beshu.ror.accesscontrol.blocks.rules.DataStreamsRule.Settings | ||
import tech.beshu.ror.accesscontrol.blocks.rules.base.Rule | ||
import tech.beshu.ror.accesscontrol.blocks.rules.base.Rule.RuleResult.{Fulfilled, Rejected} | ||
import tech.beshu.ror.accesscontrol.blocks.rules.base.Rule.{RegularRule, RuleName, RuleResult} | ||
import tech.beshu.ror.accesscontrol.blocks.variables.runtime.RuntimeMultiResolvableVariable | ||
import tech.beshu.ror.accesscontrol.blocks.{BlockContext, BlockContextUpdater} | ||
import tech.beshu.ror.accesscontrol.domain.DataStreamName | ||
import tech.beshu.ror.accesscontrol.matchers.ZeroKnowledgeDataStreamsFilterScalaAdapter.CheckResult | ||
import tech.beshu.ror.accesscontrol.matchers.{MatcherWithWildcardsScalaAdapter, ZeroKnowledgeDataStreamsFilterScalaAdapter} | ||
import tech.beshu.ror.accesscontrol.request.RequestContext | ||
import tech.beshu.ror.accesscontrol.utils.RuntimeMultiResolvableVariableOps.resolveAll | ||
import tech.beshu.ror.utils.ZeroKnowledgeIndexFilter | ||
|
||
class DataStreamsRule(val settings: Settings) | ||
extends RegularRule | ||
with Logging { | ||
|
||
override val name: Rule.Name = DataStreamsRule.Name.name | ||
|
||
private val zeroKnowledgeMatchFilter = new ZeroKnowledgeDataStreamsFilterScalaAdapter( | ||
new ZeroKnowledgeIndexFilter(true) | ||
) | ||
|
||
override def regularCheck[B <: BlockContext : BlockContextUpdater](blockContext: B): Task[Rule.RuleResult[B]] = Task { | ||
BlockContextUpdater[B] match { | ||
case BlockContextUpdater.DataStreamRequestBlockContextUpdater => | ||
checkDataStreams(blockContext) | ||
case _ => | ||
Fulfilled(blockContext) | ||
} | ||
} | ||
|
||
private def checkDataStreams(blockContext: DataStreamRequestBlockContext): RuleResult[DataStreamRequestBlockContext] = { | ||
checkAllowedDataStreams( | ||
resolveAll(settings.allowedDataStreams.toNonEmptyList, blockContext).toSet, | ||
blockContext.dataStreams, | ||
blockContext.requestContext | ||
) match { | ||
case Right(filteredDataStreams) => Fulfilled(blockContext.withDataStreams(filteredDataStreams)) | ||
case Left(()) => Rejected() | ||
} | ||
} | ||
|
||
private def checkAllowedDataStreams(allowedDataStreams: Set[DataStreamName], | ||
dataStreamsToCheck: Set[DataStreamName], | ||
requestContext: RequestContext) = { | ||
if (allowedDataStreams.contains(DataStreamName.All) || allowedDataStreams.contains(DataStreamName.Wildcard)) { | ||
Right(dataStreamsToCheck) | ||
} else { | ||
zeroKnowledgeMatchFilter.check( | ||
dataStreamsToCheck, | ||
MatcherWithWildcardsScalaAdapter.create(allowedDataStreams) | ||
) match { | ||
case CheckResult.Ok(processedDataStreams) if requestContext.isReadOnlyRequest => | ||
Right(processedDataStreams) | ||
case CheckResult.Ok(processedDataStreams) if processedDataStreams.size === dataStreamsToCheck.size => | ||
Right(processedDataStreams) | ||
case CheckResult.Ok(processedDataStreams) => | ||
val filteredOutDataStreams = dataStreamsToCheck.diff(processedDataStreams).map(_.show) | ||
logger.debug( | ||
s"[${requestContext.id.show}] Write request with data streams cannot proceed because some of the data streams " + | ||
s"[${filteredOutDataStreams.toList.mkString_(",")}] were filtered out by ACL. The request will be rejected.." | ||
) | ||
Left(()) | ||
case CheckResult.Failed => | ||
logger.debug(s"[${requestContext.id.show}] The processed data streams do not match the allowed data streams. The request will be rejected..") | ||
Left(()) | ||
} | ||
} | ||
} | ||
} | ||
|
||
object DataStreamsRule { | ||
implicit case object Name extends RuleName[DataStreamsRule] { | ||
override val name: Rule.Name = Rule.Name("data_streams") | ||
} | ||
|
||
final case class Settings(allowedDataStreams: NonEmptySet[RuntimeMultiResolvableVariable[DataStreamName]]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.