11package org .imdc .nodered .servlet ;
22
3+ import com .google .common .collect .ImmutableCollection ;
4+ import com .google .common .collect .ImmutableSet ;
35import com .inductiveautomation .ignition .common .Dataset ;
46import com .inductiveautomation .ignition .common .TypeUtilities ;
7+ import com .inductiveautomation .ignition .common .auth .security .level .SecurityLevelConfig ;
58import com .inductiveautomation .ignition .common .browsing .BrowseFilter ;
69import com .inductiveautomation .ignition .common .browsing .Results ;
710import com .inductiveautomation .ignition .common .model .values .QualifiedValue ;
811import com .inductiveautomation .ignition .common .model .values .QualityCode ;
912import com .inductiveautomation .ignition .common .tags .browsing .NodeDescription ;
13+ import com .inductiveautomation .ignition .common .tags .model .SecurityContext ;
1014import com .inductiveautomation .ignition .common .tags .model .TagPath ;
1115import com .inductiveautomation .ignition .common .tags .paths .parser .TagPathParser ;
1216import com .inductiveautomation .ignition .common .util .AuditStatus ;
@@ -95,6 +99,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
9599 String apiToken = input .getString ("apiToken" );
96100 String secret = input .getString ("secret" );
97101 APITokenValidation validation = APITokenValidation .validateToken (context , apiToken , secret );
102+ SecurityContext securityContext = getSecurityContext (validation );
98103
99104 if (validation .isSuccess ()) {
100105 String command = input .getString ("command" );
@@ -143,9 +148,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
143148
144149 if (errorMessage == null ) {
145150 if (command .equals ("tagRead" )) {
146- tagRead (context , tagPaths , result );
151+ tagRead (context , tagPaths , securityContext , result );
147152 } else if (command .equals ("tagBrowse" )) {
148- tagBrowse (context , tagPaths , result );
153+ tagBrowse (context , tagPaths , securityContext , result );
149154 } else if (command .equals ("tagWrite" )) {
150155 List <Object > values = new ArrayList <>();
151156 if (input .has ("value" )) {
@@ -168,7 +173,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
168173 if (values .size () != tagPaths .size ()) {
169174 errorMessage = "Number of tag paths (" + tagPaths .size () + ") does not match values (" + values .size () + ")" ;
170175 } else {
171- tagWrite (context , tagPaths , values , result , ipAddress , validation );
176+ tagWrite (context , tagPaths , values , securityContext , result , ipAddress , validation );
172177 }
173178 }
174179 }
@@ -214,6 +219,28 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
214219 }
215220 }
216221
222+ private SecurityContext getSecurityContext (APITokenValidation validation ) {
223+ if (validation .getSecurityLevels () != null && !validation .getSecurityLevels ().isBlank ()) {
224+ String [][] paths = Arrays .stream (validation .getSecurityLevels ().split ("," )).map (r -> Arrays .stream (r .trim ().split ("/" )).toArray (String []::new )).toArray (String [][]::new );
225+ return SecurityContext .fromSecurityLevels (SecurityLevelConfig .fromPaths (paths ));
226+ } else if ((validation .getRoles () != null && !validation .getRoles ().isBlank ()) || (validation .getZones () != null && !validation .getZones ().isBlank ())) {
227+ ImmutableCollection <String > roles = ImmutableSet .of ();
228+ ImmutableCollection <String > zones = ImmutableSet .of ();
229+
230+ if (validation .getRoles () != null && !validation .getRoles ().isBlank ()) {
231+ roles = ImmutableSet .copyOf (Arrays .stream (validation .getRoles ().split ("," )).map (String ::trim ).toArray (String []::new ));
232+ }
233+
234+ if (validation .getZones () != null && !validation .getZones ().isBlank ()) {
235+ zones = ImmutableSet .copyOf (Arrays .stream (validation .getZones ().split ("," )).map (String ::trim ).toArray (String []::new ));
236+ }
237+
238+ return SecurityContext .fromRolesAndZones (roles , zones );
239+ }
240+
241+ return SecurityContext .emptyContext ();
242+ }
243+
217244 public static void setTagValue (List <TagPath > tagPaths , List <QualifiedValue > tagValues , JSONObject result ) throws JSONException {
218245 if (tagPaths .size () == 1 ) {
219246 result .put ("tagPath" , tagPaths .get (0 ).toStringFull ());
@@ -267,9 +294,9 @@ public static void setQuality(JSONObject result, QualityCode qual) throws JSONEx
267294 result .put ("quality" , quality );
268295 }
269296
270- private JSONArray browseTags (GatewayContext context , TagPath tagPath ) throws JSONException , ExecutionException , InterruptedException , Exception {
297+ private JSONArray browseTags (GatewayContext context , TagPath tagPath , SecurityContext securityContext ) throws JSONException , ExecutionException , InterruptedException , Exception {
271298 JSONArray tagsArray = new JSONArray ();
272- Results <NodeDescription > browseResults = context .getTagManager ().browseAsync (tagPath , BrowseFilter .NONE ).get ();
299+ Results <NodeDescription > browseResults = context .getTagManager ().browseAsync (tagPath , BrowseFilter .NONE , securityContext ).get ();
273300 Collection <NodeDescription > tagDescriptions = browseResults .getResults ();
274301 if (tagDescriptions != null ) {
275302 Iterator <NodeDescription > iterator = tagDescriptions .iterator ();
@@ -292,31 +319,31 @@ private JSONArray browseTags(GatewayContext context, TagPath tagPath) throws JSO
292319 return tagsArray ;
293320 }
294321
295- private void tagBrowse (GatewayContext context , final List <TagPath > tagPaths , JSONObject result ) throws JSONException , ExecutionException , InterruptedException , Exception {
322+ private void tagBrowse (GatewayContext context , final List <TagPath > tagPaths , SecurityContext securityContext , JSONObject result ) throws JSONException , ExecutionException , InterruptedException , Exception {
296323 if (tagPaths .size () == 1 ) {
297324 logger .info ("Browsing " + tagPaths .get (0 ).toStringFull ());
298325 result .put ("tagPath" , tagPaths .get (0 ).toStringFull ());
299- result .put ("tags" , browseTags (context , tagPaths .get (0 )));
326+ result .put ("tags" , browseTags (context , tagPaths .get (0 ), securityContext ));
300327 } else {
301328 JSONArray resultValues = new JSONArray ();
302329 for (int i = 0 ; i < tagPaths .size (); i ++) {
303330 JSONObject tagObject = new JSONObject ();
304331 TagPath tagPath = tagPaths .get (i );
305332 tagObject .put ("tagPath" , tagPath .toStringFull ());
306- tagObject .put ("tags" , browseTags (context , tagPath ));
333+ tagObject .put ("tags" , browseTags (context , tagPath , securityContext ));
307334 resultValues .put (tagObject );
308335 }
309336 result .put ("values" , resultValues );
310337 }
311338 }
312339
313- private void tagRead (GatewayContext context , final List <TagPath > tagPaths , JSONObject result ) throws JSONException , ExecutionException , InterruptedException {
314- List <QualifiedValue > tagValues = context .getTagManager ().readAsync (tagPaths ).get ();
340+ private void tagRead (GatewayContext context , final List <TagPath > tagPaths , SecurityContext securityContext , JSONObject result ) throws JSONException , ExecutionException , InterruptedException {
341+ List <QualifiedValue > tagValues = context .getTagManager ().readAsync (tagPaths , securityContext ).get ();
315342 setTagValue (tagPaths , tagValues , result );
316343 }
317344
318- private void tagWrite (GatewayContext context , final List <TagPath > tagPaths , final List <Object > writeValues , JSONObject result , String ipAddress , APITokenValidation validation ) throws JSONException , ExecutionException , InterruptedException {
319- List <QualityCode > writeResult = context .getTagManager ().writeAsync (tagPaths , writeValues ).get ();
345+ private void tagWrite (GatewayContext context , final List <TagPath > tagPaths , final List <Object > writeValues , SecurityContext securityContext , JSONObject result , String ipAddress , APITokenValidation validation ) throws JSONException , ExecutionException , InterruptedException {
346+ List <QualityCode > writeResult = context .getTagManager ().writeAsync (tagPaths , writeValues , securityContext ).get ();
320347
321348 if (tagPaths .size () == 1 ) {
322349 TagPath tagPath = tagPaths .get (0 );
0 commit comments