8989import org .apache .syncope .core .provisioning .java .utils .ConnObjectUtils ;
9090import org .apache .syncope .core .provisioning .java .utils .MappingUtils ;
9191import org .apache .syncope .core .spring .security .AuthContextUtils ;
92+ import org .apache .syncope .core .spring .security .DelegatedAdministrationException ;
9293import org .identityconnectors .framework .common .objects .Attribute ;
9394import org .identityconnectors .framework .common .objects .ConnectorObject ;
9495import org .identityconnectors .framework .common .objects .ObjectClass ;
@@ -156,23 +157,6 @@ public ReconciliationLogic(
156157 this .connectorManager = connectorManager ;
157158 }
158159
159- protected ProvisioningInfo getProvisioningInfo (final String anyTypeKey , final String resourceKey ) {
160- AnyType anyType = anyTypeDAO .findById (anyTypeKey ).
161- orElseThrow (() -> new NotFoundException ("AnyType " + anyTypeKey ));
162-
163- ExternalResource resource = resourceDAO .findById (resourceKey ).
164- orElseThrow (() -> new NotFoundException ("Resource '" + resourceKey ));
165-
166- Provision provision = resource .getProvisionByAnyType (anyType .getKey ()).
167- orElseThrow (() -> new NotFoundException (
168- "Provision for " + anyType + " on Resource '" + resourceKey + "'" ));
169- if (provision .getMapping () == null ) {
170- throw new NotFoundException ("Mapping for " + anyType + " on Resource '" + resourceKey + "'" );
171- }
172-
173- return new ProvisioningInfo (anyType , resource , provision );
174- }
175-
176160 protected ConnObject getOnSyncope (
177161 final Item connObjectKeyItem ,
178162 final String connObjectKeyValue ,
@@ -239,6 +223,22 @@ protected Any getAny(final Provision provision, final AnyTypeKind anyTypeKind, f
239223 orElseThrow (() -> new NotFoundException (provision .getAnyType () + " '" + anyKey + "'" ));
240224 }
241225
226+ protected ProvisioningInfo getProvisioningInfo (final String anyTypeKey , final String resourceKey ) {
227+ AnyType anyType = anyTypeDAO .findById (anyTypeKey ).
228+ orElseThrow (() -> new NotFoundException ("AnyType " + anyTypeKey ));
229+
230+ ExternalResource resource = Optional .ofNullable (resourceDAO .authFind (resourceKey )).
231+ orElseThrow (() -> new NotFoundException ("Resource '" + resourceKey + '\'' ));
232+ Provision provision = resource .getProvisionByAnyType (anyType .getKey ()).
233+ orElseThrow (() -> new NotFoundException (
234+ "Provision for " + anyType + " on Resource '" + resourceKey + "'" ));
235+ if (provision .getMapping () == null ) {
236+ throw new NotFoundException ("Mapping for " + anyType + " on Resource '" + resourceKey + "'" );
237+ }
238+
239+ return new ProvisioningInfo (anyType , resource , provision );
240+ }
241+
242242 @ PreAuthorize ("hasRole('" + IdMEntitlement .RESOURCE_GET_CONNOBJECT + "')" )
243243 public ReconStatus status (
244244 final String anyTypeKey ,
@@ -398,6 +398,12 @@ public List<ProvisioningReport> push(
398398 return results ;
399399 }
400400
401+ protected void securityChecks (final Set <String > realms , final String realm , final String resourceKey ) {
402+ if (!RealmUtils .SubtreePredicate .of (realms ).test (realm )) {
403+ throw new DelegatedAdministrationException (realm , ExternalResource .class .getSimpleName (), resourceKey );
404+ }
405+ }
406+
401407 @ PreAuthorize ("hasRole('" + IdRepoEntitlement .TASK_EXECUTE + "')" )
402408 public List <ProvisioningReport > push (
403409 final String anyTypeKey ,
@@ -408,6 +414,14 @@ public List<ProvisioningReport> push(
408414
409415 ProvisioningInfo info = getProvisioningInfo (anyTypeKey , resourceKey );
410416
417+ Realm sourceRealm = Optional .ofNullable (pushTask .getSourceRealm ()).
418+ flatMap (realmSearchDAO ::findByFullPath ).
419+ orElseThrow (() -> new NotFoundException ("Realm " + pushTask .getSourceRealm ()));
420+ Set <String > effectiveRealms = RealmUtils .getEffective (
421+ AuthContextUtils .getAuthorizations ().get (IdRepoEntitlement .TASK_EXECUTE ),
422+ sourceRealm .getFullPath ());
423+ securityChecks (effectiveRealms , sourceRealm .getFullPath (), null );
424+
411425 SyncDeltaBuilder syncDeltaBuilder = syncDeltaBuilder (
412426 info .resource (), info .provision (), filter , moreAttrsToGet );
413427
@@ -467,10 +481,13 @@ protected List<ProvisioningReport> pull(
467481 final Set <String > moreAttrsToGet ,
468482 final PullTaskTO pullTask ) {
469483
470- if (pullTask .getDestinationRealm () == null || realmSearchDAO .findByFullPath (pullTask .getDestinationRealm ())
471- == null ) {
472- throw new NotFoundException ("Realm " + pullTask .getDestinationRealm ());
473- }
484+ Realm destRealm = Optional .ofNullable (pullTask .getDestinationRealm ()).
485+ flatMap (realmSearchDAO ::findByFullPath ).
486+ orElseThrow (() -> new NotFoundException ("Realm " + pullTask .getDestinationRealm ()));
487+ Set <String > effectiveRealms = RealmUtils .getEffective (
488+ AuthContextUtils .getAuthorizations ().get (IdRepoEntitlement .TASK_EXECUTE ),
489+ destRealm .getFullPath ());
490+ securityChecks (effectiveRealms , destRealm .getFullPath (), null );
474491
475492 SyncopeClientException sce = SyncopeClientException .build (ClientExceptionType .Reconciliation );
476493 List <ProvisioningReport > results = new ArrayList <>();
@@ -594,7 +611,8 @@ public List<ProvisioningReport> push(
594611 entitlement = IdRepoEntitlement .USER_SEARCH ;
595612 }
596613
597- Realm base = realmSearchDAO .findByFullPath (realm ).
614+ Realm base = Optional .ofNullable (realm ).
615+ flatMap (realmSearchDAO ::findByFullPath ).
598616 orElseThrow (() -> new NotFoundException ("Realm " + realm ));
599617
600618 Set <String > adminRealms = RealmUtils .getEffective (AuthContextUtils .getAuthorizations ().get (entitlement ), realm );
@@ -673,12 +691,16 @@ public List<ProvisioningReport> pull(final CSVPullSpec spec, final InputStream c
673691 AnyType anyType = anyTypeDAO .findById (spec .getAnyTypeKey ()).
674692 orElseThrow (() -> new NotFoundException ("AnyType " + spec .getAnyTypeKey ()));
675693
676- if (realmSearchDAO .findByFullPath (spec .getDestinationRealm ()) == null ) {
677- throw new NotFoundException ("Realm " + spec .getDestinationRealm ());
678- }
694+ Realm destRealm = Optional .ofNullable (spec .getDestinationRealm ()).
695+ flatMap (realmSearchDAO ::findByFullPath ).
696+ orElseThrow (() -> new NotFoundException ("Realm " + spec .getDestinationRealm ()));
697+ Set <String > effectiveRealms = RealmUtils .getEffective (
698+ AuthContextUtils .getAuthorizations ().get (IdRepoEntitlement .TASK_EXECUTE ),
699+ destRealm .getFullPath ());
700+ securityChecks (effectiveRealms , destRealm .getFullPath (), null );
679701
680702 PullTaskTO pullTask = new PullTaskTO ();
681- pullTask .setDestinationRealm (spec . getDestinationRealm ());
703+ pullTask .setDestinationRealm (destRealm . getFullPath ());
682704 pullTask .setRemediation (spec .getRemediation ());
683705 pullTask .setMatchingRule (spec .getMatchingRule ());
684706 pullTask .setUnmatchingRule (spec .getUnmatchingRule ());
0 commit comments