1414 * limitations under the License.
1515 */
1616@file:Suppress(" TooManyFunctions" )
17+
1718package com.gooddata.oauth2.server
1819
1920import com.gooddata.oauth2.server.OAuthConstants.GD_USER_GROUPS_SCOPE
@@ -34,8 +35,10 @@ import com.nimbusds.oauth2.sdk.ParseException
3435import com.nimbusds.oauth2.sdk.Scope
3536import com.nimbusds.openid.connect.sdk.OIDCScopeValue
3637import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata
38+ import java.net.URI
3739import java.security.MessageDigest
3840import java.time.Instant
41+ import java.util.Collections
3942import net.minidev.json.JSONObject
4043import org.springframework.core.ParameterizedTypeReference
4144import org.springframework.core.convert.ConversionService
@@ -60,8 +63,6 @@ import org.springframework.web.client.RestTemplate
6063import org.springframework.web.server.ResponseStatusException
6164import org.springframework.web.util.UriComponentsBuilder
6265import reactor.core.publisher.Mono
63- import java.net.URI
64- import java.util.Collections
6566
6667/* *
6768 * Constants for OAuth type authentication which are not directly available in the Spring Security.
@@ -111,12 +112,13 @@ private val typeReference: ParameterizedTypeReference<Map<String, Any>> = object
111112fun buildClientRegistration (
112113 registrationId : String ,
113114 organization : Organization ,
115+ jitProvisioningSetting : JitProvisioningSetting ,
114116 properties : HostBasedClientRegistrationRepositoryProperties ,
115117 clientRegistrationCache : ClientRegistrationCache ,
116118): ClientRegistration {
117119 val issuerLocation = organization.oauthIssuerLocation
118120 // fallback to DEX client registration if issuer location is not defined
119- ? : return dexClientRegistration(registrationId, properties, organization)
121+ ? : return dexClientRegistration(registrationId, properties, organization, jitProvisioningSetting )
120122
121123 // fetch the cached settings obtained from the well-known endpoint for the particular issuerLocation
122124 // this saves HTTP requests to well known endpoints everytime the API call is authorized
@@ -136,7 +138,7 @@ fun buildClientRegistration(
136138 return ClientRegistration .withClientRegistration(cachedRegistration)
137139 .registrationId(registrationId)
138140 .withRedirectUri(organization.oauthIssuerId)
139- .buildWithIssuerConfig(organization)
141+ .buildWithIssuerConfig(organization, jitProvisioningSetting )
140142}
141143
142144/* *
@@ -165,11 +167,12 @@ private fun ClientRegistration.Builder.buildWithDummyValues(): ClientRegistratio
165167private fun dexClientRegistration (
166168 registrationId : String ,
167169 properties : HostBasedClientRegistrationRepositoryProperties ,
168- organization : Organization
170+ organization : Organization ,
171+ jitProvisioningSetting : JitProvisioningSetting
169172): ClientRegistration = ClientRegistration
170173 .withRegistrationId(registrationId)
171174 .withDexConfig(properties)
172- .buildWithIssuerConfig(organization)
175+ .buildWithIssuerConfig(organization, jitProvisioningSetting )
173176
174177/* *
175178 * Handles client registration for Azure B2C by validating issuer metadata and building the registration.
@@ -318,6 +321,7 @@ private fun handleRuntimeException(ex: RuntimeException, issuerLocation: String)
318321 HttpStatus .UNAUTHORIZED ,
319322 " Authorization failed for given issuer \" $issuerLocation \" . ${ex.message} "
320323 )
324+
321325 else -> throw ex
322326 }
323327}
@@ -426,6 +430,7 @@ private fun ClientRegistration.Builder.withRedirectUri(oauthIssuerId: String?) =
426430 */
427431internal fun ClientRegistration.Builder.buildWithIssuerConfig (
428432 organization : Organization ,
433+ jitProvisioningSetting : JitProvisioningSetting
429434): ClientRegistration {
430435 if (organization.oauthClientId == null || organization.oauthClientSecret == null ) {
431436 throw ResponseStatusException (
@@ -439,7 +444,7 @@ internal fun ClientRegistration.Builder.buildWithIssuerConfig(
439444 .authorizationGrantType(AuthorizationGrantType .AUTHORIZATION_CODE )
440445 .userNameAttributeName(" name" )
441446 val supportedScopes = withIssuerConfigBuilder.build().resolveSupportedScopes()
442- return withIssuerConfigBuilder.withScopes(supportedScopes, organization).build()
447+ return withIssuerConfigBuilder.withScopes(supportedScopes, organization, jitProvisioningSetting ).build()
443448}
444449
445450private fun ClientRegistration.resolveSupportedScopes () =
@@ -449,18 +454,25 @@ private fun ClientRegistration.resolveSupportedScopes() =
449454
450455private fun ClientRegistration.Builder.withScopes (
451456 supportedScopes : Scope ? ,
452- organization : Organization
453-
457+ organization : Organization ,
458+ jitProvisioningSetting : JitProvisioningSetting ,
454459): ClientRegistration .Builder {
455460 // in the future, we could check mandatory scopes against the supported ones
456461 val mandatoryScopes = listOf (OIDCScopeValue .OPENID , OIDCScopeValue .PROFILE ).map(Scope .Value ::getValue)
457462 val userGroupsScope = if (organization.jitEnabled == true ) {
458463 listOf (OIDCScopeValue .EMAIL .value, GD_USER_GROUPS_SCOPE )
464+ } else if (jitProvisioningSetting.enabled) {
465+ if (jitProvisioningSetting.userGroupsScopeEnabled) {
466+ listOf (OIDCScopeValue .EMAIL .value, jitProvisioningSetting.userGroupsScopeName ? : GD_USER_GROUPS_SCOPE )
467+ } else {
468+ listOf (OIDCScopeValue .EMAIL .value)
469+ }
459470 } else {
460471 listOf ()
461472 }
462473 val azureB2CScope = if (organization.oauthIssuerLocation != null &&
463- organization.oauthIssuerLocation.toUri().isAzureB2C()) {
474+ organization.oauthIssuerLocation.toUri().isAzureB2C()
475+ ) {
464476 listOf (organization.oauthClientId)
465477 } else {
466478 listOf ()
0 commit comments