Skip to content

Commit 2ac9576

Browse files
committed
Adapt CsmRbac mecanism and CsmPlatformProperties to accept identifier other than mail
1 parent 574889f commit 2ac9576

File tree

5 files changed

+180
-80
lines changed

5 files changed

+180
-80
lines changed

src/main/kotlin/com/cosmotech/api/config/CsmPlatformProperties.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ data class CsmPlatformProperties(
9898
/** The JWT Claim where the roles information is stored */
9999
val rolesJwtClaim: String = "roles",
100100

101+
/** The JWT Claim used to define application id in ACL */
102+
val applicationIdJwtClaim: String = "oid",
103+
101104
/**
102105
* List of additional tenants allowed to register, besides the configured
103106
* `csm.platform.azure.credentials.tenantId`

src/main/kotlin/com/cosmotech/api/metrics/MonitorServiceAspect.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33
package com.cosmotech.api.metrics
44

5+
import com.cosmotech.api.config.CsmPlatformProperties
56
import com.cosmotech.api.events.CsmEventPublisher
67
import com.cosmotech.api.events.PersistentMetricEvent
78
import com.cosmotech.api.utils.getCurrentAuthenticatedIssuer
@@ -25,6 +26,7 @@ private const val SERVICE_NAME = "API"
2526
class MonitorServiceAspect(
2627
private var meterRegistry: MeterRegistry,
2728
private val eventPublisher: CsmEventPublisher,
29+
private val csmPlatformProperties: CsmPlatformProperties
2830
) {
2931
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
3032

@@ -55,10 +57,10 @@ class MonitorServiceAspect(
5557
Tag.of(parameterNames[idx], args[idx] as String)
5658
}
5759
val name = signature.name
58-
val user = getCurrentAuthenticatedUserName()
60+
val user = getCurrentAuthenticatedUserName(csmPlatformProperties)
5961
var issuer = getCurrentAuthenticatedIssuer()
60-
Counter.builder("cosmotech.${name}")
61-
.description("${name}")
62+
Counter.builder("cosmotech.$name")
63+
.description(name)
6264
.tag("method", name)
6365
.tag("user", user)
6466
.tag("issuer", issuer)

src/main/kotlin/com/cosmotech/api/rbac/CsmRbac.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import com.cosmotech.api.exceptions.CsmClientException
88
import com.cosmotech.api.exceptions.CsmResourceNotFoundException
99
import com.cosmotech.api.rbac.model.RbacAccessControl
1010
import com.cosmotech.api.rbac.model.RbacSecurity
11-
import com.cosmotech.api.utils.getCurrentAuthenticatedMail
11+
import com.cosmotech.api.utils.getCurrentAccountIdentifier
1212
import org.slf4j.Logger
1313
import org.slf4j.LoggerFactory
1414
import org.springframework.stereotype.Component
@@ -44,7 +44,7 @@ open class CsmRbac(
4444
}
4545
var userIsAdminOrHasPermission = this.isAdmin(rbacSecurity, rolesDefinition)
4646
if (!userIsAdminOrHasPermission) {
47-
val user = getCurrentAuthenticatedMail(this.csmPlatformProperties)
47+
val user = getCurrentAccountIdentifier(this.csmPlatformProperties)
4848
userIsAdminOrHasPermission = this.verifyRbac(rbacSecurity, permission, rolesDefinition, user)
4949
}
5050
return userIsAdminOrHasPermission
@@ -145,7 +145,7 @@ open class CsmRbac(
145145
fun isAdmin(rbacSecurity: RbacSecurity, rolesDefinition: RolesDefinition): Boolean {
146146
var isAdmin = this.isAdminToken(rbacSecurity)
147147
if (!isAdmin) {
148-
val user = getCurrentAuthenticatedMail(this.csmPlatformProperties)
148+
val user = getCurrentAccountIdentifier(this.csmPlatformProperties)
149149
isAdmin = this.verifyAdminRole(rbacSecurity, user, rolesDefinition)
150150
}
151151
return isAdmin
@@ -214,8 +214,8 @@ open class CsmRbac(
214214
return rolesDefinition[role] ?: listOf()
215215
}
216216

217-
internal fun getUserRole(rbacSecurity: RbacSecurity, user: String): String? {
218-
return rbacSecurity.accessControlList.firstOrNull { it.id == user }?.role
217+
internal fun getUserRole(rbacSecurity: RbacSecurity, user: String): String {
218+
return rbacSecurity.accessControlList.firstOrNull { it.id == user }?.role ?: rbacSecurity.default
219219
}
220220

221221
internal fun getAdminCount(rbacSecurity: RbacSecurity, rolesDefinition: RolesDefinition): Int {

src/main/kotlin/com/cosmotech/api/utils/SecurityUtils.kt

Lines changed: 20 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,60 +13,40 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut
1313

1414
fun getCurrentAuthentication(): Authentication? = SecurityContextHolder.getContext().authentication
1515

16-
fun getCurrentUserName(): String? = getCurrentAuthentication()?.name
17-
18-
fun getCurrentAuthenticatedUserName() =
19-
getCurrentUserName()
16+
fun getCurrentAuthenticatedUserName(configuration: CsmPlatformProperties): String {
17+
return getValueFromAuthenticatedToken {
18+
val jwtClaimsSet = JWTParser.parse(it).jwtClaimsSet
19+
jwtClaimsSet.getStringClaim("name")
20+
?: jwtClaimsSet.getStringClaim(configuration.authorization.applicationIdJwtClaim)
2021
?: throw IllegalStateException("User Authentication not found in Security Context")
21-
22-
fun getCurrentAuthenticatedIssuer(): String {
23-
if (getCurrentAuthentication() == null) {
24-
throw IllegalStateException("User Authentication not found in Security Context")
25-
}
26-
27-
val authentication = getCurrentAuthentication()
28-
29-
if (authentication is JwtAuthenticationToken) {
30-
return authentication.token.tokenValue.let { JWTParser.parse(it).jwtClaimsSet.issuer }
31-
}
32-
33-
return (authentication as BearerTokenAuthentication).token.tokenValue.let {
34-
JWTParser.parse(it).jwtClaimsSet.issuer
3522
}
3623
}
3724

38-
fun getCurrentAuthenticatedMail(configuration: CsmPlatformProperties): String {
39-
if (getCurrentAuthentication() == null) {
40-
throw IllegalStateException("User Authentication not found in Security Context")
41-
}
42-
43-
val authentication = getCurrentAuthentication()
25+
fun getCurrentAuthenticatedIssuer(): String {
26+
return getValueFromAuthenticatedToken { JWTParser.parse(it).jwtClaimsSet.issuer }
27+
}
4428

45-
if (authentication is JwtAuthenticationToken) {
46-
return authentication.token.tokenValue.let {
47-
JWTParser.parse(it).jwtClaimsSet.getStringClaim(configuration.authorization.mailJwtClaim)
48-
}
29+
fun getCurrentAccountIdentifier(configuration: CsmPlatformProperties): String {
30+
return getValueFromAuthenticatedToken {
31+
val jwtClaimsSet = JWTParser.parse(it).jwtClaimsSet
32+
jwtClaimsSet.getStringClaim(configuration.authorization.mailJwtClaim)
33+
?: jwtClaimsSet.getStringClaim(configuration.authorization.applicationIdJwtClaim)
4934
}
35+
}
5036

51-
return (authentication as BearerTokenAuthentication).token.tokenValue.let {
52-
JWTParser.parse(it).jwtClaimsSet.getStringClaim(configuration.authorization.mailJwtClaim)
37+
fun getCurrentAuthenticatedRoles(configuration: CsmPlatformProperties): List<String> {
38+
return getValueFromAuthenticatedToken {
39+
JWTParser.parse(it).jwtClaimsSet.getStringListClaim(configuration.authorization.rolesJwtClaim)
5340
}
5441
}
5542

56-
fun getCurrentAuthenticatedRoles(configuration: CsmPlatformProperties): List<String> {
43+
fun <T> getValueFromAuthenticatedToken(actionLambda: (String) -> T): T {
5744
if (getCurrentAuthentication() == null) {
5845
throw IllegalStateException("User Authentication not found in Security Context")
5946
}
60-
6147
val authentication = getCurrentAuthentication()
62-
6348
if (authentication is JwtAuthenticationToken) {
64-
return authentication.token.tokenValue.let {
65-
JWTParser.parse(it).jwtClaimsSet.getStringListClaim(configuration.authorization.rolesJwtClaim)
66-
}
67-
}
68-
69-
return (authentication as BearerTokenAuthentication).token.tokenValue.let {
70-
JWTParser.parse(it).jwtClaimsSet.getStringListClaim(configuration.authorization.rolesJwtClaim)
49+
return authentication.token.tokenValue.let { actionLambda(it) }
7150
}
51+
return (authentication as BearerTokenAuthentication).token.tokenValue.let { actionLambda(it) }
7252
}

0 commit comments

Comments
 (0)