diff --git a/src/main/kotlin/io/github/flecomte/AccessKontrol.kt b/src/main/kotlin/io/github/flecomte/AccessKontrol.kt index f279244..c08bc09 100644 --- a/src/main/kotlin/io/github/flecomte/AccessKontrol.kt +++ b/src/main/kotlin/io/github/flecomte/AccessKontrol.kt @@ -27,9 +27,13 @@ abstract class AccessKontrol { /** * A helper to convert a list of subject into one response + * + * @throws [NoDecision] if the list of responses is empty */ protected fun , T> canAll(items: S, action: (T) -> AccessResponse): AccessResponses = items - .map { action(it) }.let { responses -> + .ifEmpty { throw NoDecision() } + .map { action(it) } + .let { responses -> if (responses.any { it is DeniedResponse }) { DeniedResponses(responses) } else { @@ -50,9 +54,12 @@ typealias AccessResponses = List /** * Check all responses and return DENIED if one is DENIED * - * If the list of responses is empty, return GRANTED + * @throws [NoDecision] if the list of responses is empty */ -fun AccessResponses.getFirstDecisionResponse(): AccessResponse = this.firstOrNull { it.decision == AccessDecision.DENIED } ?: this.first { it.decision == AccessDecision.GRANTED } +fun AccessResponses.getFirstDecisionResponse(): AccessResponse { + ifEmpty { throw NoDecision() } + return firstOrNull { it.decision == AccessDecision.DENIED } ?: first() +} /** * Throw an Exception if one response is DENIED @@ -166,3 +173,5 @@ class DeniedResponses( accessResponses.deniedResponses.first().message, accessResponses.deniedResponses.first().code ) + +class NoDecision : RuntimeException("No decision has been taken") diff --git a/src/test/kotlin/io/github/flecomte/AccessKontrolTest.kt b/src/test/kotlin/io/github/flecomte/AccessKontrolTest.kt index bcd1668..a83c01f 100644 --- a/src/test/kotlin/io/github/flecomte/AccessKontrolTest.kt +++ b/src/test/kotlin/io/github/flecomte/AccessKontrolTest.kt @@ -59,6 +59,14 @@ class AccessKontrolTest { } } + @Test + fun `test empty canAllGranted`() { + assertThrows(NoDecision::class.java) { + AccessControlSample() + .canView(listOf(), User("")) + } + } + @Test fun `test CanAllDenied`() { AccessControlSample().run { @@ -127,13 +135,14 @@ class AccessKontrolTest { .run { assertFalse(decision.toBoolean()) } + } - AccessControlSample() - .canView(listOf(MyObject("denied"), MyObject("granted")), User("")) - .getFirstDecisionResponse() - .run { - assertFalse(decision.toBoolean()) - } + @Test + fun `test getFirstDecisionResponse on empty`() { + assertThrows(NoDecision::class.java) { + listOf() + .getFirstDecisionResponse() + } } @Test