Skip to content

Commit

Permalink
Remove duplicate authentication logic in WebTab
Browse files Browse the repository at this point in the history
  • Loading branch information
adrw committed Aug 12, 2019
1 parent 9621367 commit d5e0fba
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 34 deletions.
12 changes: 12 additions & 0 deletions misk/src/main/kotlin/misk/MiskCaller.kt
Expand Up @@ -27,4 +27,16 @@ data class MiskCaller(
"service=$service"
}
}

/** Determine based on allowed capabilities/services if the caller is permitted */
fun isAllowed(allowedCapabilities: Set<String>, allowedServices: Set<String>): Boolean {
// Allow if we don't have any requirements on service or capability
if (allowedServices.isEmpty() && allowedCapabilities.isEmpty()) return true

// Allow if the caller has provided an allowed service
if (service != null && allowedServices.contains(service)) return true

// Allow if the caller has provided an allowed capability
return capabilities.any { allowedCapabilities.contains(it) }
}
}
13 changes: 1 addition & 12 deletions misk/src/main/kotlin/misk/security/authz/AccessInterceptor.kt
Expand Up @@ -19,25 +19,14 @@ class AccessInterceptor private constructor(

override fun intercept(chain: Chain): Any {
val caller = caller.get() ?: throw UnauthenticatedException()
if (!isAllowed(caller)) {
if (!caller.isAllowed(allowedCapabilities, allowedServices)) {
logger.info { "$caller is not allowed to access ${chain.action}" }
throw UnauthorizedException()
}

return chain.proceed(chain.args)
}

private fun isAllowed(caller: MiskCaller): Boolean {
// Allow if we don't have any requirements on service or capability
if (allowedServices.isEmpty() && allowedCapabilities.isEmpty()) return true

// Allow if the caller has provided an allowed service
if (caller.service != null && allowedServices.contains(caller.service)) return true

// Allow if the caller has provided an allowed capability
return caller.capabilities.any { allowedCapabilities.contains(it) }
}

internal class Factory @Inject internal constructor(
private val caller: @JvmSuppressWildcards ActionScoped<MiskCaller?>,
private val registeredEntries: List<AccessAnnotationEntry>
Expand Down
20 changes: 1 addition & 19 deletions misk/src/main/kotlin/misk/web/WebTab.kt
@@ -1,28 +1,10 @@
package misk.web

import misk.MiskCaller

abstract class WebTab(
slug: String,
url_path_prefix: String,
// capabilities, services permissions control visibility of tab to misk web application user
// it does not deal with any other permissions such as static resource access or otherwise
val capabilities: Set<String> = setOf(),
val services: Set<String> = setOf()
) : ValidWebEntry(slug = slug, url_path_prefix = url_path_prefix) {
fun isAuthenticated(caller: MiskCaller?): Boolean = when {
// no capabilities/service requirement => unauthenticated and null caller requests allowed
capabilities.isEmpty() && services.isEmpty() -> true

// capability/service requirement present but caller null => assume authentication broken
caller == null -> false

// matching capability
capabilities.any { caller.capabilities.contains(it) } -> true

// matching service
services.any { caller.service == it } -> true

else -> false
}
}
) : ValidWebEntry(slug = slug, url_path_prefix = url_path_prefix)
Expand Up @@ -32,12 +32,13 @@ class AdminDashboardTabAction @Inject constructor() : WebAction {
@ResponseContentType(MediaTypes.APPLICATION_JSON)
@Unauthenticated
fun getAll(): Response {
val caller = callerProvider.get()
val authorizedAdminDashboardTabs = adminDashboardTabs.filter { it.isAuthenticated(caller) }
val caller = callerProvider.get() ?: return Response()
val authorizedAdminDashboardTabs =
adminDashboardTabs.filter { caller.isAllowed(it.capabilities, it.services) }
return Response(adminDashboardTabs = authorizedAdminDashboardTabs)
}

data class Response(val adminDashboardTabs: List<DashboardTab>)
data class Response(val adminDashboardTabs: List<DashboardTab> = listOf())
}

@Qualifier
Expand Down

0 comments on commit d5e0fba

Please sign in to comment.