218218import com .cloud .storage .dao .VMTemplateDao ;
219219import com .cloud .tags .ResourceTagVO ;
220220import com .cloud .tags .dao .ResourceTagDao ;
221+ import com .cloud .template .TemplateManager ;
221222import com .cloud .template .VirtualMachineTemplate .State ;
222223import com .cloud .template .VirtualMachineTemplate .TemplateFilter ;
223224import com .cloud .user .Account ;
@@ -3355,7 +3356,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTempl
33553356 Long parentTemplateId = cmd .getParentTemplateId ();
33563357
33573358 boolean listAll = false ;
3358- if (templateFilter != null && templateFilter == TemplateFilter . all ) {
3359+ if (TemplateFilter . all == templateFilter ) {
33593360 if (caller .getType () == Account .ACCOUNT_TYPE_NORMAL ) {
33603361 throw new InvalidParameterValueException ("Filter " + TemplateFilter .all + " can be specified by admin only" );
33613362 }
@@ -3365,21 +3366,48 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTempl
33653366 List <Long > permittedAccountIds = new ArrayList <Long >();
33663367 Ternary <Long , Boolean , ListProjectResourcesCriteria > domainIdRecursiveListProject = new Ternary <Long , Boolean , ListProjectResourcesCriteria >(cmd .getDomainId (), cmd .isRecursive (), null );
33673368 _accountMgr .buildACLSearchParameters (caller , id , cmd .getAccountName (), cmd .getProjectId (), permittedAccountIds , domainIdRecursiveListProject , listAll , false );
3369+ Long domainId = domainIdRecursiveListProject .first ();
33683370 ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject .third ();
33693371 List <Account > permittedAccounts = new ArrayList <Account >();
33703372 for (Long accountId : permittedAccountIds ) {
33713373 permittedAccounts .add (_accountMgr .getAccount (accountId ));
33723374 }
33733375
3374- boolean showDomr = ((templateFilter != TemplateFilter .selfexecutable ) && (templateFilter != TemplateFilter .featured ));
3376+ boolean showDomr = ((templateFilter != TemplateFilter .selfexecutable ) && (templateFilter != TemplateFilter .featured ) && _accountMgr . isRootAdmin ( caller . getId ()) );
33753377 HypervisorType hypervisorType = HypervisorType .getType (cmd .getHypervisor ());
33763378
33773379 return searchForTemplatesInternal (id , cmd .getTemplateName (), cmd .getKeyword (), templateFilter , false , null , cmd .getPageSizeVal (), cmd .getStartIndex (), cmd .getZoneId (), hypervisorType ,
3378- showDomr , cmd .listInReadyState (), permittedAccounts , caller , listProjectResourcesCriteria , tags , showRemovedTmpl , cmd .getIds (), parentTemplateId , cmd .getShowUnique ());
3380+ showDomr , cmd .listInReadyState (), permittedAccounts , caller , domainId , listProjectResourcesCriteria , tags , showRemovedTmpl , cmd .getIds (), parentTemplateId , cmd .getShowUnique ());
3381+ }
3382+
3383+ private DomainVO getDomainOf (TemplateFilter templateFilter , Account account ) {
3384+ boolean publicTemplates = (templateFilter == TemplateFilter .featured || templateFilter == TemplateFilter .community || templateFilter == TemplateFilter .executable );
3385+
3386+ // get all parent domain ID's all the way till root domain
3387+ //if template filter is featured, or community, all child domains should be included in search
3388+ if (publicTemplates )
3389+ return _domainDao .findById (Domain .ROOT_DOMAIN );
3390+ else
3391+ return _domainDao .findById (account .getDomainId ());
3392+ }
3393+
3394+ private ArrayList <Long > getChildDomainIds (boolean isAdmin , TemplateFilter templateFilter , DomainVO domainTreeNode ){
3395+ boolean publicTemplates = (templateFilter == TemplateFilter .featured || templateFilter == TemplateFilter .community || templateFilter == TemplateFilter .executable );
3396+ ArrayList <Long > domainIds = new ArrayList <>();
3397+
3398+ // get all child domain ID's
3399+ if (isAdmin || publicTemplates ) {
3400+ List <DomainVO > allChildDomains = _domainDao .findAllChildren (domainTreeNode .getPath (), domainTreeNode .getId ());
3401+ for (DomainVO childDomain : allChildDomains ) {
3402+ domainIds .add (childDomain .getId ());
3403+ }
3404+ }
3405+
3406+ return domainIds ;
33793407 }
33803408
33813409 private Pair <List <TemplateJoinVO >, Integer > searchForTemplatesInternal (Long templateId , String name , String keyword , TemplateFilter templateFilter , boolean isIso , Boolean bootable , Long pageSize ,
3382- Long startIndex , Long zoneId , HypervisorType hyperType , boolean showDomr , boolean onlyReady , List <Account > permittedAccounts , Account caller ,
3410+ Long startIndex , Long zoneId , HypervisorType hyperType , boolean showDomr , boolean onlyReady , List <Account > permittedAccounts , Account caller , Long domainId ,
33833411 ListProjectResourcesCriteria listProjectResourcesCriteria , Map <String , String > tags , boolean showRemovedTmpl , List <Long > ids , Long parentTemplateId , Boolean showUnique ) {
33843412
33853413 // check if zone is configured, if not, just return empty list
@@ -3407,6 +3435,8 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long temp
34073435 }
34083436 SearchCriteria <TemplateJoinVO > sc = sb .create ();
34093437
3438+ boolean restrictPublicTemplatesToDomain = TemplateManager .RestrictPublicTemplateAccessToDomain .value ();
3439+
34103440 // verify templateId parameter and specially handle it
34113441 if (templateId != null ) {
34123442 template = _templateDao .findByIdIncludingRemoved (templateId ); // Done for backward compatibility - Bug-5221
@@ -3434,6 +3464,8 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long temp
34343464 // if template is not public, perform permission check here
34353465 else if (!template .isPublicTemplate () && caller .getType () != Account .ACCOUNT_TYPE_ADMIN ) {
34363466 _accountMgr .checkAccess (caller , null , false , template );
3467+ } else if (template .isPublicTemplate ()) {
3468+ _accountMgr .checkAccess (caller , null , false , template );
34373469 }
34383470
34393471 // if templateId is specified, then we will just use the id to
@@ -3444,6 +3476,8 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP
34443476 DomainVO domain = null ;
34453477 if (!permittedAccounts .isEmpty ()) {
34463478 domain = _domainDao .findById (permittedAccounts .get (0 ).getDomainId ());
3479+ } else if (restrictPublicTemplatesToDomain && domainId != null ) {
3480+ domain = _domainDao .findById (domainId );
34473481 } else {
34483482 domain = _domainDao .findById (Domain .ROOT_DOMAIN );
34493483 }
@@ -3468,31 +3502,34 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP
34683502 if (!permittedAccounts .isEmpty ()) {
34693503 for (Account account : permittedAccounts ) {
34703504 permittedAccountIds .add (account .getId ());
3471- boolean publicTemplates = (templateFilter == TemplateFilter .featured || templateFilter == TemplateFilter .community );
34723505
3473- // get all parent domain ID's all the way till root domain
3474- DomainVO domainTreeNode = null ;
3475- //if template filter is featured, or community, all child domains should be included in search
3476- if (publicTemplates ) {
3477- domainTreeNode = _domainDao .findById (Domain .ROOT_DOMAIN );
3506+ DomainVO domainTreeNode = domain ;
34783507
3479- } else {
3480- domainTreeNode = _domainDao . findById ( account . getDomainId () );
3508+ if (! restrictPublicTemplatesToDomain ) {
3509+ domainTreeNode = getDomainOf ( templateFilter , account );
34813510 }
34823511 relatedDomainIds .add (domainTreeNode .getId ());
34833512 while (domainTreeNode .getParent () != null ) {
34843513 domainTreeNode = _domainDao .findById (domainTreeNode .getParent ());
34853514 relatedDomainIds .add (domainTreeNode .getId ());
34863515 }
34873516
3488- // get all child domain ID's
3489- if (_accountMgr .isAdmin (account .getId ()) || publicTemplates ) {
3490- List <DomainVO > allChildDomains = _domainDao .findAllChildren (domainTreeNode .getPath (), domainTreeNode .getId ());
3491- for (DomainVO childDomain : allChildDomains ) {
3492- relatedDomainIds .add (childDomain .getId ());
3493- }
3517+ boolean isAdmin = _accountMgr .isAdmin (account .getId ());
3518+ if (! restrictPublicTemplatesToDomain ) {
3519+ relatedDomainIds .addAll (getChildDomainIds (isAdmin , templateFilter , domainTreeNode ));
3520+ } else if (isAdmin ) {
3521+ relatedDomainIds .addAll (getChildDomainIds (isAdmin , templateFilter , domain ));
34943522 }
34953523 }
3524+ } else if (restrictPublicTemplatesToDomain && domainId != null ) {
3525+ // templatefilter=all or domainid is passed, called by root admin/domain admin
3526+ DomainVO domainTreeNode = domain ;
3527+ relatedDomainIds .add (domainTreeNode .getId ());
3528+ while (domainTreeNode .getParent () != null ) {
3529+ domainTreeNode = _domainDao .findById (domainTreeNode .getParent ());
3530+ relatedDomainIds .add (domainTreeNode .getId ());
3531+ }
3532+ relatedDomainIds .addAll (getChildDomainIds (true , templateFilter , domain ));
34963533 }
34973534
34983535 // control different template filters
@@ -3517,18 +3554,38 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP
35173554 // only show templates shared by others
35183555 sc .addAnd ("sharedAccountId" , SearchCriteria .Op .IN , permittedAccountIds .toArray ());
35193556 } else if (templateFilter == TemplateFilter .executable ) {
3557+ SearchCriteria <TemplateJoinVO > scc2 = _templateJoinDao .createSearchCriteria ();
3558+ scc2 .addAnd ("publicTemplate" , SearchCriteria .Op .EQ , true );
3559+ if (restrictPublicTemplatesToDomain ) {
3560+ SearchCriteria <TemplateJoinVO > scc3 = _templateJoinDao .createSearchCriteria ();
3561+ scc3 .addOr ("domainId" , SearchCriteria .Op .IN , relatedDomainIds .toArray ());
3562+ scc3 .addOr ("domainId" , SearchCriteria .Op .NULL );
3563+ scc2 .addAnd ("domainId" , SearchCriteria .Op .SC , scc3 );
3564+ }
35203565 SearchCriteria <TemplateJoinVO > scc = _templateJoinDao .createSearchCriteria ();
3521- scc .addOr ("publicTemplate" , SearchCriteria .Op .EQ , true );
3566+ scc .addOr ("publicTemplate" , SearchCriteria .Op .SC , scc2 );
35223567 if (!permittedAccounts .isEmpty ()) {
35233568 scc .addOr ("accountId" , SearchCriteria .Op .IN , permittedAccountIds .toArray ());
35243569 }
35253570 sc .addAnd ("publicTemplate" , SearchCriteria .Op .SC , scc );
3526- } else if (templateFilter == TemplateFilter .all && caller .getType () != Account .ACCOUNT_TYPE_ADMIN ) {
3571+ } else if (templateFilter == TemplateFilter .all && (caller .getType () != Account .ACCOUNT_TYPE_ADMIN || domainId != null )) {
3572+ SearchCriteria <TemplateJoinVO > scc2 = _templateJoinDao .createSearchCriteria ();
3573+ scc2 .addAnd ("publicTemplate" , SearchCriteria .Op .EQ , true );
3574+ if (restrictPublicTemplatesToDomain ) {
3575+ SearchCriteria <TemplateJoinVO > scc3 = _templateJoinDao .createSearchCriteria ();
3576+ scc3 .addOr ("domainId" , SearchCriteria .Op .IN , relatedDomainIds .toArray ());
3577+ scc3 .addOr ("domainId" , SearchCriteria .Op .NULL );
3578+ scc2 .addAnd ("domainId" , SearchCriteria .Op .SC , scc3 );
3579+ }
35273580 SearchCriteria <TemplateJoinVO > scc = _templateJoinDao .createSearchCriteria ();
3528- scc .addOr ("publicTemplate" , SearchCriteria .Op .EQ , true );
3581+ scc .addOr ("publicTemplate" , SearchCriteria .Op .SC , scc2 );
35293582
35303583 if (listProjectResourcesCriteria == ListProjectResourcesCriteria .SkipProjectResources ) {
3531- scc .addOr ("domainPath" , SearchCriteria .Op .LIKE , _domainDao .findById (caller .getDomainId ()).getPath () + "%" );
3584+ if (domainId != null ) {
3585+ scc .addOr ("domainPath" , SearchCriteria .Op .LIKE , _domainDao .findById (domainId ).getPath () + "%" );
3586+ } else {
3587+ scc .addOr ("domainPath" , SearchCriteria .Op .LIKE , _domainDao .findById (caller .getDomainId ()).getPath () + "%" );
3588+ }
35323589 } else {
35333590 if (!permittedAccounts .isEmpty ()) {
35343591 scc .addOr ("accountId" , SearchCriteria .Op .IN , permittedAccountIds .toArray ());
@@ -3539,13 +3596,13 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP
35393596 }
35403597 }
35413598
3542- return templateChecks (isIso , hypers , tags , name , keyword , hyperType , onlyReady , bootable , zoneId , showDomr ,
3599+ return templateChecks (isIso , hypers , tags , name , keyword , hyperType , onlyReady , bootable , zoneId , showDomr , domainId ,
35433600 showRemovedTmpl , parentTemplateId , showUnique , searchFilter , sc );
35443601
35453602 }
35463603
35473604 private Pair <List <TemplateJoinVO >, Integer > templateChecks (boolean isIso , List <HypervisorType > hypers , Map <String , String > tags , String name , String keyword ,
3548- HypervisorType hyperType , boolean onlyReady , Boolean bootable , Long zoneId , boolean showDomr ,
3605+ HypervisorType hyperType , boolean onlyReady , Boolean bootable , Long zoneId , boolean showDomr , Long domainId ,
35493606 boolean showRemovedTmpl , Long parentTemplateId , Boolean showUnique ,
35503607 Filter searchFilter , SearchCriteria <TemplateJoinVO > sc ) {
35513608 if (!isIso ) {
@@ -3606,7 +3663,7 @@ private Pair<List<TemplateJoinVO>, Integer> templateChecks(boolean isIso, List<H
36063663 sc .addAnd ("state" , SearchCriteria .Op .SC , readySc );
36073664 }
36083665
3609- if (!showDomr ) {
3666+ if (!showDomr || domainId != null ) {
36103667 // excluding system template
36113668 sc .addAnd ("templateType" , SearchCriteria .Op .NEQ , Storage .TemplateType .SYSTEM );
36123669 }
@@ -3707,6 +3764,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForIsosInternal(ListIsosCmd cm
37073764 List <Long > permittedAccountIds = new ArrayList <Long >();
37083765 Ternary <Long , Boolean , ListProjectResourcesCriteria > domainIdRecursiveListProject = new Ternary <Long , Boolean , ListProjectResourcesCriteria >(cmd .getDomainId (), cmd .isRecursive (), null );
37093766 _accountMgr .buildACLSearchParameters (caller , id , cmd .getAccountName (), cmd .getProjectId (), permittedAccountIds , domainIdRecursiveListProject , listAll , false );
3767+ Long domainId = domainIdRecursiveListProject .first ();
37103768 ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject .third ();
37113769 List <Account > permittedAccounts = new ArrayList <Account >();
37123770 for (Long accountId : permittedAccountIds ) {
@@ -3716,7 +3774,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForIsosInternal(ListIsosCmd cm
37163774 HypervisorType hypervisorType = HypervisorType .getType (cmd .getHypervisor ());
37173775
37183776 return searchForTemplatesInternal (cmd .getId (), cmd .getIsoName (), cmd .getKeyword (), isoFilter , true , cmd .isBootable (), cmd .getPageSizeVal (), cmd .getStartIndex (), cmd .getZoneId (),
3719- hypervisorType , true , cmd .listInReadyState (), permittedAccounts , caller , listProjectResourcesCriteria , tags , showRemovedISO , null , null , cmd .getShowUnique ());
3777+ hypervisorType , true , cmd .listInReadyState (), permittedAccounts , caller , domainId , listProjectResourcesCriteria , tags , showRemovedISO , null , null , cmd .getShowUnique ());
37203778 }
37213779
37223780 @ Override
0 commit comments