4848import javax .inject .Inject ;
4949import javax .naming .ConfigurationException ;
5050
51+ import org .apache .cloudstack .acl .Role ;
52+ import org .apache .cloudstack .acl .RoleService ;
5153import org .apache .cloudstack .acl .RoleType ;
5254import org .apache .cloudstack .api .ApiConstants ;
5355import org .apache .cloudstack .api .response .ExtensionCustomActionParameterResponse ;
124126import com .cloud .org .Cluster ;
125127import com .cloud .serializer .GsonHelper ;
126128import com .cloud .storage .dao .VMTemplateDao ;
129+ import com .cloud .user .Account ;
127130import com .cloud .utils .Pair ;
128131import com .cloud .utils .component .ManagerBase ;
129132import com .cloud .utils .component .PluggableService ;
@@ -202,6 +205,9 @@ public class ExtensionsManagerImpl extends ManagerBase implements ExtensionsMana
202205 @ Inject
203206 VMTemplateDao templateDao ;
204207
208+ @ Inject
209+ RoleService roleService ;
210+
205211 private ScheduledExecutorService extensionPathStateCheckExecutor ;
206212
207213 protected String getDefaultExtensionRelativePath (String name ) {
@@ -1037,6 +1043,7 @@ public List<ExtensionCustomActionResponse> listCustomActions(ListCustomActionCmd
10371043 final Boolean enabled = cmd .isEnabled ();
10381044 final SearchBuilder <ExtensionCustomActionVO > sb = extensionCustomActionDao .createSearchBuilder ();
10391045 final Filter searchFilter = new Filter (ExtensionCustomActionVO .class , "id" , false , cmd .getStartIndex (), cmd .getPageSizeVal ());
1046+ final Account caller = CallContext .current ().getCallingAccount ();
10401047
10411048 ExtensionCustomAction .ResourceType resourceType = null ;
10421049 if (StringUtils .isNotBlank (resourceTypeStr )) {
@@ -1055,8 +1062,10 @@ public List<ExtensionCustomActionResponse> listCustomActions(ListCustomActionCmd
10551062 extensionId = extension .getId ();
10561063 }
10571064
1065+ final Role role = roleService .findRole (caller .getRoleId ());
1066+
10581067 sb .and ("id" , sb .entity ().getId (), SearchCriteria .Op .EQ );
1059- sb .and ("extensionid " , sb .entity ().getExtensionId (), SearchCriteria .Op .EQ );
1068+ sb .and ("extensionId " , sb .entity ().getExtensionId (), SearchCriteria .Op .EQ );
10601069 sb .and ("name" , sb .entity ().getName (), SearchCriteria .Op .EQ );
10611070 sb .and ("keyword" , sb .entity ().getName (), SearchCriteria .Op .LIKE );
10621071 sb .and ("enabled" , sb .entity ().isEnabled (), SearchCriteria .Op .EQ );
@@ -1065,13 +1074,16 @@ public List<ExtensionCustomActionResponse> listCustomActions(ListCustomActionCmd
10651074 sb .or ("resourceType" , sb .entity ().getResourceType (), SearchCriteria .Op .EQ );
10661075 sb .cp ();
10671076 }
1077+ if (!RoleType .Admin .equals (role .getRoleType ())) {
1078+ sb .and ("roleType" , sb .entity ().getAllowedRoleTypes (), SearchCriteria .Op .BINARY_OR );
1079+ }
10681080 sb .done ();
10691081 final SearchCriteria <ExtensionCustomActionVO > sc = sb .create ();
10701082 if (id != null ) {
10711083 sc .setParameters ("id" , id );
10721084 }
10731085 if (extensionId != null ) {
1074- sc .setParameters ("extensionid " , extensionId );
1086+ sc .setParameters ("extensionId " , extensionId );
10751087 }
10761088 if (StringUtils .isNotBlank (name )) {
10771089 sc .setParameters ("name" , name );
@@ -1085,6 +1097,9 @@ public List<ExtensionCustomActionResponse> listCustomActions(ListCustomActionCmd
10851097 if (resourceType != null ) {
10861098 sc .setParameters ("resourceType" , resourceType );
10871099 }
1100+ if (!RoleType .Admin .equals (role .getRoleType ())) {
1101+ sc .setParameters ("roleType" , role .getRoleType ().getMask ());
1102+ }
10881103 final Pair <List <ExtensionCustomActionVO >, Integer > result = extensionCustomActionDao .searchAndCount (sc , searchFilter );
10891104 List <ExtensionCustomActionResponse > responses = new ArrayList <>();
10901105 for (ExtensionCustomActionVO customAction : result .first ()) {
@@ -1235,13 +1250,23 @@ public CustomActionResultResponse runCustomAction(RunCustomActionCmd cmd) {
12351250 final String resourceTypeStr = cmd .getResourceType ();
12361251 final String resourceUuid = cmd .getResourceId ();
12371252 Map <String , String > cmdParameters = cmd .getParameters ();
1253+ final Account caller = CallContext .current ().getCallingAccount ();
12381254
12391255 String error = "Internal error running action" ;
12401256 ExtensionCustomActionVO customActionVO = extensionCustomActionDao .findById (id );
12411257 if (customActionVO == null ) {
12421258 logger .error ("Invalid custom action specified with ID: {}" , id );
12431259 throw new InvalidParameterValueException (error );
12441260 }
1261+ final Role role = roleService .findRole (caller .getRoleId ());
1262+ if (!RoleType .Admin .equals (role .getRoleType ())) {
1263+ final Set <RoleType > allowedRoles = RoleType .fromCombinedMask (customActionVO .getAllowedRoleTypes ());
1264+ if (!allowedRoles .contains (role .getRoleType ())) {
1265+ logger .error ("Caller does not have permission to run {} with {} having role: {}" ,
1266+ customActionVO , caller , role .getRoleType ().name ());
1267+ throw new InvalidParameterValueException (error );
1268+ }
1269+ }
12451270 if (!customActionVO .isEnabled ()) {
12461271 logger .error ("Failed to run {} as it is not enabled" , customActionVO );
12471272 throw new InvalidParameterValueException (error );
0 commit comments