221221import com .cloud .storage .dao .VMTemplateDetailsDao ;
222222import com .cloud .tags .ResourceTagVO ;
223223import com .cloud .tags .dao .ResourceTagDao ;
224+ import com .cloud .template .TemplateManager ;
224225import com .cloud .template .VirtualMachineTemplate .State ;
225226import com .cloud .template .VirtualMachineTemplate .TemplateFilter ;
226227import com .cloud .user .Account ;
@@ -3406,7 +3407,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTempl
34063407 Long parentTemplateId = cmd .getParentTemplateId ();
34073408
34083409 boolean listAll = false ;
3409- if (templateFilter != null && templateFilter == TemplateFilter . all ) {
3410+ if (TemplateFilter . all == templateFilter ) {
34103411 if (caller .getType () == Account .ACCOUNT_TYPE_NORMAL ) {
34113412 throw new InvalidParameterValueException ("Filter " + TemplateFilter .all + " can be specified by admin only" );
34123413 }
@@ -3416,21 +3417,48 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTempl
34163417 List <Long > permittedAccountIds = new ArrayList <Long >();
34173418 Ternary <Long , Boolean , ListProjectResourcesCriteria > domainIdRecursiveListProject = new Ternary <Long , Boolean , ListProjectResourcesCriteria >(cmd .getDomainId (), cmd .isRecursive (), null );
34183419 _accountMgr .buildACLSearchParameters (caller , id , cmd .getAccountName (), cmd .getProjectId (), permittedAccountIds , domainIdRecursiveListProject , listAll , false );
3420+ Long domainId = domainIdRecursiveListProject .first ();
34193421 ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject .third ();
34203422 List <Account > permittedAccounts = new ArrayList <Account >();
34213423 for (Long accountId : permittedAccountIds ) {
34223424 permittedAccounts .add (_accountMgr .getAccount (accountId ));
34233425 }
34243426
3425- boolean showDomr = ((templateFilter != TemplateFilter .selfexecutable ) && (templateFilter != TemplateFilter .featured ));
3427+ boolean showDomr = ((templateFilter != TemplateFilter .selfexecutable ) && (templateFilter != TemplateFilter .featured ) && _accountMgr . isRootAdmin ( caller . getId ()) );
34263428 HypervisorType hypervisorType = HypervisorType .getType (cmd .getHypervisor ());
34273429
34283430 return searchForTemplatesInternal (id , cmd .getTemplateName (), cmd .getKeyword (), templateFilter , false , null , cmd .getPageSizeVal (), cmd .getStartIndex (), cmd .getZoneId (), hypervisorType ,
3429- showDomr , cmd .listInReadyState (), permittedAccounts , caller , listProjectResourcesCriteria , tags , showRemovedTmpl , cmd .getIds (), parentTemplateId , cmd .getShowUnique ());
3431+ showDomr , cmd .listInReadyState (), permittedAccounts , caller , domainId , listProjectResourcesCriteria , tags , showRemovedTmpl , cmd .getIds (), parentTemplateId , cmd .getShowUnique ());
3432+ }
3433+
3434+ private DomainVO getDomainOf (TemplateFilter templateFilter , Account account ) {
3435+ boolean publicTemplates = (templateFilter == TemplateFilter .featured || templateFilter == TemplateFilter .community || templateFilter == TemplateFilter .executable );
3436+
3437+ // get all parent domain ID's all the way till root domain
3438+ //if template filter is featured, or community, all child domains should be included in search
3439+ if (publicTemplates )
3440+ return _domainDao .findById (Domain .ROOT_DOMAIN );
3441+ else
3442+ return _domainDao .findById (account .getDomainId ());
3443+ }
3444+
3445+ private ArrayList <Long > getChildDomainIds (boolean isAdmin , TemplateFilter templateFilter , DomainVO domainTreeNode ){
3446+ boolean publicTemplates = (templateFilter == TemplateFilter .featured || templateFilter == TemplateFilter .community || templateFilter == TemplateFilter .executable );
3447+ ArrayList <Long > domainIds = new ArrayList <>();
3448+
3449+ // get all child domain ID's
3450+ if (isAdmin || publicTemplates ) {
3451+ List <DomainVO > allChildDomains = _domainDao .findAllChildren (domainTreeNode .getPath (), domainTreeNode .getId ());
3452+ for (DomainVO childDomain : allChildDomains ) {
3453+ domainIds .add (childDomain .getId ());
3454+ }
3455+ }
3456+
3457+ return domainIds ;
34303458 }
34313459
34323460 private Pair <List <TemplateJoinVO >, Integer > searchForTemplatesInternal (Long templateId , String name , String keyword , TemplateFilter templateFilter , boolean isIso , Boolean bootable , Long pageSize ,
3433- Long startIndex , Long zoneId , HypervisorType hyperType , boolean showDomr , boolean onlyReady , List <Account > permittedAccounts , Account caller ,
3461+ Long startIndex , Long zoneId , HypervisorType hyperType , boolean showDomr , boolean onlyReady , List <Account > permittedAccounts , Account caller , Long domainId ,
34343462 ListProjectResourcesCriteria listProjectResourcesCriteria , Map <String , String > tags , boolean showRemovedTmpl , List <Long > ids , Long parentTemplateId , Boolean showUnique ) {
34353463
34363464 // check if zone is configured, if not, just return empty list
@@ -3458,6 +3486,8 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long temp
34583486 }
34593487 SearchCriteria <TemplateJoinVO > sc = sb .create ();
34603488
3489+ boolean restrictPublicTemplatesToDomain = TemplateManager .RestrictPublicTemplateAccessToDomain .value ();
3490+
34613491 // verify templateId parameter and specially handle it
34623492 if (templateId != null ) {
34633493 template = _templateDao .findByIdIncludingRemoved (templateId ); // Done for backward compatibility - Bug-5221
@@ -3485,6 +3515,8 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long temp
34853515 // if template is not public, perform permission check here
34863516 else if (!template .isPublicTemplate () && caller .getType () != Account .ACCOUNT_TYPE_ADMIN ) {
34873517 _accountMgr .checkAccess (caller , null , false , template );
3518+ } else if (template .isPublicTemplate ()) {
3519+ _accountMgr .checkAccess (caller , null , false , template );
34883520 }
34893521
34903522 // if templateId is specified, then we will just use the id to
@@ -3495,6 +3527,8 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP
34953527 DomainVO domain = null ;
34963528 if (!permittedAccounts .isEmpty ()) {
34973529 domain = _domainDao .findById (permittedAccounts .get (0 ).getDomainId ());
3530+ } else if (restrictPublicTemplatesToDomain && domainId != null ) {
3531+ domain = _domainDao .findById (domainId );
34983532 } else {
34993533 domain = _domainDao .findById (Domain .ROOT_DOMAIN );
35003534 }
@@ -3519,31 +3553,34 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP
35193553 if (!permittedAccounts .isEmpty ()) {
35203554 for (Account account : permittedAccounts ) {
35213555 permittedAccountIds .add (account .getId ());
3522- boolean publicTemplates = (templateFilter == TemplateFilter .featured || templateFilter == TemplateFilter .community );
35233556
3524- // get all parent domain ID's all the way till root domain
3525- DomainVO domainTreeNode = null ;
3526- //if template filter is featured, or community, all child domains should be included in search
3527- if (publicTemplates ) {
3528- domainTreeNode = _domainDao .findById (Domain .ROOT_DOMAIN );
3557+ DomainVO domainTreeNode = domain ;
35293558
3530- } else {
3531- domainTreeNode = _domainDao . findById ( account . getDomainId () );
3559+ if (! restrictPublicTemplatesToDomain ) {
3560+ domainTreeNode = getDomainOf ( templateFilter , account );
35323561 }
35333562 relatedDomainIds .add (domainTreeNode .getId ());
35343563 while (domainTreeNode .getParent () != null ) {
35353564 domainTreeNode = _domainDao .findById (domainTreeNode .getParent ());
35363565 relatedDomainIds .add (domainTreeNode .getId ());
35373566 }
35383567
3539- // get all child domain ID's
3540- if (_accountMgr .isAdmin (account .getId ()) || publicTemplates ) {
3541- List <DomainVO > allChildDomains = _domainDao .findAllChildren (domainTreeNode .getPath (), domainTreeNode .getId ());
3542- for (DomainVO childDomain : allChildDomains ) {
3543- relatedDomainIds .add (childDomain .getId ());
3544- }
3568+ boolean isAdmin = _accountMgr .isAdmin (account .getId ());
3569+ if (! restrictPublicTemplatesToDomain ) {
3570+ relatedDomainIds .addAll (getChildDomainIds (isAdmin , templateFilter , domainTreeNode ));
3571+ } else if (isAdmin ) {
3572+ relatedDomainIds .addAll (getChildDomainIds (isAdmin , templateFilter , domain ));
35453573 }
35463574 }
3575+ } else if (restrictPublicTemplatesToDomain && domainId != null ) {
3576+ // templatefilter=all or domainid is passed, called by root admin/domain admin
3577+ DomainVO domainTreeNode = domain ;
3578+ relatedDomainIds .add (domainTreeNode .getId ());
3579+ while (domainTreeNode .getParent () != null ) {
3580+ domainTreeNode = _domainDao .findById (domainTreeNode .getParent ());
3581+ relatedDomainIds .add (domainTreeNode .getId ());
3582+ }
3583+ relatedDomainIds .addAll (getChildDomainIds (true , templateFilter , domain ));
35473584 }
35483585
35493586 // control different template filters
@@ -3568,18 +3605,38 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP
35683605 // only show templates shared by others
35693606 sc .addAnd ("sharedAccountId" , SearchCriteria .Op .IN , permittedAccountIds .toArray ());
35703607 } else if (templateFilter == TemplateFilter .executable ) {
3608+ SearchCriteria <TemplateJoinVO > scc2 = _templateJoinDao .createSearchCriteria ();
3609+ scc2 .addAnd ("publicTemplate" , SearchCriteria .Op .EQ , true );
3610+ if (restrictPublicTemplatesToDomain ) {
3611+ SearchCriteria <TemplateJoinVO > scc3 = _templateJoinDao .createSearchCriteria ();
3612+ scc3 .addOr ("domainId" , SearchCriteria .Op .IN , relatedDomainIds .toArray ());
3613+ scc3 .addOr ("domainId" , SearchCriteria .Op .NULL );
3614+ scc2 .addAnd ("domainId" , SearchCriteria .Op .SC , scc3 );
3615+ }
35713616 SearchCriteria <TemplateJoinVO > scc = _templateJoinDao .createSearchCriteria ();
3572- scc .addOr ("publicTemplate" , SearchCriteria .Op .EQ , true );
3617+ scc .addOr ("publicTemplate" , SearchCriteria .Op .SC , scc2 );
35733618 if (!permittedAccounts .isEmpty ()) {
35743619 scc .addOr ("accountId" , SearchCriteria .Op .IN , permittedAccountIds .toArray ());
35753620 }
35763621 sc .addAnd ("publicTemplate" , SearchCriteria .Op .SC , scc );
3577- } else if (templateFilter == TemplateFilter .all && caller .getType () != Account .ACCOUNT_TYPE_ADMIN ) {
3622+ } else if (templateFilter == TemplateFilter .all && (caller .getType () != Account .ACCOUNT_TYPE_ADMIN || domainId != null )) {
3623+ SearchCriteria <TemplateJoinVO > scc2 = _templateJoinDao .createSearchCriteria ();
3624+ scc2 .addAnd ("publicTemplate" , SearchCriteria .Op .EQ , true );
3625+ if (restrictPublicTemplatesToDomain ) {
3626+ SearchCriteria <TemplateJoinVO > scc3 = _templateJoinDao .createSearchCriteria ();
3627+ scc3 .addOr ("domainId" , SearchCriteria .Op .IN , relatedDomainIds .toArray ());
3628+ scc3 .addOr ("domainId" , SearchCriteria .Op .NULL );
3629+ scc2 .addAnd ("domainId" , SearchCriteria .Op .SC , scc3 );
3630+ }
35783631 SearchCriteria <TemplateJoinVO > scc = _templateJoinDao .createSearchCriteria ();
3579- scc .addOr ("publicTemplate" , SearchCriteria .Op .EQ , true );
3632+ scc .addOr ("publicTemplate" , SearchCriteria .Op .SC , scc2 );
35803633
35813634 if (listProjectResourcesCriteria == ListProjectResourcesCriteria .SkipProjectResources ) {
3582- scc .addOr ("domainPath" , SearchCriteria .Op .LIKE , _domainDao .findById (caller .getDomainId ()).getPath () + "%" );
3635+ if (domainId != null ) {
3636+ scc .addOr ("domainPath" , SearchCriteria .Op .LIKE , _domainDao .findById (domainId ).getPath () + "%" );
3637+ } else {
3638+ scc .addOr ("domainPath" , SearchCriteria .Op .LIKE , _domainDao .findById (caller .getDomainId ()).getPath () + "%" );
3639+ }
35833640 } else {
35843641 if (!permittedAccounts .isEmpty ()) {
35853642 scc .addOr ("accountId" , SearchCriteria .Op .IN , permittedAccountIds .toArray ());
@@ -3590,13 +3647,13 @@ else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYP
35903647 }
35913648 }
35923649
3593- return templateChecks (isIso , hypers , tags , name , keyword , hyperType , onlyReady , bootable , zoneId , showDomr ,
3650+ return templateChecks (isIso , hypers , tags , name , keyword , hyperType , onlyReady , bootable , zoneId , showDomr , domainId ,
35943651 showRemovedTmpl , parentTemplateId , showUnique , searchFilter , sc );
35953652
35963653 }
35973654
35983655 private Pair <List <TemplateJoinVO >, Integer > templateChecks (boolean isIso , List <HypervisorType > hypers , Map <String , String > tags , String name , String keyword ,
3599- HypervisorType hyperType , boolean onlyReady , Boolean bootable , Long zoneId , boolean showDomr ,
3656+ HypervisorType hyperType , boolean onlyReady , Boolean bootable , Long zoneId , boolean showDomr , Long domainId ,
36003657 boolean showRemovedTmpl , Long parentTemplateId , Boolean showUnique ,
36013658 Filter searchFilter , SearchCriteria <TemplateJoinVO > sc ) {
36023659 if (!isIso ) {
@@ -3657,7 +3714,7 @@ private Pair<List<TemplateJoinVO>, Integer> templateChecks(boolean isIso, List<H
36573714 sc .addAnd ("state" , SearchCriteria .Op .SC , readySc );
36583715 }
36593716
3660- if (!showDomr ) {
3717+ if (!showDomr || domainId != null ) {
36613718 // excluding system template
36623719 sc .addAnd ("templateType" , SearchCriteria .Op .NEQ , Storage .TemplateType .SYSTEM );
36633720 }
@@ -3758,6 +3815,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForIsosInternal(ListIsosCmd cm
37583815 List <Long > permittedAccountIds = new ArrayList <Long >();
37593816 Ternary <Long , Boolean , ListProjectResourcesCriteria > domainIdRecursiveListProject = new Ternary <Long , Boolean , ListProjectResourcesCriteria >(cmd .getDomainId (), cmd .isRecursive (), null );
37603817 _accountMgr .buildACLSearchParameters (caller , id , cmd .getAccountName (), cmd .getProjectId (), permittedAccountIds , domainIdRecursiveListProject , listAll , false );
3818+ Long domainId = domainIdRecursiveListProject .first ();
37613819 ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject .third ();
37623820 List <Account > permittedAccounts = new ArrayList <Account >();
37633821 for (Long accountId : permittedAccountIds ) {
@@ -3767,7 +3825,7 @@ private Pair<List<TemplateJoinVO>, Integer> searchForIsosInternal(ListIsosCmd cm
37673825 HypervisorType hypervisorType = HypervisorType .getType (cmd .getHypervisor ());
37683826
37693827 return searchForTemplatesInternal (cmd .getId (), cmd .getIsoName (), cmd .getKeyword (), isoFilter , true , cmd .isBootable (), cmd .getPageSizeVal (), cmd .getStartIndex (), cmd .getZoneId (),
3770- hypervisorType , true , cmd .listInReadyState (), permittedAccounts , caller , listProjectResourcesCriteria , tags , showRemovedISO , null , null , cmd .getShowUnique ());
3828+ hypervisorType , true , cmd .listInReadyState (), permittedAccounts , caller , domainId , listProjectResourcesCriteria , tags , showRemovedISO , null , null , cmd .getShowUnique ());
37713829 }
37723830
37733831 @ Override
0 commit comments