4646import org .apache .syncope .common .rest .api .beans .AbstractCSVSpec ;
4747import org .apache .syncope .common .rest .api .beans .CSVPullSpec ;
4848import org .apache .syncope .common .rest .api .beans .CSVPushSpec ;
49- import org .apache .syncope .core .logic .AbstractTransactionalLogic .ProvisioningInfo ;
5049import org .apache .syncope .core .persistence .api .dao .AnyDAO ;
5150import org .apache .syncope .core .persistence .api .dao .AnyObjectDAO ;
5251import org .apache .syncope .core .persistence .api .dao .AnySearchDAO ;
8887import org .apache .syncope .core .provisioning .java .utils .ConnObjectUtils ;
8988import org .apache .syncope .core .provisioning .java .utils .MappingUtils ;
9089import org .apache .syncope .core .spring .security .AuthContextUtils ;
90+ import org .apache .syncope .core .spring .security .DelegatedAdministrationException ;
9191import org .identityconnectors .framework .common .objects .Attribute ;
9292import org .identityconnectors .framework .common .objects .ConnectorObject ;
9393import org .identityconnectors .framework .common .objects .ObjectClass ;
@@ -161,23 +161,6 @@ public ReconciliationLogic(
161161 this .ctx = ctx ;
162162 }
163163
164- protected ProvisioningInfo getProvisioningInfo (final String anyTypeKey , final String resourceKey ) {
165- AnyType anyType = anyTypeDAO .findById (anyTypeKey ).
166- orElseThrow (() -> new NotFoundException ("AnyType " + anyTypeKey ));
167-
168- ExternalResource resource = resourceDAO .findById (resourceKey ).
169- orElseThrow (() -> new NotFoundException ("Resource '" + resourceKey ));
170-
171- Provision provision = resource .getProvisionByAnyType (anyType .getKey ()).
172- orElseThrow (() -> new NotFoundException (
173- "Provision for " + anyType + " on Resource '" + resourceKey + "'" ));
174- if (provision .getMapping () == null ) {
175- throw new NotFoundException ("Mapping for " + anyType + " on Resource '" + resourceKey + "'" );
176- }
177-
178- return new ProvisioningInfo (anyType , resource , provision );
179- }
180-
181164 protected ConnObject getOnSyncope (
182165 final Item connObjectKeyItem ,
183166 final String connObjectKeyValue ,
@@ -244,6 +227,22 @@ protected Any getAny(final Provision provision, final AnyTypeKind anyTypeKind, f
244227 orElseThrow (() -> new NotFoundException (provision .getAnyType () + " '" + anyKey + "'" ));
245228 }
246229
230+ protected ProvisioningInfo getProvisioningInfo (final String anyTypeKey , final String resourceKey ) {
231+ AnyType anyType = anyTypeDAO .findById (anyTypeKey ).
232+ orElseThrow (() -> new NotFoundException ("AnyType " + anyTypeKey ));
233+
234+ ExternalResource resource = Optional .ofNullable (resourceDAO .authFind (resourceKey )).
235+ orElseThrow (() -> new NotFoundException ("Resource '" + resourceKey + '\'' ));
236+ Provision provision = resource .getProvisionByAnyType (anyType .getKey ()).
237+ orElseThrow (() -> new NotFoundException (
238+ "Provision for " + anyType + " on Resource '" + resourceKey + "'" ));
239+ if (provision .getMapping () == null ) {
240+ throw new NotFoundException ("Mapping for " + anyType + " on Resource '" + resourceKey + "'" );
241+ }
242+
243+ return new ProvisioningInfo (anyType , resource , provision );
244+ }
245+
247246 @ PreAuthorize ("hasRole('" + IdMEntitlement .RESOURCE_GET_CONNOBJECT + "')" )
248247 @ Transactional (readOnly = true )
249248 public ReconStatus status (
@@ -407,6 +406,12 @@ public List<ProvisioningReport> push(
407406 return results ;
408407 }
409408
409+ protected void securityChecks (final Set <String > realms , final String realm , final String resourceKey ) {
410+ if (!RealmUtils .SubtreePredicate .of (realms ).test (realm )) {
411+ throw new DelegatedAdministrationException (realm , ExternalResource .class .getSimpleName (), resourceKey );
412+ }
413+ }
414+
410415 @ PreAuthorize ("hasRole('" + IdRepoEntitlement .TASK_EXECUTE + "')" )
411416 @ Transactional (readOnly = true )
412417 public List <ProvisioningReport > push (
@@ -418,6 +423,14 @@ public List<ProvisioningReport> push(
418423
419424 ProvisioningInfo info = getProvisioningInfo (anyTypeKey , resourceKey );
420425
426+ Realm sourceRealm = Optional .ofNullable (pushTask .getSourceRealm ()).
427+ flatMap (realmSearchDAO ::findByFullPath ).
428+ orElseThrow (() -> new NotFoundException ("Realm " + pushTask .getSourceRealm ()));
429+ Set <String > effectiveRealms = RealmUtils .getEffective (
430+ AuthContextUtils .getAuthorizations ().get (IdRepoEntitlement .TASK_EXECUTE ),
431+ sourceRealm .getFullPath ());
432+ securityChecks (effectiveRealms , sourceRealm .getFullPath (), null );
433+
421434 SyncDeltaBuilder syncDeltaBuilder = syncDeltaBuilder (
422435 info .resource (), info .provision (), filter , moreAttrsToGet );
423436
@@ -478,11 +491,13 @@ protected List<ProvisioningReport> pull(
478491 final Set <String > moreAttrsToGet ,
479492 final PullTaskTO pullTask ) {
480493
481- if (pullTask .getDestinationRealm () == null
482- || realmSearchDAO .findByFullPath (pullTask .getDestinationRealm ()).isEmpty ()) {
483-
484- throw new NotFoundException ("Realm " + pullTask .getDestinationRealm ());
485- }
494+ Realm destRealm = Optional .ofNullable (pullTask .getDestinationRealm ()).
495+ flatMap (realmSearchDAO ::findByFullPath ).
496+ orElseThrow (() -> new NotFoundException ("Realm " + pullTask .getDestinationRealm ()));
497+ Set <String > effectiveRealms = RealmUtils .getEffective (
498+ AuthContextUtils .getAuthorizations ().get (IdRepoEntitlement .TASK_EXECUTE ),
499+ destRealm .getFullPath ());
500+ securityChecks (effectiveRealms , destRealm .getFullPath (), null );
486501
487502 SyncopeClientException sce = SyncopeClientException .build (ClientExceptionType .Reconciliation );
488503 List <ProvisioningReport > results = new ArrayList <>();
@@ -606,7 +621,8 @@ public List<ProvisioningReport> push(
606621 entitlement = IdRepoEntitlement .USER_SEARCH ;
607622 }
608623
609- Realm base = realmSearchDAO .findByFullPath (realm ).
624+ Realm base = Optional .ofNullable (realm ).
625+ flatMap (realmSearchDAO ::findByFullPath ).
610626 orElseThrow (() -> new NotFoundException ("Realm " + realm ));
611627
612628 Set <String > adminRealms = RealmUtils .getEffective (AuthContextUtils .getAuthorizations ().get (entitlement ), realm );
@@ -684,12 +700,16 @@ public List<ProvisioningReport> pull(final CSVPullSpec spec, final InputStream c
684700 AnyType anyType = anyTypeDAO .findById (spec .getAnyTypeKey ()).
685701 orElseThrow (() -> new NotFoundException ("AnyType " + spec .getAnyTypeKey ()));
686702
687- if (realmSearchDAO .findByFullPath (spec .getDestinationRealm ()) == null ) {
688- throw new NotFoundException ("Realm " + spec .getDestinationRealm ());
689- }
703+ Realm destRealm = Optional .ofNullable (spec .getDestinationRealm ()).
704+ flatMap (realmSearchDAO ::findByFullPath ).
705+ orElseThrow (() -> new NotFoundException ("Realm " + spec .getDestinationRealm ()));
706+ Set <String > effectiveRealms = RealmUtils .getEffective (
707+ AuthContextUtils .getAuthorizations ().get (IdRepoEntitlement .TASK_EXECUTE ),
708+ destRealm .getFullPath ());
709+ securityChecks (effectiveRealms , destRealm .getFullPath (), null );
690710
691711 PullTaskTO pullTask = new PullTaskTO ();
692- pullTask .setDestinationRealm (spec . getDestinationRealm ());
712+ pullTask .setDestinationRealm (destRealm . getFullPath ());
693713 pullTask .setRemediation (spec .getRemediation ());
694714 pullTask .setMatchingRule (spec .getMatchingRule ());
695715 pullTask .setUnmatchingRule (spec .getUnmatchingRule ());
0 commit comments